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

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Fri Jun 11 22:00:53 UTC 2021


 vcl/qa/cppunit/GraphicTest.cxx               |   79 +++++++++++++++++++++++++++
 vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf |binary
 vcl/source/filter/wmf/wmf.cxx                |   11 ++-
 3 files changed, 85 insertions(+), 5 deletions(-)

New commits:
commit 6b349bcc32336664a31deed3f4463e40dd028f63
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Jun 11 15:51:32 2021 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Jun 11 23:59:46 2021 +0200

    when converting WMF to WMF, simply do a direct copy
    
    Actually, if we have the graphics data, just copy the graphics data,
    that'll keep both the EMF+ and non-EMF+ content.
    
    Change-Id: Ia14df0ba2a94d4310ee745b49de1d2190e425f05
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117063
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index 608c5f4de85d..e9af574aa5a4 100644
--- a/vcl/qa/cppunit/GraphicTest.cxx
+++ b/vcl/qa/cppunit/GraphicTest.cxx
@@ -28,6 +28,7 @@
 #include <unotools/tempfile.hxx>
 #include <vcl/cvtgrf.hxx>
 #include <vcl/metaact.hxx>
+#include <vcl/wmf.hxx>
 
 #include <impgraph.hxx>
 #include <graphic/GraphicFormatDetector.hxx>
@@ -53,6 +54,7 @@ private:
     void testUnloadedGraphicSizeUnit();
 
     void testWMFRoundtrip();
+    void testWMFWithEmfPlusRoundtrip();
     void testEmfToWmfConversion();
 
     void testSwappingGraphic_PNG_WithGfxLink();
@@ -89,6 +91,7 @@ private:
     CPPUNIT_TEST(testUnloadedGraphicAlpha);
     CPPUNIT_TEST(testUnloadedGraphicSizeUnit);
     CPPUNIT_TEST(testWMFRoundtrip);
+    CPPUNIT_TEST(testWMFWithEmfPlusRoundtrip);
     CPPUNIT_TEST(testEmfToWmfConversion);
 
     CPPUNIT_TEST(testSwappingGraphic_PNG_WithGfxLink);
@@ -411,6 +414,82 @@ void GraphicTest::testWMFRoundtrip()
     CPPUNIT_ASSERT_EQUAL(nExpectedSize, nActualSize);
 }
 
+int getEmfPlusActionsCount(const Graphic& graphic)
+{
+    const GDIMetaFile& metafile = graphic.GetGDIMetaFile();
+    int emfPlusCount = 0;
+    for (size_t i = 0; i < metafile.GetActionSize(); ++i)
+    {
+        MetaAction* action = metafile.GetAction(i);
+        if (action->GetType() == MetaActionType::COMMENT)
+        {
+            const MetaCommentAction* commentAction = static_cast<const MetaCommentAction*>(action);
+            if (commentAction->GetComment() == "EMF_PLUS")
+                ++emfPlusCount;
+        }
+    }
+    return emfPlusCount;
+}
+
+int getPolygonActionsCount(const Graphic& graphic)
+{
+    const GDIMetaFile& metafile = graphic.GetGDIMetaFile();
+    int polygonCount = 0;
+    for (size_t i = 0; i < metafile.GetActionSize(); ++i)
+    {
+        MetaAction* action = metafile.GetAction(i);
+        if (action->GetType() == MetaActionType::POLYGON)
+            ++polygonCount;
+    }
+    return polygonCount;
+}
+
+void GraphicTest::testWMFWithEmfPlusRoundtrip()
+{
+    // Load a WMF file.
+    test::Directories aDirectories;
+    OUString aURL = aDirectories.getURLFromSrc(u"vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf");
+    SvFileStream aStream(aURL, StreamMode::READ);
+    sal_uInt64 nExpectedSize = aStream.TellEnd();
+    GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
+    Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream);
+
+    CPPUNIT_ASSERT_GREATER(0, getEmfPlusActionsCount(aGraphic));
+    CPPUNIT_ASSERT_EQUAL(0, getPolygonActionsCount(aGraphic));
+
+    for (bool useConvertMetafile : { false, true })
+    {
+        // Save as WMF.
+        utl::TempFile aTempFile;
+        aTempFile.EnableKillingFile();
+        SvStream& rOutStream = *aTempFile.GetStream(StreamMode::READWRITE);
+        if (useConvertMetafile)
+            ConvertGraphicToWMF(aGraphic, rOutStream, nullptr);
+        else
+        {
+            sal_uInt16 nFormat = rGraphicFilter.GetExportFormatNumberForShortName(u"WMF");
+            rGraphicFilter.ExportGraphic(aGraphic, OUString(), rOutStream, nFormat);
+        }
+        CPPUNIT_ASSERT_EQUAL(nExpectedSize, rOutStream.TellEnd());
+
+        rOutStream.Seek(0);
+        Graphic aNewGraphic = rGraphicFilter.ImportUnloadedGraphic(rOutStream);
+        // Check that reading the WMF back preserves the EMF+ actions in it.
+        CPPUNIT_ASSERT_GREATER(0, getEmfPlusActionsCount(aNewGraphic));
+        // EmfReader::ReadEnhWMF() drops non-EMF+ drawing actions if EMF+ is found.
+        CPPUNIT_ASSERT_EQUAL(0, getPolygonActionsCount(aNewGraphic));
+
+        // With EMF+ disabled there should be no EMF+ actions.
+        auto& rDataContainer = aNewGraphic.GetGfxLink().getDataContainer();
+        auto aVectorGraphicData
+            = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Wmf);
+        aVectorGraphicData->setEnableEMFPlus(false);
+        Graphic aNoEmfPlusGraphic(aVectorGraphicData);
+        CPPUNIT_ASSERT_EQUAL(0, getEmfPlusActionsCount(aNoEmfPlusGraphic));
+        CPPUNIT_ASSERT_GREATER(0, getPolygonActionsCount(aNoEmfPlusGraphic));
+    }
+}
+
 void GraphicTest::testEmfToWmfConversion()
 {
     // Load EMF data.
diff --git a/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf
new file mode 100644
index 000000000000..1e7f75b19809
Binary files /dev/null and b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf differ
diff --git a/vcl/source/filter/wmf/wmf.cxx b/vcl/source/filter/wmf/wmf.cxx
index ee1ce77e4185..bf91502b426e 100644
--- a/vcl/source/filter/wmf/wmf.cxx
+++ b/vcl/source/filter/wmf/wmf.cxx
@@ -90,13 +90,14 @@ bool ConvertGraphicToWMF(const Graphic& rGraphic, SvStream& rTargetStream,
     GfxLink aLink = rGraphic.GetGfxLink();
     if (aLink.GetType() == GfxLinkType::NativeWmf && aLink.GetData() && aLink.GetDataSize())
     {
-        // This may be an EMF+ file or WMF file with EMF+ embedded. In EmfReader::ReadEnhWMF()
-        // we normally drop non-EMF commands when reading EMF+, so converting that to WMF
-        // is better done by re-parsing with EMF+ disabled.
+        if(!aLink.IsEMF()) // If WMF, just write directly.
+            return rTargetStream.WriteBytes(aLink.GetData(), aLink.GetDataSize()) == aLink.GetDataSize();
+
+        // This may be an EMF+ file. In EmfReader::ReadEnhWMF() we normally drop non-EMF commands
+        // when reading EMF+, so converting that to WMF is better done by re-parsing with EMF+ disabled.
         auto & rDataContainer = aLink.getDataContainer();
         auto aVectorGraphicData
-            = std::make_shared<VectorGraphicData>(rDataContainer,
-                aLink.IsEMF() ? VectorGraphicDataType::Emf : VectorGraphicDataType::Wmf);
+            = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Emf);
         aVectorGraphicData->setEnableEMFPlus(false);
         Graphic aGraphic(aVectorGraphicData);
         bool bRet = ConvertGDIMetaFileToWMF(aGraphic.GetGDIMetaFile(), rTargetStream, pConfigItem,


More information about the Libreoffice-commits mailing list