diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx index 6097a8a0388f..dadc782c0af6 100644 --- a/chart2/qa/extras/chart2import.cxx +++ b/chart2/qa/extras/chart2import.cxx @@ -2579,8 +2579,8 @@ void Chart2ImportTest::testTdf134225() awt::Point aLabelPosition2 = xDataPointLabel2->getPosition(); // Check the distance between the position of the 1st data point label and the second one - CPPUNIT_ASSERT_DOUBLES_EQUAL(1800, sal_Int32(aLabelPosition2.X - aLabelPosition1.X), 30); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2123, sal_Int32(aLabelPosition2.Y - aLabelPosition1.Y), 30); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1669, sal_Int32(aLabelPosition2.X - aLabelPosition1.X), 30); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2166, sal_Int32(aLabelPosition2.Y - aLabelPosition1.Y), 30); #endif } diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx index e2dd04f6c645..6042b0d0dbe4 100644 --- a/chart2/source/view/charttypes/PieChart.cxx +++ b/chart2/source/view/charttypes/PieChart.cxx @@ -389,26 +389,51 @@ void PieChart::createTextLabelShape( * First off the routine try to place the label inside the related pie slice, * if this is not possible the label is placed outside. */ - if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo) - && m_aAvailableOuterRect.getWidth()) + if (!performLabelBestFitInnerPlacement(rParam, aPieLabelInfo)) { - double fAngleDegree - = rParam.mfUnitCircleStartAngleDegree + rParam.mfUnitCircleWidthAngleDegree / 2.0; - while (fAngleDegree > 360.0) - fAngleDegree -= 360.0; - while (fAngleDegree < 0.0) - fAngleDegree += 360.0; + if (m_aAvailableOuterRect.getWidth()) + { + double fAngleDegree = rParam.mfUnitCircleStartAngleDegree + + rParam.mfUnitCircleWidthAngleDegree / 2.0; + while (fAngleDegree > 360.0) + fAngleDegree -= 360.0; + while (fAngleDegree < 0.0) + fAngleDegree += 360.0; - if (fAngleDegree < 67.5 || fAngleDegree >= 292.5) - fTextMaximumFrameWidth - = 0.8 * (m_aAvailableOuterRect.getMaxX() - aPieLabelInfo.aFirstPosition.getX()); - else if (fAngleDegree < 112.5 || fAngleDegree >= 247.5) - fTextMaximumFrameWidth = 0.8 * m_aAvailableOuterRect.getWidth(); - else - fTextMaximumFrameWidth - = 0.8 * (aPieLabelInfo.aFirstPosition.getX() - m_aAvailableOuterRect.getMinX()); + if (fAngleDegree < 67.5 || fAngleDegree >= 292.5) + fTextMaximumFrameWidth + = 0.8 + * (m_aAvailableOuterRect.getMaxX() - aPieLabelInfo.aFirstPosition.getX()); + else if (fAngleDegree < 112.5 || fAngleDegree >= 247.5) + fTextMaximumFrameWidth = 0.8 * m_aAvailableOuterRect.getWidth(); + else + fTextMaximumFrameWidth + = 0.8 + * (aPieLabelInfo.aFirstPosition.getX() - m_aAvailableOuterRect.getMinX()); + + nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth); + } + + nScreenValueOffsetInRadiusDirection = (m_nDimension != 3) ? 150 : 0; + aScreenPosition2D + = aPolarPosHelper.getLabelScreenPositionAndAlignmentForUnitCircleValues( + eAlignment, css::chart::DataLabelPlacement::OUTSIDE, + rParam.mfUnitCircleStartAngleDegree, + rParam.mfUnitCircleWidthAngleDegree, rParam.mfUnitCircleInnerRadius, + rParam.mfUnitCircleOuterRadius, rParam.mfLogicZ + 0.5, 0); + aPieLabelInfo.aFirstPosition + = basegfx::B2IVector(aScreenPosition2D.X, aScreenPosition2D.Y); + + //add a scaling independent Offset if requested + if (nScreenValueOffsetInRadiusDirection != 0) + { + basegfx::B2IVector aDirection(aScreenPosition2D.X - aOrigin.X, + aScreenPosition2D.Y - aOrigin.Y); + aDirection.setLength(nScreenValueOffsetInRadiusDirection); + aScreenPosition2D.X += aDirection.getX(); + aScreenPosition2D.Y += aDirection.getY(); + } - nTextMaximumFrameWidth = ceil(fTextMaximumFrameWidth); uno::Reference xShapes(xChild->getParent(), uno::UNO_QUERY); xShapes->remove(aPieLabelInfo.xTextShape); aPieLabelInfo.xTextShape @@ -420,7 +445,6 @@ void PieChart::createTextLabelShape( return; aPieLabelInfo.xLabelGroupShape.set(xChild->getParent(), uno::UNO_QUERY); - performLabelBestFitOuterPlacement(rParam, aPieLabelInfo); } } @@ -1608,57 +1632,6 @@ bool PieChart::performLabelBestFitInnerPlacement(ShapeParam& rShapeParam, PieLab return true; } -void PieChart::performLabelBestFitOuterPlacement(ShapeParam& rShapeParam, - PieLabelInfo const& rPieLabelInfo) -{ - awt::Point aOldPos(rPieLabelInfo.xLabelGroupShape->getPosition()); - basegfx::B2IVector aTranslationVector = rPieLabelInfo.aFirstPosition - rPieLabelInfo.aOrigin; - awt::Point aScreenPosition2D(aOldPos.X + aTranslationVector.getX(), - aOldPos.Y + aTranslationVector.getY()); - - double fAngleDegree - = rShapeParam.mfUnitCircleStartAngleDegree + rShapeParam.mfUnitCircleWidthAngleDegree / 2.0; - ::basegfx::B2IRectangle aBb(lcl_getRect(rPieLabelInfo.xLabelGroupShape)); - double fLabelWidth = aBb.getWidth(); - double fLabelHeight = aBb.getHeight(); - - while (fAngleDegree > 360.0) - fAngleDegree -= 360.0; - while (fAngleDegree < 0.0) - fAngleDegree += 360.0; - - if (fAngleDegree <= 22.5 || fAngleDegree >= 337.5) - aScreenPosition2D.X += fLabelWidth / 2; - else if (fAngleDegree < 67.5) - { - aScreenPosition2D.X += fLabelWidth / 2; - aScreenPosition2D.Y -= fLabelHeight / 2; - } - else if (fAngleDegree < 112.5) - aScreenPosition2D.Y -= fLabelHeight / 2; - else if (fAngleDegree <= 157.5) - { - aScreenPosition2D.X -= fLabelWidth / 2; - aScreenPosition2D.Y -= fLabelHeight / 2; - } - else if (fAngleDegree <= 202.5) - aScreenPosition2D.X -= fLabelWidth / 2; - else if (fAngleDegree < 247.5) - { - aScreenPosition2D.X -= fLabelWidth / 2; - aScreenPosition2D.Y += fLabelHeight / 2; - } - else if (fAngleDegree < 292.5) - aScreenPosition2D.Y += fLabelHeight / 2; - else - { - aScreenPosition2D.X += fLabelWidth / 2; - aScreenPosition2D.Y += fLabelHeight / 2; - } - - rPieLabelInfo.xLabelGroupShape->setPosition(aScreenPosition2D); -} - } //namespace chart /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/source/view/charttypes/PieChart.hxx b/chart2/source/view/charttypes/PieChart.hxx index 41e5d3f25648..73d40d06bbfa 100644 --- a/chart2/source/view/charttypes/PieChart.hxx +++ b/chart2/source/view/charttypes/PieChart.hxx @@ -107,8 +107,6 @@ struct PieLabelInfo; bool performLabelBestFitInnerPlacement( ShapeParam& rShapeParam , PieLabelInfo const & rPieLabelInfo ); - static void performLabelBestFitOuterPlacement( ShapeParam& rShapeParam - , PieLabelInfo const & rPieLabelInfo ); private: //member std::unique_ptr diff --git a/sw/qa/extras/layout/data/tdf137116.docx b/sw/qa/extras/layout/data/tdf137116.docx new file mode 100644 index 000000000000..8edff3b78e23 Binary files /dev/null and b/sw/qa/extras/layout/data/tdf137116.docx differ diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx index 194fea99d3b1..6f2fea3918a1 100644 --- a/sw/qa/extras/layout/layout.cxx +++ b/sw/qa/extras/layout/layout.cxx @@ -2923,6 +2923,26 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf134866) pXmlDoc, "/metafile/push[1]/push[1]/push[1]/push[4]/push[1]/textarray[2]/text", "100%"); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf137116) +{ + SwDoc* pDoc = createDoc("tdf137116.docx"); + SwDocShell* pShell = pDoc->GetDocShell(); + + // Dump the rendering of the first page as an XML file. + std::shared_ptr xMetaFile = pShell->GetPreviewMetaFile(); + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + CPPUNIT_ASSERT(pXmlDoc); + sal_Int32 nX2 = getXPath(pXmlDoc, "//textarray[2]", "x").toInt32(); // second data label + sal_Int32 nX4 = getXPath(pXmlDoc, "//textarray[4]", "x").toInt32(); // fourth data label + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 694 + // - Actual : -225 + // - Delta : 100 + // i.e. the second data label appeared inside the pie slice. + CPPUNIT_ASSERT_DOUBLES_EQUAL(694, nX2 - nX4, 100); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf130031) { SwDoc* pDoc = createDoc("tdf130031.docx");