From ca67839234e78fe6bea21ec39906d1bd71d34d47 Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.com>
Date: Wed, 9 Dec 2020 09:38:48 +0100
Subject: vcl: improve EMF+ -> WMF conversion

We throw away EMF fallback info when parsing EMF+ data. This means that
the resulting GDIMetaFile (containing EMF+ data but no EMF fallback) is
tricky to export to WMF, where EMF+ comments are not allowed.

Improve the conversion result by re-parsing such EMF+ data with EMF+
disabled, and then converting the GDIMetaFile (containing EMF fallback
data) to WMF.

Change-Id: Ib2c0388f1344aef7f601ce9be59e4a8924e8085b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107453
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
---
 emfio/inc/emfreader.hxx            |  2 ++
 emfio/source/emfuno/xemfparser.cxx | 16 ++++++++++++++++
 emfio/source/reader/emfreader.cxx  |  6 ++++++
 3 files changed, 24 insertions(+)

(limited to 'emfio')

diff --git a/emfio/inc/emfreader.hxx b/emfio/inc/emfreader.hxx
index 39d576b64aed..e580835fc083 100644
--- a/emfio/inc/emfreader.hxx
+++ b/emfio/inc/emfreader.hxx
@@ -35,6 +35,7 @@ namespace emfio
         /// Another format is read already, can ignore actual EMF data.
         bool mbReadOtherGraphicFormat = false;
         basegfx::B2DTuple maSizeHint;
+        bool mbEnableEMFPlus = true;
 
         bool        ReadHeader();
         // reads and converts the rectangle
@@ -49,6 +50,7 @@ namespace emfio
         /// Parses EMR_COMMENT_MULTIFORMATS.
         void ReadMultiformatsComment();
         void SetSizeHint(const basegfx::B2DTuple& rSizeHint) { maSizeHint = rSizeHint; }
+        void SetEnableEMFPlus(bool bEnableEMFPlus) { mbEnableEMFPlus = bEnableEMFPlus; }
 
     private:
         template <class T> void ReadAndDrawPolyPolygon(sal_uInt32 nNextPos);
diff --git a/emfio/source/emfuno/xemfparser.cxx b/emfio/source/emfuno/xemfparser.cxx
index 8667ccf1faea..7788802c4e1c 100644
--- a/emfio/source/emfuno/xemfparser.cxx
+++ b/emfio/source/emfuno/xemfparser.cxx
@@ -33,6 +33,7 @@
 #include <unotools/ucbstreamhelper.hxx>
 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
 #include <sal/log.hxx>
+#include <comphelper/sequenceashashmap.hxx>
 
 #include <wmfreader.hxx>
 #include <emfreader.hxx>
@@ -87,6 +88,17 @@ namespace emfio::emfreader
             {
                 WmfExternal aExternalHeader;
                 const bool bExternalHeaderUsed(aExternalHeader.setSequence(rProperties));
+                bool bEnableEMFPlus = true;
+                comphelper::SequenceAsHashMap aMap(rProperties);
+                auto it = aMap.find("EMFPlusEnable");
+                if (it != aMap.end())
+                {
+                    bool bValue;
+                    if (it->second >>= bValue)
+                    {
+                        bEnableEMFPlus = bValue;
+                    }
+                }
 
                 // rough check - import and conv to primitive
                 GDIMetaFile aMtf;
@@ -110,6 +122,10 @@ namespace emfio::emfreader
                         // read and get possible failure/error, ReadEnhWMF returns success
                         emfio::EmfReader aReader(*pStream, aMtf);
                         aReader.SetSizeHint(maSizeHint);
+                        if (!bEnableEMFPlus)
+                        {
+                            aReader.SetEnableEMFPlus(bEnableEMFPlus);
+                        }
                         bReadError = !aReader.ReadEnhWMF();
                     }
                     else
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index 69916939fa26..ae00508380e1 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -803,6 +803,12 @@ namespace emfio
         OUString aEMFPlusDisable;
         rtl::Bootstrap::get("EMF_PLUS_DISABLE", aEMFPlusDisable);
         bool bEnableEMFPlus = aEMFPlusDisable.isEmpty();
+        if (!mbEnableEMFPlus)
+        {
+            // EMF+ is enabled if neither the bootstrap variable, not the member variable disables
+            // it.
+            bEnableEMFPlus = mbEnableEMFPlus;
+        }
 
         SAL_INFO("emfio", "EMF_PLUS_DISABLE is " << (bEnableEMFPlus ? "enabled" : "disabled"));
 
-- 
cgit