tdf#133376 Chart view: improve BestFit position of data labels

Put exceeding data label outside the pie slice
without overlapping the other pie slices.

Change-Id: I220fd43f0d52c940cf3ef30764074776d19da184
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94859
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
(cherry picked from commit 73477348e30c6931a537cba5557c250183fbeb9b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95317
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx
index df324ee..e47f123 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -159,6 +159,7 @@ public:
    void testTdf130032();
    void testTdf119138MissingAutoTitleDeleted();
    void testStockChartShiftedCategoryPosition();
    void testTdf133376();

    CPPUNIT_TEST_SUITE(Chart2ImportTest);
    CPPUNIT_TEST(Fdo60083);
@@ -266,6 +267,7 @@ public:
    CPPUNIT_TEST(testTdf130032);
    CPPUNIT_TEST(testTdf119138MissingAutoTitleDeleted);
    CPPUNIT_TEST(testStockChartShiftedCategoryPosition);
    CPPUNIT_TEST(testTdf133376);

    CPPUNIT_TEST_SUITE_END();

@@ -2482,6 +2484,25 @@ void Chart2ImportTest::testStockChartShiftedCategoryPosition()
    CPPUNIT_ASSERT(aScaleData.ShiftedCategoryPosition);
}

void Chart2ImportTest::testTdf133376()
{
    load("/chart2/qa/extras/data/xlsx/", "tdf133376.xlsx");
    Reference<chart::XChartDocument> xChartDoc(getChartDocFromSheet(0, mxComponent),
        UNO_QUERY_THROW);

    Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xChartDoc, UNO_QUERY_THROW);
    Reference<drawing::XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage(), UNO_SET_THROW);
    Reference<drawing::XShapes> xShapes(xDrawPage->getByIndex(0), UNO_QUERY_THROW);
    Reference<drawing::XShape> xDataPointLabel(getShapeByName(xShapes,
        "CID/MultiClick/CID/D=0:CS=0:CT=0:Series=0:DataLabels=:DataLabel=2"), UNO_SET_THROW);

    CPPUNIT_ASSERT(xDataPointLabel.is());
    // Check the position of the 3rd data point label, which is out from the pie slice
    awt::Point aLabelPosition = xDataPointLabel->getPosition();
    CPPUNIT_ASSERT_DOUBLES_EQUAL(1466, aLabelPosition.X, 30);
    CPPUNIT_ASSERT_DOUBLES_EQUAL(5269, aLabelPosition.Y, 30);
}

CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ImportTest);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/data/xlsx/tdf133376.xlsx b/chart2/qa/extras/data/xlsx/tdf133376.xlsx
new file mode 100644
index 0000000..2000733
--- /dev/null
+++ b/chart2/qa/extras/data/xlsx/tdf133376.xlsx
Binary files differ
diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx
index 009552c..03e928a 100644
--- a/chart2/source/view/charttypes/PieChart.cxx
+++ b/chart2/source/view/charttypes/PieChart.cxx
@@ -1591,6 +1591,41 @@ void PieChart::performLabelBestFit(ShapeParam& rShapeParam, PieLabelInfo const &
    aTranslationVector.setLength(150);
    aScreenPosition2D.X += aTranslationVector.getX();
    aScreenPosition2D.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.Y -= fLabelHeight / 2;
    else if( fAngleDegree < 67.5 )
        aScreenPosition2D.Y -= fLabelHeight;
    else if( fAngleDegree < 112.5 )
    {
        aScreenPosition2D.X -= fLabelWidth / 2;
        aScreenPosition2D.Y -= fLabelHeight;
    }
    else if (fAngleDegree <= 157.5)
    {
        aScreenPosition2D.X -= fLabelWidth;
        aScreenPosition2D.Y -= fLabelHeight;
    }
    else if (fAngleDegree <= 202.5)
    {
        aScreenPosition2D.X -= fLabelWidth;
        aScreenPosition2D.Y -= fLabelHeight / 2;
    }
    else if (fAngleDegree < 247.5)
        aScreenPosition2D.X -= fLabelWidth;
    else if (fAngleDegree < 292.5)
        aScreenPosition2D.X -= fLabelWidth / 2;

    rPieLabelInfo.xLabelGroupShape->setPosition(aScreenPosition2D);
}