[Libreoffice-commits] core.git: emfio/inc emfio/qa emfio/source

Bartosz Kosiorek (via logerrit) logerrit at kemper.freedesktop.org
Fri Jun 11 10:32:46 UTC 2021


 emfio/inc/mtftools.hxx                      |    2 
 emfio/qa/cppunit/emf/EmfImportTest.cxx      |   59 ++++++++++++++++++++++++++++
 emfio/qa/cppunit/emf/data/TestRestoreDC.emf |binary
 emfio/qa/cppunit/wmf/data/TestRestoreDC.wmf |binary
 emfio/source/reader/emfreader.cxx           |    6 ++
 emfio/source/reader/mtftools.cxx            |   21 ++++++++-
 emfio/source/reader/wmfreader.cxx           |    5 +-
 7 files changed, 87 insertions(+), 6 deletions(-)

New commits:
commit cabb9f5c8e22a23a453559636d9c9b3c2b0a5984
Author:     Bartosz Kosiorek <gang65 at poczta.onet.pl>
AuthorDate: Fri Jun 11 22:25:42 2021 +0200
Commit:     Bartosz Kosiorek <gang65 at poczta.onet.pl>
CommitDate: Fri Jun 11 12:31:59 2021 +0200

    WMF/EMF tdf#59814 tdf#142567 Fix RestoreDC record
    
    With previous implementation, the RestoreDC index argument was skipped,
    and always the last entry was taken.
    
    With this commit the support for reading SaveDC by specific index
    was added. The SaveDC/RestoreDC index support was added for
    both EMF and WMF, according to [MS-WMF] and [MS-EMF] documentation.
    
    Change-Id: I9b8a1a41462ae01de25ac3c85e453bcd80e05537
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117033
    Tested-by: Jenkins
    Reviewed-by: Bartosz Kosiorek <gang65 at poczta.onet.pl>

diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx
index cffe5e4fa511..456f2349cbf9 100644
--- a/emfio/inc/mtftools.hxx
+++ b/emfio/inc/mtftools.hxx
@@ -614,7 +614,7 @@ namespace emfio
         void                ModifyWorldTransform(const XForm& rXForm, sal_uInt32 nMode);
 
         void                Push();
-        void                Pop();
+        void                Pop( const sal_Int32 nSavedDC = -1 );
 
         WMFRasterOp         SetRasterOp(WMFRasterOp nRasterOp);
         void                StrokeAndFillPath(bool bStroke, bool bFill);
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 8c56190203b0..1383b5fdfc03 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -65,10 +65,13 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest:
     void TestBitBltStretchBltWMF();
     void TestExtTextOutOpaqueAndClipWMF();
     void TestPaletteWMF();
+    void TestRestoreDCWMF();
     void TestRoundrectWMF();
     void TestStretchDIBWMF();
     void TestPolylinetoCloseStroke();
     void TestPolyLineWidth();
+
+    void TestRestoreDC();
     void TestRoundRect();
     void TestCreatePen();
     void TestPdfInEmf();
@@ -101,10 +104,12 @@ public:
     CPPUNIT_TEST(TestBitBltStretchBltWMF);
     CPPUNIT_TEST(TestExtTextOutOpaqueAndClipWMF);
     CPPUNIT_TEST(TestPaletteWMF);
+    CPPUNIT_TEST(TestRestoreDCWMF);
     CPPUNIT_TEST(TestRoundrectWMF);
     CPPUNIT_TEST(TestStretchDIBWMF);
     CPPUNIT_TEST(TestPolylinetoCloseStroke);
     CPPUNIT_TEST(TestPolyLineWidth);
+    CPPUNIT_TEST(TestRestoreDC);
     CPPUNIT_TEST(TestRoundRect);
     CPPUNIT_TEST(TestCreatePen);
     CPPUNIT_TEST(TestPdfInEmf);
@@ -699,6 +704,7 @@ void Test::TestExtTextOutOpaqueAndClipWMF()
 #endif
 }
 
+
 void Test::TestPaletteWMF()
 {
     // WMF import with records: CREATEPALETTE, SELECTOBJECT, CREATEPENINDIRECT, CREATEBRUSHINDIRECT, ELLIPSE.
@@ -735,6 +741,40 @@ void Test::TestPaletteWMF()
                 "width", "132");
 }
 
+void Test::TestRestoreDCWMF()
+{
+    // WMF records: RESTOREDC, SAVEDC, CREATEBRUSHINDIRECT, RECTANGLE.
+    Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/wmf/data/TestRestoreDC.wmf");
+    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", 3);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[1]",
+                "color", "#0000ff");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[1]/polypolygon",
+                "path", "m238 2884h1640v1110h-1640z");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonhairline[1]",
+                "color", "#000000");
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonhairline[1]/polygon",
+                       "238,2884 1878,2884 1878,3994 238,3994");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[2]",
+                "color", "#ff0000");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[2]/polypolygon",
+                "path", "m238 238h1640v1110h-1640z");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonhairline[2]",
+                "color", "#000000");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[3]",
+                "color", "#ff0000");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[3]/polypolygon",
+                "path", "m238 5530h1640v1110h-1640z");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonhairline[3]",
+                "color", "#000000");
+}
+
 void Test::TestRoundrectWMF()
 {
     // WMF records: ROUNDRECT, SETBKCOLOR, CREATEBRUSHINDIRECT
@@ -815,6 +855,25 @@ void Test::TestPolyLineWidth()
                 "width", "71");
 }
 
+void Test::TestRestoreDC()
+{
+    // EMF records: SAVEDC, RESTOREDC, POLYGON16, MODIFYWORLDTRANSFORM
+    Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestRestoreDC.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", "#ff0000");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor/polypolygon",
+                "path", "m1148 4354v1481h4943v-1481z");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonhairline",
+                "color", "#000000");
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonhairline/polygon",
+                       "1148,4354 1148,5835 6091,5835 6091,4354");
+}
+
 void Test::TestRoundRect()
 {
     // EMF import with records: CREATEPEN, ROUNDRECT.
diff --git a/emfio/qa/cppunit/emf/data/TestRestoreDC.emf b/emfio/qa/cppunit/emf/data/TestRestoreDC.emf
new file mode 100644
index 000000000000..b65b48d6b1f7
Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TestRestoreDC.emf differ
diff --git a/emfio/qa/cppunit/wmf/data/TestRestoreDC.wmf b/emfio/qa/cppunit/wmf/data/TestRestoreDC.wmf
new file mode 100644
index 000000000000..c81244f6bf68
Binary files /dev/null and b/emfio/qa/cppunit/wmf/data/TestRestoreDC.wmf differ
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index 064a8b0334c9..ac56c64db026 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -1098,7 +1098,11 @@ namespace emfio
 
                     case EMR_RESTOREDC :
                     {
-                        Pop();
+                        sal_Int32 nSavedDC;
+                        mpInputStream->ReadInt32( nSavedDC );
+                        SAL_INFO( "emfio", "\t\t SavedDC Index: " << nSavedDC );
+                        if ( nSavedDC < 0 ) // For EMF values above -1 is ignored
+                            Pop( nSavedDC );
                     }
                     break;
 
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index 866f6996d9e3..e4d2ed462bdb 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -2452,15 +2452,29 @@ namespace emfio
         SAL_INFO("emfio", "\t\t WinExt: " << mnWinExtX << " x " << mnWinExtY);
         SAL_INFO("emfio", "\t\t DevOrg: " << mnDevOrgX << ", " << mnDevOrgY);
         SAL_INFO("emfio", "\t\t DevWidth/Height: " << mnDevWidth << " x " << mnDevHeight);
+        SAL_INFO("emfio", "\t\t LineStyle: " << maLineStyle.aLineColor << " FillStyle: " << maFillStyle.aFillColor );
         mvSaveStack.push_back( pSave );
     }
 
-    void MtfTools::Pop()
+    void MtfTools::Pop( const sal_Int32 nSavedDC )
     {
-        // Get the latest data from the stack
-        if( mvSaveStack.empty() )
+        if ( nSavedDC == 0 )
             return;
 
+        sal_Int32 aIndex;
+        if ( nSavedDC < 0 ) // WMF/EMF, if negative, nSavedDC represents an instance relative to the current state.
+            aIndex = static_cast< sal_Int32 >( mvSaveStack.size() ) + nSavedDC;
+        else
+            aIndex = nSavedDC; // WMF, if positive, nSavedDC represents a specific instance of the state to be restored.
+        if( aIndex < 0 )
+        {
+            mvSaveStack.clear();
+            return;
+        }
+        if( mvSaveStack.empty() || ( aIndex >= static_cast< sal_Int32 >( mvSaveStack.size() ) ) )
+            return;
+
+        mvSaveStack.resize( aIndex + 1 );
         // Backup the current data on the stack
         std::shared_ptr<SaveStruct>& pSave( mvSaveStack.back() );
 
@@ -2508,6 +2522,7 @@ namespace emfio
         SAL_INFO("emfio", "\t\t WinExt: " << mnWinExtX << " x " << mnWinExtY);
         SAL_INFO("emfio", "\t\t DevOrg: " << mnDevOrgX << ", " << mnDevOrgY);
         SAL_INFO("emfio", "\t\t DevWidth/Height: " << mnDevWidth << " x " << mnDevHeight);
+        SAL_INFO("emfio", "\t\t LineStyle: " << maLineStyle.aLineColor << " FillStyle: " << maFillStyle.aFillColor );
         mvSaveStack.pop_back();
     }
 
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index 64dbf6658854..38f6252afa59 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -600,7 +600,10 @@ namespace emfio
 
             case W_META_RESTOREDC:
             {
-                Pop();
+                sal_Int16 nSavedDC;
+                mpInputStream->ReadInt16( nSavedDC );
+                SAL_INFO( "emfio", "\t\t SavedDC: " << nSavedDC );
+                Pop( nSavedDC );
             }
             break;
 


More information about the Libreoffice-commits mailing list