emfio/qa/cppunit/emf/EmfImportTest.cxx | 89 ++++++++++-------------- emfio/qa/cppunit/emf/data/TestAngleArc.emf |binary emfio/source/reader/emfreader.cxx | 38 +++++++++- include/tools/poly.hxx | 3 tools/inc/poly.h | 3 tools/source/generic/poly.cxx | 104 ++++++++++++++++++++++------- 6 files changed, 154 insertions(+), 83 deletions(-)
New commits: commit 5b32c63c6569996acc39216f81520291f15c7659 Author: Bartosz Kosiorek <gan...@poczta.onet.pl> AuthorDate: Wed Aug 6 18:03:05 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Aug 8 20:03:18 2025 +0200 tdf#103859 EMF Fix quality of EMR_ROUNDRECT by using Bazier curve for drawing As WMF and EMF is using integers and previous EMR_ROUNDRECT implementation used many small lines to display curves, it produces low quality curves. With this implementation using Bezier curves, EMR_ROUNDRECT images are scalable without any loss of quality. Change-Id: I3ef7f15ed9e3835065030bdf196b9bfa044d84a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189016 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl> (cherry picked from commit 05fd7ddeb2f7d506b6c94dfcdef12b9bdbf9e4e5) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189090 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 6ef45e866f19..a644d46b2b73 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -1504,33 +1504,8 @@ CPPUNIT_TEST_FIXTURE(Test, testRoundrectWMF) assertXPath(pDocument, aXPathPrefix + "polypolygoncolor", "color", u"#ffffff"); - assertXPathContent( - pDocument, aXPathPrefix + "polygonstroke/polygon", - u"2858,659 2858,651 2858,643 2858,635 2858,619 2858,611 2858,603 2850,595 2850,587 " - u"2850,580 " - "2850,564 2850,556 2842,548 2842,540 2842,532 2834,524 2834,516 2834,508 2826,500 2826,492 " - "2818,484 2818,476 2810,468 2810,460 2802,452 2802,445 2794,437 2794,429 2786,421 2786,421 " - "2778,413 2770,405 2770,397 2762,389 2754,389 2754,381 2746,373 2738,373 2731,365 2731,365 " - "2723,357 2715,349 2707,349 2707,341 2699,341 2691,341 2683,333 2675,333 2675,333 2667,325 " - "2659,325 2651,325 2643,325 2635,318 2627,318 2627,318 2619,318 2611,318 2604,318 572,318 " - "564,318 556,318 548,318 548,318 540,318 532,325 524,325 516,325 508,325 500,333 500,333 " - "492,333 484,341 476,341 468,341 468,349 460,349 452,357 445,365 445,365 437,373 429,373 " - "421,381 421,389 413,389 405,397 405,405 397,413 389,421 389,421 381,429 381,437 373,445 " - "373,452 365,460 365,468 357,476 357,484 349,492 349,500 341,508 341,516 341,524 333,532 " - "333,540 333,548 325,556 325,564 325,580 325,587 325,595 318,603 318,611 318,619 318,635 " - "318,643 318,651 318,659 318,1667 318,1675 318,1683 318,1691 318,1707 318,1715 318,1723 " - "325,1731 325,1739 325,1746 325,1762 325,1770 333,1778 333,1786 333,1794 341,1802 341,1810 " - "341,1818 349,1826 349,1834 357,1842 357,1850 365,1858 365,1866 373,1874 373,1881 381,1889 " - "381,1897 389,1905 389,1905 397,1913 405,1921 405,1929 413,1937 421,1937 421,1945 429,1953 " - "437,1953 445,1961 445,1961 452,1969 460,1977 468,1977 468,1985 476,1985 484,1985 492,1993 " - "500,1993 500,1993 508,2001 516,2001 524,2001 532,2001 540,2008 548,2008 548,2008 556,2008 " - "564,2008 572,2008 2604,2008 2611,2008 2619,2008 2627,2008 2627,2008 2635,2008 2643,2001 " - "2651,2001 2659,2001 2667,2001 2675,1993 2675,1993 2683,1993 2691,1985 2699,1985 2707,1985 " - "2707,1977 2715,1977 2723,1969 2731,1961 2731,1961 2738,1953 2746,1953 2754,1945 2754,1937 " - "2762,1937 2770,1929 2770,1921 2778,1913 2786,1905 2786,1905 2794,1897 2794,1889 2802,1881 " - "2802,1874 2810,1866 2810,1858 2818,1850 2818,1842 2826,1834 2826,1826 2834,1818 2834,1810 " - "2834,1802 2842,1794 2842,1786 2842,1778 2850,1770 2850,1762 2850,1746 2850,1739 2850,1731 " - "2858,1723 2858,1715 2858,1707 2858,1691 2858,1683 2858,1675 2858,1667"); + assertXPathContent(pDocument, aXPathPrefix + "polygonstroke/polygon", + u"318,659 572,318 2604,318 2858,659 2858,1667 2604,2008 572,2008 318,1667"); assertXPath(pDocument, aXPathPrefix + "polygonstroke/line", "color", u"#000000"); assertXPath(pDocument, aXPathPrefix + "polygonstroke/line", "width", u"143"); } @@ -1632,36 +1607,14 @@ CPPUNIT_TEST_FIXTURE(Test, testRoundRect) u"100,100 4100,100 4100,2100 100,2100"); assertXPath(pDocument, aXPathPrefix + "polygonstroke[1]/line", "color", u"#ff0000"); - assertXPath( - pDocument, aXPathPrefix + "polypolygoncolor[2]/polypolygon", "path", - u"m4090 " - "2700v-30-20l-10-30v-20l-10-30-10-20-10-20-20-30-10-20-20-20-20-20-20-30-20-20-20-20-20-10-" - "30-20-20-20-30-20-30-10-30-10-30-20-30-10-30-10-40-10-30-10h-30l-40-10h-30l-40-10h-30-40-" - "2590-40-30l-40 10h-30l-40 10h-30l-30 10-40 10-30 10-30 10-30 20-30 10-30 10-30 20-20 " - "20-30 20-20 10-20 20-20 20-20 30-20 20-20 20-10 20-20 30-10 20-10 20-10 30v20l-10 30v20 " - "30 990 30 20l10 30v20l10 30 10 20 10 20 20 30 10 20 20 20 20 20 20 30 20 20 20 20 20 10 " - "30 20 20 20 30 20 30 10 30 10 30 20 30 10 30 10 40 10 30 10h30l40 10h30l40 10h30 40 2590 " - "40 30l40-10h30l40-10h30l30-10 40-10 30-10 30-10 30-20 30-10 30-10 30-20 20-20 30-20 20-10 " - "20-20 20-20 20-30 20-20 20-20 10-20 20-30 10-20 10-20 10-30v-20l10-30v-20-30z"); + assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]/polypolygon", "path", + u"m100 2700c0-250 350-500 700-500h2590c350 0 700 250 700 500v990c0 250-350 500-700 " + u"500h-2590c-350 0-700-250-700-500z"); assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]", "color", u"#ffffff"); assertXPathContent( pDocument, aXPathPrefix + "polygonstroke[2]/polygon", - u"4090,2700 4090,2670 4090,2650 4080,2620 4080,2600 4070,2570 4060,2550 4050,2530 " - u"4030,2500 " - "4020,2480 4000,2460 3980,2440 3960,2410 3940,2390 3920,2370 3900,2360 3870,2340 3850,2320 " - "3820,2300 3790,2290 3760,2280 3730,2260 3700,2250 3670,2240 3630,2230 3600,2220 3570,2220 " - "3530,2210 3500,2210 3460,2200 3430,2200 3390,2200 800,2200 760,2200 730,2200 690,2210 " - "660,2210 620,2220 590,2220 560,2230 520,2240 490,2250 460,2260 430,2280 400,2290 370,2300 " - "340,2320 320,2340 290,2360 270,2370 250,2390 230,2410 210,2440 190,2460 170,2480 160,2500 " - "140,2530 130,2550 120,2570 110,2600 110,2620 100,2650 100,2670 100,2700 100,3690 100,3720 " - "100,3740 110,3770 110,3790 120,3820 130,3840 140,3860 160,3890 170,3910 190,3930 210,3950 " - "230,3980 250,4000 270,4020 290,4030 320,4050 340,4070 370,4090 400,4100 430,4110 460,4130 " - "490,4140 520,4150 560,4160 590,4170 620,4170 660,4180 690,4180 730,4190 760,4190 800,4190 " - "3390,4190 3430,4190 3460,4190 3500,4180 3530,4180 3570,4170 3600,4170 3630,4160 3670,4150 " - "3700,4140 3730,4130 3760,4110 3790,4100 3820,4090 3850,4070 3870,4050 3900,4030 3920,4020 " - "3940,4000 3960,3980 3980,3950 4000,3930 4020,3910 4030,3890 4050,3860 4060,3840 4070,3820 " - "4080,3790 4080,3770 4090,3740 4090,3720 4090,3690"); + u"100,2700 800,2200 3390,2200 4090,2700 4090,3690 3390,4190 800,4190 100,3690"); assertXPath(pDocument, aXPathPrefix + "polygonstroke[2]/line", "color", u"#ff0000"); } diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx index 13961baab645..e281e4f009ee 100644 --- a/emfio/source/reader/emfreader.cxx +++ b/emfio/source/reader/emfreader.cxx @@ -1347,11 +1347,13 @@ namespace emfio } break; - case EMR_ROUNDRECT : + case EMR_ROUNDRECT: { - mpInputStream->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nW ).ReadUInt32( nH ); - tools::Polygon aRoundRectPoly( ReadRectangle( nX32, nY32, nx32, ny32 ), nW, nH ); - DrawPolygon( std::move(aRoundRectPoly), mbRecordPath ); + mpInputStream->ReadInt32(nX32).ReadInt32(nY32).ReadInt32(nx32).ReadInt32(ny32).ReadUInt32(nW).ReadUInt32(nH); + SAL_INFO("emfio", " Rectangle position: " << nX32 << ":" << nY32 << ", " << nx32 << ":" << ny32); + SAL_INFO("emfio", " Ellipse Width: " << nW << ", Height" << nH); + tools::Polygon aRoundRectPoly(ReadRectangle(nX32, nY32, nx32, ny32), nW, nH); + DrawPolygon(std::move(aRoundRectPoly), mbRecordPath); } break; diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx index b68cb92425a7..028b2925c2b2 100644 --- a/tools/source/generic/poly.cxx +++ b/tools/source/generic/poly.cxx @@ -123,17 +123,19 @@ ImplPolygon::ImplPolygon( const tools::Rectangle& rRect ) mnPoints = 0; } -ImplPolygon::ImplPolygon( const tools::Rectangle& rRect, sal_uInt32 nHorzRound, sal_uInt32 nVertRound ) +ImplPolygon::ImplPolygon(const tools::Rectangle& rRect, sal_uInt32 nHorzRound, + sal_uInt32 nVertRound) { - if ( !rRect.IsEmpty() ) + if (!rRect.IsEmpty()) { - tools::Rectangle aRect( rRect ); - aRect.Normalize(); // SJ: i9140 + tools::Rectangle aRect(rRect); + aRect.Normalize(); // SJ: i9140 - nHorzRound = std::min( nHorzRound, static_cast<sal_uInt32>(std::abs( aRect.GetWidth() >> 1 )) ); - nVertRound = std::min( nVertRound, static_cast<sal_uInt32>(std::abs( aRect.GetHeight() >> 1 )) ); + nHorzRound = std::min(nHorzRound, static_cast<sal_uInt32>(std::abs(aRect.GetWidth() >> 1))); + nVertRound + = std::min(nVertRound, static_cast<sal_uInt32>(std::abs(aRect.GetHeight() >> 1))); - if( !nHorzRound && !nVertRound ) + if (!nHorzRound || !nVertRound) { ImplInitSize(5); mxPointAry[0] = aRect.TopLeft(); @@ -144,31 +146,49 @@ ImplPolygon::ImplPolygon( const tools::Rectangle& rRect, sal_uInt32 nHorzRound, } else { - const Point aTL( aRect.Left() + nHorzRound, aRect.Top() + nVertRound ); - const Point aTR( aRect.Right() - nHorzRound, aRect.Top() + nVertRound ); - const Point aBR( aRect.Right() - nHorzRound, aRect.Bottom() - nVertRound ); - const Point aBL( aRect.Left() + nHorzRound, aRect.Bottom() - nVertRound ); - tools::Polygon aEllipsePoly( Point(), nHorzRound, nVertRound ); - sal_uInt16 i, nEnd, nSize4 = aEllipsePoly.GetSize() >> 2; + ImplInitSize(17, true); + + mxPointAry[0] = Point(aRect.Left(), aRect.Top() + nVertRound); + + mxPointAry[1] = Point(aRect.Left(), aRect.Top() + 0.5 * nVertRound); + mxFlagAry[1] = PolyFlags::Control; + + mxPointAry[2] = Point(aRect.Left() + 0.5 * nHorzRound, aRect.Top()); + mxFlagAry[2] = PolyFlags::Control; + + mxPointAry[3] = Point(aRect.Left() + nHorzRound, aRect.Top()); + + mxPointAry[4] = Point(aRect.Right() - nHorzRound, aRect.Top()); + + mxPointAry[5] = Point(aRect.Right() - 0.5 * nHorzRound, aRect.Top()); + mxFlagAry[5] = PolyFlags::Control; + + mxPointAry[6] = Point(aRect.Right(), aRect.Top() + 0.5 * nVertRound); + mxFlagAry[6] = PolyFlags::Control; + + mxPointAry[7] = Point(aRect.Right(), aRect.Top() + nVertRound); + + mxPointAry[8] = Point(aRect.Right(), aRect.Bottom() - nVertRound); + + mxPointAry[9] = Point(aRect.Right(), aRect.Bottom() - 0.5 * nVertRound); + mxFlagAry[9] = PolyFlags::Control; - ImplInitSize(aEllipsePoly.GetSize() + 1); + mxPointAry[10] = Point(aRect.Right() - 0.5 * nHorzRound, aRect.Bottom()); + mxFlagAry[10] = PolyFlags::Control; - const Point* pSrcAry = aEllipsePoly.GetConstPointAry(); - Point* pDstAry = mxPointAry.get(); + mxPointAry[11] = Point(aRect.Right() - nHorzRound, aRect.Bottom()); - for( i = 0, nEnd = nSize4; i < nEnd; i++ ) - pDstAry[ i ] = pSrcAry[ i ] + aTR; + mxPointAry[12] = Point(aRect.Left() + nHorzRound, aRect.Bottom()); - for( nEnd = nEnd + nSize4; i < nEnd; i++ ) - pDstAry[ i ] = pSrcAry[ i ] + aTL; + mxPointAry[13] = Point(aRect.Left() + 0.5 * nHorzRound, aRect.Bottom()); + mxFlagAry[13] = PolyFlags::Control; - for( nEnd = nEnd + nSize4; i < nEnd; i++ ) - pDstAry[ i ] = pSrcAry[ i ] + aBL; + mxPointAry[14] = Point(aRect.Left(), aRect.Bottom() - 0.5 * nVertRound); + mxFlagAry[14] = PolyFlags::Control; - for( nEnd = nEnd + nSize4; i < nEnd; i++ ) - pDstAry[ i ] = pSrcAry[ i ] + aBR; + mxPointAry[15] = Point(aRect.Left(), aRect.Bottom() - nVertRound); - pDstAry[ nEnd ] = pDstAry[ 0 ]; + mxPointAry[16] = mxPointAry[0]; } } else commit 6f1769122be69e31ce8a67c91a1d90430150fe47 Author: Bartosz Kosiorek <gan...@poczta.onet.pl> AuthorDate: Sun Aug 3 01:01:38 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Aug 8 20:03:14 2025 +0200 tdf#167616 EMF Add support for EMR_ANGLEARC record Change-Id: Ic872f80b2a318ac7c0f3b0cbdb4ad285795989c8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188865 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl> (cherry picked from commit 1b68f859034ecc2342a772685d6563fa1ad71f7f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189091 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 1c4378c7bc42..6ef45e866f19 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -607,6 +607,36 @@ CPPUNIT_TEST_FIXTURE(Test, testChordWithModifyWorldTransform) "575,716 608,704 654,725 720,700 753,688 819,664 853,652 919,628"); } +CPPUNIT_TEST_FIXTURE(Test, testAngleArc) +{ + // tdf167616 EMF import test of displaying AngleArc which draw a line segment and an arc in a single operation + // Records: EMR_ANGLEARC, EMR_SETARCDIRECTION + Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestAngleArc.emf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence)); + CPPUNIT_ASSERT(pDocument); + assertXPath(pDocument, aXPathPrefix + "mask/polygonhairline", 20); + assertXPath(pDocument, aXPathPrefix + "mask/polygonhairline[1]", "color", u"#000000"); + + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[5]/polygon", + u"2350,990 4000,640"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[7]/polygon", + u"4000,640 1140,2000"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[9]/polygon", + u"640,2500 2350,2350"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[11]/polygon", + u"2350,1650 4000,2000"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[13]/polygon", + u"4000,2000 640,3000"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[15]/polygon", + u"1140,3500 2350,3850"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[17]/polygon", + u"1650,3850 3500,3000"); + assertXPathContent(pDocument, aXPathPrefix + "mask/polygonhairline[19]/polygon", + u"3500,4000 1280,4250"); +} + CPPUNIT_TEST_FIXTURE(Test, testArcStartPointEqualEndPoint) { // i73608 EMF import test where StartPoint == EndPoint. It should draw full circle diff --git a/emfio/qa/cppunit/emf/data/TestAngleArc.emf b/emfio/qa/cppunit/emf/data/TestAngleArc.emf new file mode 100644 index 000000000000..dce3c8442fa1 Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TestAngleArc.emf differ diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx index 31903c4ce10f..13961baab645 100644 --- a/emfio/source/reader/emfreader.cxx +++ b/emfio/source/reader/emfreader.cxx @@ -1355,6 +1355,33 @@ namespace emfio } break; + case EMR_ANGLEARC: + { + sal_Int32 nCenterX, nCenterY; + sal_uInt32 nRadius; + float fStartAngle, fSweepAngle; + mpInputStream->ReadInt32(nCenterX).ReadInt32(nCenterY).ReadUInt32(nRadius); + mpInputStream->ReadFloat(fStartAngle).ReadFloat(fSweepAngle); + SAL_INFO("emfio", " Center: " << nCenterX << ":" << nCenterY << ", Radius: " << nRadius); + SAL_INFO("emfio", " Start Angle: " << fStartAngle << ", Sweep Angle: " << fSweepAngle); + + if (!mpInputStream->good()) + bStatus = false; + else + { + // Convert from degrees to radians and start angle to draw from x-axis + fStartAngle = basegfx::deg2rad(fStartAngle); + fSweepAngle = basegfx::deg2rad(fSweepAngle); + + tools::Polygon aPoly(Point(nCenterX, nCenterY), nRadius, fStartAngle, fSweepAngle, IsArcDirectionClockWise()); + + // Before drawing the arc, AngleArc draws the line segment from the current position to the beginning of the arc + LineTo(aPoly[0], mbRecordPath); + DrawPolyLine(std::move(aPoly), true, mbRecordPath); + } + } + break; + case EMR_ARC : case EMR_ARCTO : case EMR_CHORD : @@ -2173,7 +2200,6 @@ namespace emfio case EMR_SETPALETTEENTRIES : case EMR_RESIZEPALETTE : case EMR_EXTFLOODFILL : - case EMR_ANGLEARC : case EMR_SETCOLORADJUSTMENT : case EMR_POLYDRAW16 : case EMR_SETCOLORSPACE : diff --git a/include/tools/poly.hxx b/include/tools/poly.hxx index 95d39d8df5ab..8d9fbeea8e8c 100644 --- a/include/tools/poly.hxx +++ b/include/tools/poly.hxx @@ -95,6 +95,9 @@ public: const Point& rStart, const Point& rEnd, PolyStyle ePolyStyle = PolyStyle::Arc, const bool bClockWiseArcDirection = false); + Polygon( const Point& aCenter, const sal_uInt32 nRadius, + const float fStartAngle, const float fSweepAngle, + const bool bClockWiseArcDirection); Polygon( const Point& rBezPt1, const Point& rCtrlPt1, const Point& rBezPt2, const Point& rCtrlPt2, sal_uInt16 nPoints ); diff --git a/tools/inc/poly.h b/tools/inc/poly.h index 6576beecaf97..f61850b352a3 100644 --- a/tools/inc/poly.h +++ b/tools/inc/poly.h @@ -40,6 +40,9 @@ public: ImplPolygon( const Point& rCenter, tools::Long nRadX, tools::Long nRadY ); ImplPolygon( const tools::Rectangle& rBound, const Point& rStart, const Point& rEnd, PolyStyle eStyle, bool bClockWiseArcDirection ); + ImplPolygon( const Point& aCenter, const sal_uInt32 nRadius, + const float fStartAngle, const float fSweepAngle, + const bool bClockWiseArcDirection ); ImplPolygon( const Point& rBezPt1, const Point& rCtrlPt1, const Point& rBezPt2, const Point& rCtrlPt2, sal_uInt16 nPoints ); ImplPolygon(const basegfx::B2DPolygon& rPolygon); diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx index 0b8350bd8638..b68cb92425a7 100644 --- a/tools/source/generic/poly.cxx +++ b/tools/source/generic/poly.cxx @@ -306,6 +306,34 @@ ImplPolygon::ImplPolygon(const tools::Rectangle& rBound, const Point& rStart, co mnPoints = 0; } +ImplPolygon::ImplPolygon(const Point& aCenter, const sal_uInt32 nRadius, const float fStartAngle, + const float fSweepAngle, const bool bClockWiseArcDirection) +{ + float fStart = fStartAngle; + float fEnd = fStartAngle + fSweepAngle; + + if (bClockWiseArcDirection) + std::swap(fStart, fEnd); + float fDiff = fEnd - fStart; + float fStep = static_cast<float>(M_PI / 128.0); + + if ((fSweepAngle < 0.0) || bClockWiseArcDirection) + fStep = -fStep; + + const sal_uInt16 nPoints = static_cast<sal_uInt16>(fDiff / fStep) + 1; + + ImplInitSize(nPoints); + + for (sal_uInt16 i = 0; i < nPoints; i++, fStart += fStep) + { + Point& rPt = mxPointAry[i]; + rPt.setX(basegfx::fround<tools::Long>(aCenter.X() + nRadius * cos(fStart))); + rPt.setY(basegfx::fround<tools::Long>(aCenter.Y() - nRadius * sin(fStart))); + } + mxPointAry[nPoints - 1].setX(basegfx::fround<tools::Long>(aCenter.X() + nRadius * cos(fEnd))); + mxPointAry[nPoints - 1].setY(basegfx::fround<tools::Long>(aCenter.Y() - nRadius * sin(fEnd))); +} + ImplPolygon::ImplPolygon( const Point& rBezPt1, const Point& rCtrlPt1, const Point& rBezPt2, const Point& rCtrlPt2, sal_uInt16 nPoints ) { @@ -911,6 +939,12 @@ Polygon::Polygon(const tools::Rectangle& rBound, const Point& rStart, const Poin { } +Polygon::Polygon(const Point& aCenter, const sal_uInt32 nRadius, const float fStartAngle, + const float fSweepAngle, const bool bClockWiseArcDirection) + : mpImplPolygon(ImplPolygon(aCenter, nRadius, fStartAngle, fSweepAngle, bClockWiseArcDirection)) +{ +} + Polygon::Polygon( const Point& rBezPt1, const Point& rCtrlPt1, const Point& rBezPt2, const Point& rCtrlPt2, sal_uInt16 nPoints ) : mpImplPolygon(ImplPolygon(rBezPt1, rCtrlPt1, rBezPt2, rCtrlPt2, nPoints))