tdf#55058 tdf#141982 EMF: Add rotation support for ARC, ARCTO, CHORD, PIE

Change-Id: I5d9b76f0ddd2b7f12604f472986dd95976a8b04d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115185
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 3b08f7f..83b42a3 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -53,6 +53,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest:
    void TestTextMapMode();
    void TestEnglishMapMode();
    void TestRectangleWithModifyWorldTransform();
    void TestChordWithModifyWorldTransform();
    void TestEllipseWithSelectClipPath();
    void TestDrawPolyLine16WithClip();
    void TestFillRegion();
@@ -75,6 +76,7 @@ public:
    CPPUNIT_TEST(TestTextMapMode);
    CPPUNIT_TEST(TestEnglishMapMode);
    CPPUNIT_TEST(TestRectangleWithModifyWorldTransform);
    CPPUNIT_TEST(TestChordWithModifyWorldTransform);
    CPPUNIT_TEST(TestEllipseWithSelectClipPath);
    CPPUNIT_TEST(TestDrawPolyLine16WithClip);
    CPPUNIT_TEST(TestFillRegion);
@@ -334,6 +336,20 @@ void Test::TestRectangleWithModifyWorldTransform()
    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonstroke[1]/polygon", "1042,417 1960,946 2313,1556 1395,1028");
}

void Test::TestChordWithModifyWorldTransform()
{
    // EMF import test with records: CHORD, MODIFYWORLDTRANSFORM, EXTCREATEPEN, SELECTOBJECT
    Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestChordWithModifyWorldTransform.emf");
    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
    drawinglayer::Primitive2dXmlDump dumper;
    xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
    CPPUNIT_ASSERT (pDocument);

    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor", "color", "#ffffff");
    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor/polypolygon", "path", "m590 448-154 93-54 57-21 45 24 67 45 21 224-6 265-97z");
    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonstroke/polygon", "590,448 436,541 382,598 361,643 385,710 430,731 654,725 919,628");
}

void Test::TestEllipseWithSelectClipPath()
{
    // EMF import test with records: RECTANGLE, BEGINPATH, ENDPATH, ELLIPSE
diff --git a/emfio/qa/cppunit/emf/data/TestChordWithModifyWorldTransform.emf b/emfio/qa/cppunit/emf/data/TestChordWithModifyWorldTransform.emf
new file mode 100644
index 0000000..991a1f8
--- /dev/null
+++ b/emfio/qa/cppunit/emf/data/TestChordWithModifyWorldTransform.emf
Binary files differ
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index 3f1945b..96c935a 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -1367,18 +1367,17 @@ namespace emfio
                    break;

                    case EMR_ARC :
                    {
                        sal_uInt32 nStartX, nStartY, nEndX, nEndY;
                        mpInputStream->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
                        DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
                    }
                    break;

                    case EMR_ARCTO :
                    case EMR_CHORD :
                    {
                        sal_uInt32 nStartX, nStartY, nEndX, nEndY;
                        mpInputStream->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
                        DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
                        tools::Polygon aPoly( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), PolyStyle::Arc );
                        aPoly.Optimize( PolyOptimizeFlags::EDGES );
                        if ( nRecType == EMR_CHORD )
                            DrawPolygon( aPoly, mbRecordPath );
                        else
                            DrawPolyLine( aPoly, nRecType == EMR_ARCTO, mbRecordPath );
                    }
                    break;

@@ -1386,14 +1385,21 @@ namespace emfio
                    {
                        sal_uInt32 nStartX, nStartY, nEndX, nEndY;
                        mpInputStream->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
                        const tools::Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 ));
                        tools::Polygon aPoly;

                        // #i73608# OutputDevice deviates from WMF
                        // semantics. start==end means full ellipse here.
                        if( nStartX == nEndX && nStartY == nEndY )
                            DrawEllipse( aRect );
                        {
                            tools::Long dw = (nx32 - nX32) / 2;
                            tools::Long dh = (ny32 - nY32) / 2;
                            Point aCenter( nX32 + dw, nY32 + dh );
                            aPoly = tools::Polygon( aCenter, dw, dh );
                        }
                        else
                            DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
                            aPoly = tools::Polygon( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), PolyStyle::Pie );
                        aPoly.Optimize( PolyOptimizeFlags::EDGES );
                        DrawPolygon( aPoly, mbRecordPath );
                    }
                    break;

@@ -1404,14 +1410,6 @@ namespace emfio
                    }
                    break;

                    case EMR_ARCTO :
                    {
                        sal_uInt32 nStartX, nStartY, nEndX, nEndY;
                        mpInputStream->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
                        DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), true );
                    }
                    break;

                    case EMR_BEGINPATH :
                    {
                        ClearPath();