[Libreoffice-commits] core.git: Branch 'feature/emfplusprimitiveparser' - drawinglayer/source emfio/inc emfio/source include/drawinglayer include/oox include/vcl offapi/com oox/source svtools/source vcl/Library_vcl.mk vcl/qa vcl/source writerfilter/source xmlsecurity/workben

Armin Le Grand Armin.Le.Grand at cib.de
Fri Jun 16 15:19:00 UTC 2017


 drawinglayer/source/primitive2d/metafileprimitive2d.cxx  |    7 
 emfio/inc/wmfreader.hxx                                  |    8 
 emfio/source/emfuno/xemfparser.cxx                       |  161 -
 emfio/source/reader/mtftools.cxx                         |    3 
 emfio/source/reader/wmfreader.cxx                        |   54 
 include/drawinglayer/primitive2d/metafileprimitive2d.hxx |    6 
 include/oox/helper/graphichelper.hxx                     |    8 
 include/vcl/gdimetafiletools.hxx                         |    9 
 include/vcl/graphicfilter.hxx                            |    6 
 include/vcl/vectorgraphicdata.hxx                        |   11 
 include/vcl/wmf.hxx                                      |   33 
 include/vcl/wmfexternal.hxx                              |   55 
 offapi/com/sun/star/graphic/XEmfParser.idl               |    8 
 oox/source/drawingml/shape.cxx                           |    2 
 oox/source/helper/graphichelper.cxx                      |    6 
 oox/source/vml/vmlshape.cxx                              |    2 
 svtools/source/graphic/provider.cxx                      |    4 
 vcl/Library_vcl.mk                                       |    4 
 vcl/qa/cppunit/wmf/wmfimporttest.cxx                     |    1 
 vcl/source/filter/graphicfilter.cxx                      |   72 
 vcl/source/filter/wmf/enhwmf.cxx                         | 1966 -------------
 vcl/source/filter/wmf/winmtf.cxx                         | 2248 ---------------
 vcl/source/filter/wmf/winmtf.hxx                         |  723 ----
 vcl/source/filter/wmf/winwmf.cxx                         | 1836 ------------
 vcl/source/filter/wmf/wmf.cxx                            |   73 
 vcl/source/filter/wmf/wmfexternal.cxx                    |   76 
 vcl/source/gdi/impgraph.cxx                              |   27 
 vcl/source/gdi/vectorgraphicdata.cxx                     |   32 
 writerfilter/source/rtftok/rtfdocumentimpl.cxx           |    4 
 xmlsecurity/workben/pdfverify.cxx                        |    2 
 30 files changed, 408 insertions(+), 7039 deletions(-)

New commits:
commit e76f931777616c10660ef11d3b348efb3107a23b
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Fri Jun 16 17:16:22 2017 +0200

    emfplus: completed isolation/migration of Emf/Wmf
    
    Decided to keep the migrated/isolated Emf/Wmf reader
    which are now hidden behind a Uno Api. Had to re-implement
    WMF_EXTERNALHEADER (now WmfExternal, own file/header)
    to not break anything. It *seems* to just scale something
    and could be done after import, but I could not be sure.
    Also needed a callback hook to allow getting the Metafile
    out of a MetafilePrimitive in a lower module (vcl relative
    to drawinglayer) which is needed as long as primitives
    are not completely on Uno Api. Deleted all Emf/Wmf reader
    stuff from vcl.
    
    Change-Id: Ic5540defa8ec770728280df4df3f12e1f48cfc3a

diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
index e07033aa50d5..4737f78c765b 100644
--- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
@@ -3244,6 +3244,13 @@ namespace drawinglayer
             return aRetval;
         }
 
+        // from MetafileAccessor
+        bool MetafilePrimitive2D::accessMetafile(GDIMetaFile& rTargetMetafile) const
+        {
+            rTargetMetafile = maMetaFile;
+            return true;
+        }
+
         // provide unique ID
         ImplPrimitive2DIDBlock(MetafilePrimitive2D, PRIMITIVE2D_ID_METAFILEPRIMITIVE2D)
 
diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx
index e0566bb95cfb..1cd6077b05d8 100644
--- a/emfio/inc/wmfreader.hxx
+++ b/emfio/inc/wmfreader.hxx
@@ -23,6 +23,9 @@
 #include <mtftools.hxx>
 #include <tools/stream.hxx>
 
+// predefines
+struct WmfExternal;
+
 namespace emfio
 {
     class WmfReader : public MtfTools
@@ -46,6 +49,9 @@ namespace emfio
         sal_uInt32      mnSkipActions;
         sal_uInt32      mnCurrentAction;
 
+        // eventually handed over external header
+        const WmfExternal* mpExternalHeader;
+
         // reads header of the WMF-Datei
         bool            ReadHeader();
 
@@ -59,7 +65,7 @@ namespace emfio
         void            GetPlaceableBound(tools::Rectangle& rSize, SvStream* pStrm);
 
     public:
-        WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile);
+        WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader);
 
         // read WMF file from stream and fill the GDIMetaFile
         void ReadWMF();
diff --git a/emfio/source/emfuno/xemfparser.cxx b/emfio/source/emfuno/xemfparser.cxx
index 89d34dff1521..433210c5ecd2 100644
--- a/emfio/source/emfuno/xemfparser.cxx
+++ b/emfio/source/emfuno/xemfparser.cxx
@@ -33,7 +33,6 @@
 
 #include <vcl/svapp.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
-#include <vcl/wmf.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
 
@@ -69,7 +68,8 @@ namespace emfio
             // XEmfParser
             virtual uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > SAL_CALL getDecomposition(
                 const uno::Reference< ::io::XInputStream >& xEmfStream,
-                const OUString& aAbsolutePath) override;
+                const OUString& aAbsolutePath,
+                const uno::Sequence< ::beans::PropertyValue >& rProperties) override;
 
             // XServiceInfo
             virtual OUString SAL_CALL getImplementationName() override;
@@ -113,114 +113,85 @@ namespace emfio
 
         uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > XEmfParser::getDecomposition(
             const uno::Reference< ::io::XInputStream >& xEmfStream,
-            const OUString& aAbsolutePath )
+            const OUString& aAbsolutePath,
+            const uno::Sequence< ::beans::PropertyValue >& rProperties)
         {
             drawinglayer::primitive2d::Primitive2DContainer aRetval;
 
             if (xEmfStream.is())
             {
-                static bool bTestCode(false);
+                WmfExternal aExternalHeader;
+                const bool bExternalHeaderUsed(aExternalHeader.setSequence(rProperties));
 
-                if (bTestCode)
+                // rough check - import and conv to primitive
+                GDIMetaFile aMtf;
+                std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream));
+                sal_uInt32 nMetaType(0);
+                sal_uInt32 nOrgPos = pStream->Tell();
+
+                SvStreamEndian nOrigNumberFormat = pStream->GetEndian();
+                pStream->SetEndian(SvStreamEndian::LITTLE);
+
+                pStream->Seek(0x28);
+                pStream->ReadUInt32(nMetaType);
+                pStream->Seek(nOrgPos);
+
+                if (nMetaType == 0x464d4520)
+                {
+                    emfio::EmfReader(*pStream, aMtf).ReadEnhWMF();
+                }
+                else
+                {
+                    emfio::WmfReader(*pStream, aMtf, bExternalHeaderUsed ? &aExternalHeader : nullptr).ReadWMF();
+                }
+
+                pStream->SetEndian(nOrigNumberFormat);
+                Size aSize(aMtf.GetPrefSize());
+
+                if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
                 {
-                    static bool bUseOldFilterEmbedded(true);
-
-                    if (bUseOldFilterEmbedded)
-                    {
-                        GDIMetaFile aMtf;
-                        std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream));
-
-                        if (pStream && ConvertWMFToGDIMetaFile(*pStream, aMtf, nullptr, nullptr))
-                        {
-
-                            Size aSize(aMtf.GetPrefSize());
-
-                            if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
-                            {
-                                aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM);
-                            }
-                            else
-                            {
-                                aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM));
-                            }
-
-                            const basegfx::B2DHomMatrix aMetafileTransform(
-                                basegfx::tools::createScaleB2DHomMatrix(
-                                    aSize.Width(),
-                                    aSize.Height()));
-
-                            aRetval.push_back(
-                                new drawinglayer::primitive2d::MetafilePrimitive2D(
-                                    aMetafileTransform,
-                                    aMtf));
-                        }
-                    }
-
-                    if(aRetval.empty())
-                    {
-                        // for test, just create some graphic data that will get visualized
-                        const basegfx::B2DRange aRange(1000, 1000, 5000, 5000);
-                        const basegfx::BColor aColor(1.0, 0.0, 0.0);
-                        const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
-
-                        aRetval.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aColor));
-                    }
+                    aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM);
                 }
                 else
                 {
-                    // new parser here
-                    bool bBla = true;
-
-                    // rouch check - import and conv to primitive
-                    GDIMetaFile aMtf;
-                    std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream));
-                    sal_uInt32 nMetaType(0);
-                    sal_uInt32 nOrgPos = pStream->Tell();
-
-                    SvStreamEndian nOrigNumberFormat = pStream->GetEndian();
-                    pStream->SetEndian(SvStreamEndian::LITTLE);
-
-                    pStream->Seek(0x28);
-                    pStream->ReadUInt32(nMetaType);
-                    pStream->Seek(nOrgPos);
-
-                    if (nMetaType == 0x464d4520)
-                    {
-                        emfio::EmfReader(*pStream, aMtf).ReadEnhWMF();
-                    }
-                    else
-                    {
-                        emfio::WmfReader(*pStream, aMtf).ReadWMF();
-                    }
-
-                    pStream->SetEndian(nOrigNumberFormat);
-                    Size aSize(aMtf.GetPrefSize());
-
-                    if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
-                    {
-                        aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM);
-                    }
-                    else
-                    {
-                        aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM));
-                    }
-
-                    const basegfx::B2DHomMatrix aMetafileTransform(
-                        basegfx::tools::createScaleB2DHomMatrix(
-                            aSize.Width(),
-                            aSize.Height()));
-
-                    // force to use decomposition directly to get rid of the metafile
-                    const css::uno::Sequence< css::beans::PropertyValue > aViewParameters;
-                    drawinglayer::primitive2d::MetafilePrimitive2D aMetafilePrimitive2D(
+                    aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM));
+                }
+
+                // use size
+                const basegfx::B2DHomMatrix aMetafileTransform(
+                    basegfx::tools::createScaleB2DHomMatrix(
+                        aSize.Width(),
+                        aSize.Height()));
+
+                // ...and create a single MetafilePrimitive2D containing the Metafile.
+                // CAUTION: Currently, ReadWindowMetafile uses the local VectorGraphicData
+                // and a MetafileAccessor hook at the MetafilePrimitive2D inside of
+                // ImpGraphic::ImplGetGDIMetaFile to get the Metafile. Thus, the first
+                // and only primitive in this case *has to be* a MetafilePrimitive2D.
+                aRetval.push_back(
+                    new drawinglayer::primitive2d::MetafilePrimitive2D(
                         aMetafileTransform,
-                        aMtf);
-                    aRetval.append(aMetafilePrimitive2D.getDecomposition(aViewParameters));
+                        aMtf));
 
+                // // force to use decomposition directly to get rid of the metafile
+                // const css::uno::Sequence< css::beans::PropertyValue > aViewParameters;
+                // drawinglayer::primitive2d::MetafilePrimitive2D aMetafilePrimitive2D(
+                //     aMetafileTransform,
+                //     aMtf);
+                // aRetval.append(aMetafilePrimitive2D.getDecomposition(aViewParameters));
+
+                // if (aRetval.empty())
+                // {
+                //     // for test, just create some graphic data that will get visualized
+                //     const basegfx::B2DRange aRange(1000, 1000, 5000, 5000);
+                //     const basegfx::BColor aColor(1.0, 0.0, 0.0);
+                //     const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange));
+                //
+                //     aRetval.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aColor));
+                // }
 
 
 
-                }
             }
             else
             {
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index 96d4d5232e7e..05b8cf43bed0 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -20,13 +20,10 @@
 #include <mtftools.hxx>
 
 #include <memory>
-//#include "winmtf.hxx"
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
-//#include <vcl/metaact.hxx>
 #include <vcl/graphictools.hxx>
 #include <vcl/canvastools.hxx>
-//#include <vcl/metric.hxx>
 #include <vcl/svapp.hxx>
 #include <tools/fract.hxx>
 #include <rtl/strbuf.hxx>
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index dd41a7a1abbb..9cbe518d7e28 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -1242,26 +1242,45 @@ namespace emfio
         {
             mnUnitsPerInch = 96;
 
+            if (mpExternalHeader != nullptr
+                && mpExternalHeader->xExt > 0
+                && mpExternalHeader->yExt > 0
+                && (mpExternalHeader->mapMode == MM_ISOTROPIC || mpExternalHeader->mapMode == MM_ANISOTROPIC))
+            {
+                // #n417818#: If we have an external header then overwrite the bounds!
+                tools::Rectangle aExtRect(0, 0,
+                    (double)mpExternalHeader->xExt * 567 * mnUnitsPerInch / 1440000,
+                    (double)mpExternalHeader->yExt * 567 * mnUnitsPerInch / 1440000);
+                aPlaceableBound = aExtRect;
+
+                SAL_INFO("vcl.wmf", "External header size "
+                    " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top()
+                    << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom());
 
-            mpInputStream->Seek( nStrmPos + 18 );    // set the streampos to the start of the metaactions
-            GetPlaceableBound( aPlaceableBound, mpInputStream );
-
-            // The image size is not known so normalize the calculated bounds so that the
-            // resulting image is not too big
-            const double fMaxWidth = static_cast<double>(aMaxWidth);
-            if (aPlaceableBound.GetWidth() > aMaxWidth)
+                SetMapMode(mpExternalHeader->mapMode);
+            }
+            else
             {
-                double fRatio = aPlaceableBound.GetWidth() / fMaxWidth;
+                mpInputStream->Seek(nStrmPos + 18);    // set the streampos to the start of the metaactions
+                GetPlaceableBound(aPlaceableBound, mpInputStream);
 
-                aPlaceableBound = tools::Rectangle(
-                                    aPlaceableBound.Left()   / fRatio,
-                                    aPlaceableBound.Top()    / fRatio,
-                                    aPlaceableBound.Right()  / fRatio,
-                                    aPlaceableBound.Bottom() / fRatio);
+                // The image size is not known so normalize the calculated bounds so that the
+                // resulting image is not too big
+                const double fMaxWidth = static_cast<double>(aMaxWidth);
+                if (aPlaceableBound.GetWidth() > aMaxWidth)
+                {
+                    double fRatio = aPlaceableBound.GetWidth() / fMaxWidth;
 
-                SAL_INFO("vcl.wmf", "Placeable bounds "
-                        " t: " << aPlaceableBound.Left()  << " l: " << aPlaceableBound.Top()
-                    << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom());
+                    aPlaceableBound = tools::Rectangle(
+                        aPlaceableBound.Left() / fRatio,
+                        aPlaceableBound.Top() / fRatio,
+                        aPlaceableBound.Right() / fRatio,
+                        aPlaceableBound.Bottom() / fRatio);
+
+                    SAL_INFO("vcl.wmf", "Placeable bounds "
+                        " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top()
+                        << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom());
+                }
             }
 
             mpInputStream->Seek( nStrmPos );
@@ -1800,7 +1819,7 @@ namespace emfio
         }
     }
 
-    WmfReader::WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile)
+    WmfReader::WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader)
         : MtfTools(rGDIMetaFile, rStreamWMF)
         , mnUnitsPerInch(96)
         , mnRecSize(0)
@@ -1810,6 +1829,7 @@ namespace emfio
         , mnEMFSize(0)
         , mnSkipActions(0)
         , mnCurrentAction(0)
+        , mpExternalHeader(pExternalHeader)
     {
     }
 }
diff --git a/include/drawinglayer/primitive2d/metafileprimitive2d.hxx b/include/drawinglayer/primitive2d/metafileprimitive2d.hxx
index 0d1503809a81..e849e38b5752 100644
--- a/include/drawinglayer/primitive2d/metafileprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/metafileprimitive2d.hxx
@@ -25,6 +25,7 @@
 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
 #include <basegfx/matrix/b2dhommatrix.hxx>
 #include <vcl/gdimtf.hxx>
+#include <vcl/gdimetafiletools.hxx>
 
 
 // MetafilePrimitive2D class
@@ -53,7 +54,7 @@ namespace drawinglayer
             have many advantages; Metafile would no longer have to be rendered by
             sub-systems and a standard way for converting Metafiles would exist.
          */
-        class DRAWINGLAYER_DLLPUBLIC MetafilePrimitive2D : public BufferedDecompositionPrimitive2D
+        class DRAWINGLAYER_DLLPUBLIC MetafilePrimitive2D : public BufferedDecompositionPrimitive2D, public MetafileAccessor
         {
         private:
             /// the geometry definition
@@ -81,6 +82,9 @@ namespace drawinglayer
             /// get range
             virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
 
+            /// from MetafileAccessor
+            virtual bool accessMetafile(GDIMetaFile& rTargetMetafile) const;
+
             /// provide unique ID
             DeclPrimitive2DIDBlock()
         };
diff --git a/include/oox/helper/graphichelper.hxx b/include/oox/helper/graphichelper.hxx
index 651e9407b4ec..545bdd0fd938 100644
--- a/include/oox/helper/graphichelper.hxx
+++ b/include/oox/helper/graphichelper.hxx
@@ -33,7 +33,7 @@
 #include <sal/types.h>
 #include <com/sun/star/graphic/XGraphicProvider2.hpp>
 
-struct WMF_EXTERNALHEADER;
+struct WmfExternal;
 
 namespace com { namespace sun { namespace star {
     namespace awt { struct Point; }
@@ -113,7 +113,7 @@ public:
     css::uno::Reference< css::graphic::XGraphic >
                         importGraphic(
                             const css::uno::Reference< css::io::XInputStream >& rxInStrm,
-                            const WMF_EXTERNALHEADER* pExtHeader = nullptr ) const;
+                            const WmfExternal* pExtHeader = nullptr ) const;
 
     /** Imports graphics from the passed input streams. */
     std::vector< css::uno::Reference<css::graphic::XGraphic> >
@@ -127,7 +127,7 @@ public:
     css::uno::Reference< css::graphic::XGraphic >
                         importEmbeddedGraphic(
                             const OUString& rStreamName,
-                            const WMF_EXTERNALHEADER* pExtHeader = nullptr ) const;
+                            const WmfExternal* pExtHeader = nullptr ) const;
 
     /** Imports graphics from the storage with the passed stream names. */
     void importEmbeddedGraphics(const std::vector<OUString>& rStreamNames) const;
@@ -141,7 +141,7 @@ public:
         @return  The URL of the created and internally cached graphic object. */
     OUString     importGraphicObject(
                             const css::uno::Reference< css::io::XInputStream >& rxInStrm,
-                            const WMF_EXTERNALHEADER* pExtHeader ) const;
+                            const WmfExternal* pExtHeader ) const;
 
     /** Creates a persistent graphic object from the passed binary memory block.
         @return  The URL of the created and internally cached graphic object. */
diff --git a/include/vcl/gdimetafiletools.hxx b/include/vcl/gdimetafiletools.hxx
index 592c70714bfd..ea47ced5032e 100644
--- a/include/vcl/gdimetafiletools.hxx
+++ b/include/vcl/gdimetafiletools.hxx
@@ -39,6 +39,15 @@ void VCL_DLLPUBLIC clipMetafileContentAgainstOwnRegions(GDIMetaFile& rSource);
 
 bool VCL_DLLPUBLIC usesClipActions(const GDIMetaFile& rSource);
 
+// hook to access metafile members in classes of modules above vcl. Currently
+// used in MetafilePrimitive2D to be able to access the local Metafile member
+// e.g. from vcl module
+class VCL_DLLPUBLIC MetafileAccessor
+{
+public:
+    virtual bool accessMetafile(GDIMetaFile& rTargetMetafile) const = 0;
+};
+
 
 #endif // INCLUDED_VCL_GDIMETAFILETOOLS_HXX
 
diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx
index 01b6e07f58d0..73adc2013e0b 100644
--- a/include/vcl/graphicfilter.hxx
+++ b/include/vcl/graphicfilter.hxx
@@ -33,7 +33,7 @@
 
 class FilterConfigCache;
 class SvStream;
-struct WMF_EXTERNALHEADER;
+struct WmfExternal;
 struct ConvertData;
 
 #define ERRCODE_GRFILTER_OPENERROR    (ERRCODE_AREA_VCL | ERRCODE_CLASS_GENERAL | 1)
@@ -281,7 +281,7 @@ public:
                                    SvStream& rStream,
                                    sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW,
                                    sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE,
-                                   WMF_EXTERNALHEADER *pExtHeader = nullptr );
+                                   WmfExternal *pExtHeader = nullptr );
 
     /// Imports multiple graphics.
     ///
@@ -293,7 +293,7 @@ public:
                                    sal_uInt16 nFormat,
                                    sal_uInt16 * pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
                                    css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
-                                   WMF_EXTERNALHEADER *pExtHeader = nullptr );
+                                   WmfExternal *pExtHeader = nullptr );
 
     const FilterErrorEx&    GetLastError() const { return *pErrorEx;}
     void                    ResetLastError();
diff --git a/include/vcl/vectorgraphicdata.hxx b/include/vcl/vectorgraphicdata.hxx
index 6a259a5567e3..a045b01ee46e 100644
--- a/include/vcl/vectorgraphicdata.hxx
+++ b/include/vcl/vectorgraphicdata.hxx
@@ -23,6 +23,7 @@
 #include <basegfx/range/b2drange.hxx>
 #include <com/sun/star/graphic/XPrimitive2D.hpp>
 #include <vcl/bitmapex.hxx>
+#include <vcl/wmfexternal.hxx>
 #include <rtl/ustring.hxx>
 #include <deque>
 
@@ -57,12 +58,14 @@ private:
 
     // on demand created content
     basegfx::B2DRange           maRange;
-    std::deque< css::uno::Reference< css::graphic::XPrimitive2D > >
-                                maSequence;
+    std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > maSequence;
     BitmapEx                    maReplacement;
     size_t                      mNestedBitmapSize;
     VectorGraphicDataType       meVectorGraphicDataType;
 
+    // extra:
+    WmfExternal*         mpExternalHeader;
+
     // on demand creators
     void ensureReplacement();
     void ensureSequenceAndRange();
@@ -78,10 +81,14 @@ public:
     VectorGraphicData(
         const OUString& rPath,
         VectorGraphicDataType eVectorDataType);
+    ~VectorGraphicData();
 
     /// compare op
     bool operator==(const VectorGraphicData& rCandidate) const;
 
+    /// special: needed for emf/wmf, maybe replaced by scaling the result later (?)
+    void setWmfExternalHeader(const WmfExternal& aExtHeader);
+
     /// data read
     const VectorGraphicDataArray& getVectorGraphicDataArray() const { return maVectorGraphicDataArray; }
     sal_uInt32 getVectorGraphicDataArrayLength() const { return maVectorGraphicDataArray.getLength(); }
diff --git a/include/vcl/wmf.hxx b/include/vcl/wmf.hxx
index 67d6aa4f122b..c172cd45e86b 100644
--- a/include/vcl/wmf.hxx
+++ b/include/vcl/wmf.hxx
@@ -25,38 +25,7 @@
 class FilterConfigItem;
 class GDIMetaFile;
 class SvStream;
-
-struct WMF_EXTERNALHEADER
-{
-    sal_uInt16 xExt;
-    sal_uInt16 yExt;
-
-    /** One of the following values:
-        <ul>
-            <li>MM_TEXT</li>
-            <li>MM_LOMETRIC</li>
-            <li>MM_HIMETRIC</li>
-            <li>MM_LOENGLISH</li>
-            <li>MM_HIENGLISH</li>
-            <li>MM_TWIPS</li>
-            <li>MM_ISOTROPIC</li>
-            <li>MM_ANISOTROPIC</li>
-        </ul>
-        If this value is 0, then no external mapmode has been defined,
-        the internal one should then be used.
-     */
-    sal_uInt16 mapMode;
-
-    WMF_EXTERNALHEADER() :
-        xExt( 0 ),
-        yExt( 0 ),
-        mapMode( 0 )
-    {
-    }
-};
-
-// for 1st test, export
-VCL_DLLPUBLIC bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem, WMF_EXTERNALHEADER *pExtHeader );
+struct WmfExternal;
 
 VCL_DLLPUBLIC bool ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF );
 
diff --git a/include/vcl/wmfexternal.hxx b/include/vcl/wmfexternal.hxx
new file mode 100644
index 000000000000..30c58ab0bcb0
--- /dev/null
+++ b/include/vcl/wmfexternal.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_WMFEXTERNAL_HXX
+#define INCLUDED_VCL_WMFEXTERNAL_HXX
+
+#include <vcl/dllapi.h>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+struct VCL_DLLPUBLIC WmfExternal
+{
+    sal_uInt16 xExt;
+    sal_uInt16 yExt;
+
+    /** One of the following values:
+        <ul>
+            <li>MM_TEXT</li>
+            <li>MM_LOMETRIC</li>
+            <li>MM_HIMETRIC</li>
+            <li>MM_LOENGLISH</li>
+            <li>MM_HIENGLISH</li>
+            <li>MM_TWIPS</li>
+            <li>MM_ISOTROPIC</li>
+            <li>MM_ANISOTROPIC</li>
+        </ul>
+        If this value is 0, then no external mapmode has been defined,
+        the internal one should then be used.
+     */
+    sal_uInt16 mapMode;
+
+    WmfExternal();
+    css::uno::Sequence< css::beans::PropertyValue > getSequence() const;
+    bool setSequence(const css::uno::Sequence< css::beans::PropertyValue >& rSequence);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/graphic/XEmfParser.idl b/offapi/com/sun/star/graphic/XEmfParser.idl
index 6c55a8a0b963..42cb2cbe6459 100644
--- a/offapi/com/sun/star/graphic/XEmfParser.idl
+++ b/offapi/com/sun/star/graphic/XEmfParser.idl
@@ -41,10 +41,14 @@ interface XEmfParser : ::com::sun::star::uno::XInterface
 
         @param aAbsolutePath
         The path containing the WMF/EMF/EMF+ data
-     */
+
+        @param Properties
+        Optional values to override MapMode and size
+*/
     sequence< XPrimitive2D > getDecomposition(
         [in] io::XInputStream xEmfStream,
-        [in] string aAbsolutePath);
+        [in] string aAbsolutePath,
+        [in] ::com::sun::star::beans::PropertyValues Properties);
 };
 
 }; }; }; };
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 7d04518b5f25..72927d116cd0 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1291,7 +1291,7 @@ OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rSe
             if( !aGraphicPath.isEmpty() )
             {
                 // Transfer shape's width and height to graphicsfilter (can be used by WMF/EMF)
-                WMF_EXTERNALHEADER aExtHeader;
+                WmfExternal aExtHeader;
                 aExtHeader.mapMode = 8; // MM_ANISOTROPIC
                 aExtHeader.xExt = rShapeRect.Width;
                 aExtHeader.yExt = rShapeRect.Height;
diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx
index 30c570b01eec..6c150729a589 100644
--- a/oox/source/helper/graphichelper.cxx
+++ b/oox/source/helper/graphichelper.cxx
@@ -234,7 +234,7 @@ awt::Size GraphicHelper::convertHmmToAppFont( const awt::Size& rHmm ) const
 // Graphics and graphic objects  ----------------------------------------------
 
 Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm,
-        const WMF_EXTERNALHEADER* pExtHeader ) const
+        const WmfExternal* pExtHeader ) const
 {
     Reference< XGraphic > xGraphic;
     if( rxInStrm.is() && mxGraphicProvider.is() ) try
@@ -331,7 +331,7 @@ void GraphicHelper::importEmbeddedGraphics(const std::vector<OUString>& rStreamN
     }
 }
 
-Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WMF_EXTERNALHEADER* pExtHeader ) const
+Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WmfExternal* pExtHeader ) const
 {
     Reference< XGraphic > xGraphic;
     OSL_ENSURE( !rStreamName.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" );
@@ -367,7 +367,7 @@ OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGrap
 }
 
 OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm,
-        const WMF_EXTERNALHEADER* pExtHeader ) const
+        const WmfExternal* pExtHeader ) const
 {
     return createGraphicObject( importGraphic( rxInStrm, pExtHeader ) );
 }
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 8d85b14701fb..c51afb75d40b 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -1141,7 +1141,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes
                 // set the replacement graphic
                 if( !aGraphicPath.isEmpty() )
                 {
-                    WMF_EXTERNALHEADER aExtHeader;
+                    WmfExternal aExtHeader;
                     aExtHeader.mapMode = 8;
                     aExtHeader.xExt = rShapeRect.Width;
                     aExtHeader.yExt = rShapeRect.Height;
diff --git a/svtools/source/graphic/provider.cxx b/svtools/source/graphic/provider.cxx
index 1bdcee7812a9..f837b0b9ef0a 100644
--- a/svtools/source/graphic/provider.cxx
+++ b/svtools/source/graphic/provider.cxx
@@ -413,11 +413,11 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co
             ::Graphic aVCLGraphic;
 
             // Define APM Header if goal height and width are defined
-            WMF_EXTERNALHEADER aExtHeader;
+            WmfExternal aExtHeader;
             aExtHeader.xExt = nExtWidth;
             aExtHeader.yExt = nExtHeight;
             aExtHeader.mapMode = nExtMapMode;
-            WMF_EXTERNALHEADER *pExtHeader = nullptr;
+            WmfExternal *pExtHeader = nullptr;
             if ( nExtMapMode > 0 )
                 pExtHeader = &aExtHeader;
 
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 9735c606a1a8..2ad89aced588 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -373,10 +373,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/source/filter/jpeg/JpegWriter \
     vcl/source/filter/jpeg/JpegTransform \
     vcl/source/filter/wmf/emfwr \
-    vcl/source/filter/wmf/enhwmf \
-    vcl/source/filter/wmf/winmtf \
-    vcl/source/filter/wmf/winwmf \
     vcl/source/filter/wmf/wmf \
+    vcl/source/filter/wmf/wmfexternal \
     vcl/source/filter/wmf/wmfwr \
     vcl/source/font/PhysicalFontCollection \
     vcl/source/font/PhysicalFontFace \
diff --git a/vcl/qa/cppunit/wmf/wmfimporttest.cxx b/vcl/qa/cppunit/wmf/wmfimporttest.cxx
index ca9900c18ad9..40ac1d5b02af 100644
--- a/vcl/qa/cppunit/wmf/wmfimporttest.cxx
+++ b/vcl/qa/cppunit/wmf/wmfimporttest.cxx
@@ -23,7 +23,6 @@
 #include <unotest/bootstrapfixturebase.hxx>
 #include <vcl/wmf.hxx>
 #include <vcl/metaact.hxx>
-#include <winmtf.hxx>
 
 using namespace css;
 
diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx
index 84314080e265..491d27645d68 100644
--- a/vcl/source/filter/graphicfilter.cxx
+++ b/vcl/source/filter/graphicfilter.cxx
@@ -1312,7 +1312,7 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rP
 }
 
 sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
-                                     sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, WMF_EXTERNALHEADER *pExtHeader )
+                                     sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, WmfExternal *pExtHeader )
 {
     return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader );
 }
@@ -1467,7 +1467,7 @@ void GraphicFilter::ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGra
 ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags,
                                      css::uno::Sequence< css::beans::PropertyValue >* pFilterData,
-                                     WMF_EXTERNALHEADER *pExtHeader )
+                                     WmfExternal *pExtHeader )
 {
     OUString                       aFilterName;
     OUString                       aExternalFilterName;
@@ -1771,52 +1771,46 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath,
         else if( aFilterName.equalsIgnoreAsciiCase( IMP_WMF ) ||
                 aFilterName.equalsIgnoreAsciiCase( IMP_EMF ) )
         {
-            static bool bCheckEmfWmf = true;
-            if (bCheckEmfWmf)
-            {
-                if (rGraphic.IsDummyContext())
-                    rGraphic.SetDummyContext(false);
+            // use new UNO API service, do not directly import but create a
+            // Graphic that contains the original data and decomposes to
+            // primitives on demand
+            if (rGraphic.IsDummyContext())
+                rGraphic.SetDummyContext(false);
 
-                const sal_uInt32 nStreamPosition(rIStream.Tell());
-                const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition);
-                VectorGraphicDataArray aNewData(nStreamLength);
-                bool bOkay(false);
+            const sal_uInt32 nStreamPosition(rIStream.Tell());
+            const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition);
+            VectorGraphicDataArray aNewData(nStreamLength);
+            bool bOkay(false);
 
-                rIStream.Seek(nStreamPosition);
-                rIStream.ReadBytes(aNewData.begin(), nStreamLength);
+            rIStream.Seek(nStreamPosition);
+            rIStream.ReadBytes(aNewData.begin(), nStreamLength);
 
-                if (!rIStream.GetError())
+            if (!rIStream.GetError())
+            {
+                const bool bIsWmf(aFilterName.equalsIgnoreAsciiCase(IMP_WMF));
+                const VectorGraphicDataType aDataType(bIsWmf ? VectorGraphicDataType::Wmf : VectorGraphicDataType::Emf);
+                VectorGraphicDataPtr aVectorGraphicDataPtr(
+                    new VectorGraphicData(
+                        aNewData,
+                        rPath,
+                        aDataType));
+
+                if (pExtHeader)
                 {
-                    const bool bIsWmf(aFilterName.equalsIgnoreAsciiCase(IMP_WMF));
-                    const VectorGraphicDataType aDataType(bIsWmf ? VectorGraphicDataType::Wmf : VectorGraphicDataType::Emf);
-                    VectorGraphicDataPtr aVectorGraphicDataPtr(
-                        new VectorGraphicData(
-                            aNewData,
-                            rPath,
-                            aDataType));
-                    rGraphic = Graphic(aVectorGraphicDataPtr);
-                    bOkay = true;
+                    aVectorGraphicDataPtr->setWmfExternalHeader(*pExtHeader);
                 }
 
-                if (bOkay)
-                {
-                    eLinkType = GfxLinkType::NativeWmf;
-                }
-                else
-                {
-                    nStatus = ERRCODE_GRFILTER_FILTERERROR;
-                }
+                rGraphic = Graphic(aVectorGraphicDataPtr);
+                bOkay = true;
+            }
+
+            if (bOkay)
+            {
+                eLinkType = GfxLinkType::NativeWmf;
             }
             else
             {
-                GDIMetaFile aMtf;
-                if (!ConvertWMFToGDIMetaFile(rIStream, aMtf, nullptr, pExtHeader))
-                    nStatus = ERRCODE_GRFILTER_FORMATERROR;
-                else
-                {
-                    rGraphic = aMtf;
-                    eLinkType = GfxLinkType::NativeWmf;
-                }
+                nStatus = ERRCODE_GRFILTER_FILTERERROR;
             }
         }
         else if( aFilterName.equalsIgnoreAsciiCase( IMP_SVSGF )
diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
deleted file mode 100644
index 22125d747dbe..000000000000
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ /dev/null
@@ -1,1966 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <osl/endian.h>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <vcl/dibtools.hxx>
-#include <o3tl/make_unique.hxx>
-
-#include "winmtf.hxx"
-
-#include <memory>
-
-#ifdef DBG_UTIL
-#include <tools/stream.hxx>
-#include <vcl/pngwrite.hxx>
-#endif
-
-using namespace std;
-
-// GDI-Array
-
-#define EMR_HEADER                      1
-#define EMR_POLYBEZIER                  2
-#define EMR_POLYGON                     3
-#define EMR_POLYLINE                    4
-#define EMR_POLYBEZIERTO                5
-#define EMR_POLYLINETO                  6
-#define EMR_POLYPOLYLINE                7
-#define EMR_POLYPOLYGON                 8
-#define EMR_SETWINDOWEXTEX              9
-#define EMR_SETWINDOWORGEX              10
-#define EMR_SETVIEWPORTEXTEX            11
-#define EMR_SETVIEWPORTORGEX            12
-#define EMR_SETBRUSHORGEX               13
-#define EMR_EOF                         14
-#define EMR_SETPIXELV                   15
-#define EMR_SETMAPPERFLAGS              16
-#define EMR_SETMAPMODE                  17
-#define EMR_SETBKMODE                   18
-#define EMR_SETPOLYFILLMODE             19
-#define EMR_SETROP2                     20
-#define EMR_SETSTRETCHBLTMODE           21
-#define EMR_SETTEXTALIGN                22
-#define EMR_SETCOLORADJUSTMENT          23
-#define EMR_SETTEXTCOLOR                24
-#define EMR_SETBKCOLOR                  25
-#define EMR_OFFSETCLIPRGN               26
-#define EMR_MOVETOEX                    27
-#define EMR_SETMETARGN                  28
-#define EMR_EXCLUDECLIPRECT             29
-#define EMR_INTERSECTCLIPRECT           30
-#define EMR_SCALEVIEWPORTEXTEX          31
-#define EMR_SCALEWINDOWEXTEX            32
-#define EMR_SAVEDC                      33
-#define EMR_RESTOREDC                   34
-#define EMR_SETWORLDTRANSFORM           35
-#define EMR_MODIFYWORLDTRANSFORM        36
-#define EMR_SELECTOBJECT                37
-#define EMR_CREATEPEN                   38
-#define EMR_CREATEBRUSHINDIRECT         39
-#define EMR_DELETEOBJECT                40
-#define EMR_ANGLEARC                    41
-#define EMR_ELLIPSE                     42
-#define EMR_RECTANGLE                   43
-#define EMR_ROUNDRECT                   44
-#define EMR_ARC                         45
-#define EMR_CHORD                       46
-#define EMR_PIE                         47
-#define EMR_SELECTPALETTE               48
-#define EMR_CREATEPALETTE               49
-#define EMR_SETPALETTEENTRIES           50
-#define EMR_RESIZEPALETTE               51
-#define EMR_REALIZEPALETTE              52
-#define EMR_EXTFLOODFILL                53
-#define EMR_LINETO                      54
-#define EMR_ARCTO                       55
-#define EMR_POLYDRAW                    56
-#define EMR_SETARCDIRECTION             57
-#define EMR_SETMITERLIMIT               58
-#define EMR_BEGINPATH                   59
-#define EMR_ENDPATH                     60
-#define EMR_CLOSEFIGURE                 61
-#define EMR_FILLPATH                    62
-#define EMR_STROKEANDFILLPATH           63
-#define EMR_STROKEPATH                  64
-#define EMR_FLATTENPATH                 65
-#define EMR_WIDENPATH                   66
-#define EMR_SELECTCLIPPATH              67
-#define EMR_ABORTPATH                   68
-
-#define EMR_COMMENT                     70          // Contains arbitrary private data.
-// Comment Identifiers:
-#define EMR_COMMENT_EMFPLUS             0x2B464D45  // Contains embedded EMF+ records.
-#define EMR_COMMENT_EMFSPOOL            0x00000000  // Contains embedded EMFSPOOL records.
-#define EMR_COMMENT_PUBLIC              0x43494447  // Specify extensions to EMF processing.
-
-#define EMR_FILLRGN                     71
-#define EMR_FRAMERGN                    72
-#define EMR_INVERTRGN                   73
-#define EMR_PAINTRGN                    74
-#define EMR_EXTSELECTCLIPRGN            75
-#define EMR_BITBLT                      76
-#define EMR_STRETCHBLT                  77
-#define EMR_MASKBLT                     78
-#define EMR_PLGBLT                      79
-#define EMR_SETDIBITSTODEVICE           80
-#define EMR_STRETCHDIBITS               81
-#define EMR_EXTCREATEFONTINDIRECTW      82
-#define EMR_EXTTEXTOUTA                 83
-#define EMR_EXTTEXTOUTW                 84
-#define EMR_POLYBEZIER16                85
-#define EMR_POLYGON16                   86
-#define EMR_POLYLINE16                  87
-#define EMR_POLYBEZIERTO16              88
-#define EMR_POLYLINETO16                89
-#define EMR_POLYPOLYLINE16              90
-#define EMR_POLYPOLYGON16               91
-#define EMR_POLYDRAW16                  92
-#define EMR_CREATEMONOBRUSH             93
-#define EMR_CREATEDIBPATTERNBRUSHPT     94
-#define EMR_EXTCREATEPEN                95
-#define EMR_POLYTEXTOUTA                96
-#define EMR_POLYTEXTOUTW                97
-
-// WINDOWS VERSION >= 0x400
-#define EMR_SETICMMODE                  98
-#define EMR_CREATECOLORSPACE            99
-#define EMR_SETCOLORSPACE              100
-#define EMR_DELETECOLORSPACE           101
-#define EMR_GLSRECORD                  102
-#define EMR_GLSBOUNDEDRECORD           103
-#define EMR_PIXELFORMAT                104
-
-// WINDOWS VERSION >= 0x500
-#define EMR_DRAWESCAPE                 105
-#define EMR_EXTESCAPE                  106
-#define EMR_STARTDOC                   107
-#define EMR_SMALLTEXTOUT               108
-#define EMR_FORCEUFIMAPPING            109
-#define EMR_NAMEDESCAPE                110
-#define EMR_COLORCORRECTPALETTE        111
-#define EMR_SETICMPROFILEA             112
-#define EMR_SETICMPROFILEW             113
-#define EMR_ALPHABLEND                 114
-#define EMR_ALPHADIBBLEND              115
-#define EMR_TRANSPARENTBLT             116
-#define EMR_TRANSPARENTDIB             117
-#define EMR_GRADIENTFILL               118
-#define EMR_SETLINKEDUFIS              119
-#define EMR_SETTEXTJUSTIFICATION       120
-
-namespace
-{
-
-const char *
-record_type_name(sal_uInt32 nRecType)
-{
-#ifndef SAL_LOG_INFO
-    (void) nRecType;
-    return "";
-#else
-    switch( nRecType )
-    {
-    case EMR_HEADER: return "HEADER";
-    case EMR_POLYBEZIER: return "POLYBEZIER";
-    case EMR_POLYGON: return "POLYGON";
-    case EMR_POLYLINE: return "POLYLINE";
-    case EMR_POLYBEZIERTO: return "POLYBEZIERTO";
-    case EMR_POLYLINETO: return "POLYLINETO";
-    case EMR_POLYPOLYLINE: return "POLYPOLYLINE";
-    case EMR_POLYPOLYGON: return "POLYPOLYGON";
-    case EMR_SETWINDOWEXTEX: return "SETWINDOWEXTEX";
-    case EMR_SETWINDOWORGEX: return "SETWINDOWORGEX";
-    case EMR_SETVIEWPORTEXTEX: return "SETVIEWPORTEXTEX";
-    case EMR_SETVIEWPORTORGEX: return "SETVIEWPORTORGEX";
-    case EMR_SETBRUSHORGEX: return "SETBRUSHORGEX";
-    case EMR_EOF: return "EOF";
-    case EMR_SETPIXELV: return "SETPIXELV";
-    case EMR_SETMAPPERFLAGS: return "SETMAPPERFLAGS";
-    case EMR_SETMAPMODE: return "SETMAPMODE";
-    case EMR_SETBKMODE: return "SETBKMODE";
-    case EMR_SETPOLYFILLMODE: return "SETPOLYFILLMODE";
-    case EMR_SETROP2: return "SETROP2";
-    case EMR_SETSTRETCHBLTMODE: return "SETSTRETCHBLTMODE";
-    case EMR_SETTEXTALIGN: return "SETTEXTALIGN";
-    case EMR_SETCOLORADJUSTMENT: return "SETCOLORADJUSTMENT";
-    case EMR_SETTEXTCOLOR: return "SETTEXTCOLOR";
-    case EMR_SETBKCOLOR: return "SETBKCOLOR";
-    case EMR_OFFSETCLIPRGN: return "OFFSETCLIPRGN";
-    case EMR_MOVETOEX: return "MOVETOEX";
-    case EMR_SETMETARGN: return "SETMETARGN";
-    case EMR_EXCLUDECLIPRECT: return "EXCLUDECLIPRECT";
-    case EMR_INTERSECTCLIPRECT: return "INTERSECTCLIPRECT";
-    case EMR_SCALEVIEWPORTEXTEX: return "SCALEVIEWPORTEXTEX";
-    case EMR_SCALEWINDOWEXTEX: return "SCALEWINDOWEXTEX";
-    case EMR_SAVEDC: return "SAVEDC";
-    case EMR_RESTOREDC: return "RESTOREDC";
-    case EMR_SETWORLDTRANSFORM: return "SETWORLDTRANSFORM";
-    case EMR_MODIFYWORLDTRANSFORM: return "MODIFYWORLDTRANSFORM";
-    case EMR_SELECTOBJECT: return "SELECTOBJECT";
-    case EMR_CREATEPEN: return "CREATEPEN";
-    case EMR_CREATEBRUSHINDIRECT: return "CREATEBRUSHINDIRECT";
-    case EMR_DELETEOBJECT: return "DELETEOBJECT";
-    case EMR_ANGLEARC: return "ANGLEARC";
-    case EMR_ELLIPSE: return "ELLIPSE";
-    case EMR_RECTANGLE: return "RECTANGLE";
-    case EMR_ROUNDRECT: return "ROUNDRECT";
-    case EMR_ARC: return "ARC";
-    case EMR_CHORD: return "CHORD";
-    case EMR_PIE: return "PIE";
-    case EMR_SELECTPALETTE: return "SELECTPALETTE";
-    case EMR_CREATEPALETTE: return "CREATEPALETTE";
-    case EMR_SETPALETTEENTRIES: return "SETPALETTEENTRIES";
-    case EMR_RESIZEPALETTE: return "RESIZEPALETTE";
-    case EMR_REALIZEPALETTE: return "REALIZEPALETTE";
-    case EMR_EXTFLOODFILL: return "EXTFLOODFILL";
-    case EMR_LINETO: return "LINETO";
-    case EMR_ARCTO: return "ARCTO";
-    case EMR_POLYDRAW: return "POLYDRAW";
-    case EMR_SETARCDIRECTION: return "SETARCDIRECTION";
-    case EMR_SETMITERLIMIT: return "SETMITERLIMIT";
-    case EMR_BEGINPATH: return "BEGINPATH";
-    case EMR_ENDPATH: return "ENDPATH";
-    case EMR_CLOSEFIGURE: return "CLOSEFIGURE";
-    case EMR_FILLPATH: return "FILLPATH";
-    case EMR_STROKEANDFILLPATH: return "STROKEANDFILLPATH";
-    case EMR_STROKEPATH: return "STROKEPATH";
-    case EMR_FLATTENPATH: return "FLATTENPATH";
-    case EMR_WIDENPATH: return "WIDENPATH";
-    case EMR_SELECTCLIPPATH: return "SELECTCLIPPATH";
-    case EMR_ABORTPATH: return "ABORTPATH";
-    case EMR_COMMENT: return "COMMENT";
-    case EMR_FILLRGN: return "FILLRGN";
-    case EMR_FRAMERGN: return "FRAMERGN";
-    case EMR_INVERTRGN: return "INVERTRGN";
-    case EMR_PAINTRGN: return "PAINTRGN";
-    case EMR_EXTSELECTCLIPRGN: return "EXTSELECTCLIPRGN";
-    case EMR_BITBLT: return "BITBLT";
-    case EMR_STRETCHBLT: return "STRETCHBLT";
-    case EMR_MASKBLT: return "MASKBLT";
-    case EMR_PLGBLT: return "PLGBLT";
-    case EMR_SETDIBITSTODEVICE: return "SETDIBITSTODEVICE";
-    case EMR_STRETCHDIBITS: return "STRETCHDIBITS";
-    case EMR_EXTCREATEFONTINDIRECTW: return "EXTCREATEFONTINDIRECTW";
-    case EMR_EXTTEXTOUTA: return "EXTTEXTOUTA";
-    case EMR_EXTTEXTOUTW: return "EXTTEXTOUTW";
-    case EMR_POLYBEZIER16: return "POLYBEZIER16";
-    case EMR_POLYGON16: return "POLYGON16";
-    case EMR_POLYLINE16: return "POLYLINE16";
-    case EMR_POLYBEZIERTO16: return "POLYBEZIERTO16";
-    case EMR_POLYLINETO16: return "POLYLINETO16";
-    case EMR_POLYPOLYLINE16: return "POLYPOLYLINE16";
-    case EMR_POLYPOLYGON16: return "POLYPOLYGON16";
-    case EMR_POLYDRAW16: return "POLYDRAW16";
-    case EMR_CREATEMONOBRUSH: return "CREATEMONOBRUSH";
-    case EMR_CREATEDIBPATTERNBRUSHPT: return "CREATEDIBPATTERNBRUSHPT";
-    case EMR_EXTCREATEPEN: return "EXTCREATEPEN";
-    case EMR_POLYTEXTOUTA: return "POLYTEXTOUTA";
-    case EMR_POLYTEXTOUTW: return "POLYTEXTOUTW";
-    case EMR_SETICMMODE: return "SETICMMODE";
-    case EMR_CREATECOLORSPACE: return "CREATECOLORSPACE";
-    case EMR_SETCOLORSPACE: return "SETCOLORSPACE";
-    case EMR_DELETECOLORSPACE: return "DELETECOLORSPACE";
-    case EMR_GLSRECORD: return "GLSRECORD";
-    case EMR_GLSBOUNDEDRECORD: return "GLSBOUNDEDRECORD";
-    case EMR_PIXELFORMAT: return "PIXELFORMAT";
-    case EMR_DRAWESCAPE: return "DRAWESCAPE";
-    case EMR_EXTESCAPE: return "EXTESCAPE";
-    case EMR_STARTDOC: return "STARTDOC";
-    case EMR_SMALLTEXTOUT: return "SMALLTEXTOUT";
-    case EMR_FORCEUFIMAPPING: return "FORCEUFIMAPPING";
-    case EMR_NAMEDESCAPE: return "NAMEDESCAPE";
-    case EMR_COLORCORRECTPALETTE: return "COLORCORRECTPALETTE";
-    case EMR_SETICMPROFILEA: return "SETICMPROFILEA";
-    case EMR_SETICMPROFILEW: return "SETICMPROFILEW";
-    case EMR_ALPHABLEND: return "ALPHABLEND";
-    case EMR_ALPHADIBBLEND: return "ALPHADIBBLEND";
-    case EMR_TRANSPARENTBLT: return "TRANSPARENTBLT";
-    case EMR_TRANSPARENTDIB: return "TRANSPARENTDIB";
-    case EMR_GRADIENTFILL: return "GRADIENTFILL";
-    case EMR_SETLINKEDUFIS: return "SETLINKEDUFIS";
-    case EMR_SETTEXTJUSTIFICATION: return "SETTEXTJUSTIFICATION";
-    default:
-        // Yes, return a pointer to a static buffer. This is a very
-        // local debugging output function, so no big deal.
-        static char buffer[11];
-        sprintf(buffer, "0x%08" SAL_PRIxUINT32, nRecType);
-        return buffer;
-    }
-#endif
-}
-
-#ifdef OSL_BIGENDIAN
-// little endian <-> big endian switch
-static float GetSwapFloat(SvStream& rStream)
-{
-    float fTmp;
-    sal_Int8* pPtr = (sal_Int8*)&fTmp;
-    rStream.ReadSChar(pPtr[3]);
-    rStream.ReadSChar(pPtr[2]);
-    rStream.ReadSChar(pPtr[1]);
-    rStream.ReadSChar(pPtr[0]);
-    return fTmp;
-}
-#endif
-
-struct BLENDFUNCTION
-{
-    unsigned char aBlendOperation;
-    unsigned char aBlendFlags;
-    unsigned char aSrcConstantAlpha;
-    unsigned char aAlphaFormat;
-
-    friend SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun);
-};
-
-SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun)
-{
-    rInStream.ReadUChar(rBlendFun.aBlendOperation);
-    rInStream.ReadUChar(rBlendFun.aBlendFlags);
-    rInStream.ReadUChar(rBlendFun.aSrcConstantAlpha);
-    rInStream.ReadUChar(rBlendFun.aAlphaFormat);
-    return rInStream;
-}
-
-SvStream& operator>>(SvStream& rInStream, XForm& rXForm)
-{
-    if (sizeof(float) != 4)
-    {
-        OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
-        rXForm = XForm();
-    }
-    else
-    {
-#ifdef OSL_BIGENDIAN
-    rXForm.eM11 = GetSwapFloat(rInStream);
-    rXForm.eM12 = GetSwapFloat(rInStream);
-    rXForm.eM21 = GetSwapFloat(rInStream);
-    rXForm.eM22 = GetSwapFloat(rInStream);
-    rXForm.eDx = GetSwapFloat(rInStream);
-    rXForm.eDy = GetSwapFloat(rInStream);
-#else
-    rInStream.ReadFloat(rXForm.eM11);
-    rInStream.ReadFloat(rXForm.eM12);
-    rInStream.ReadFloat(rXForm.eM21);
-    rInStream.ReadFloat(rXForm.eM22);
-    rInStream.ReadFloat(rXForm.eDx);
-    rInStream.ReadFloat(rXForm.eDy);
-#endif
-    }
-    return rInStream;
-}
-
-bool ImplReadRegion( tools::PolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen )
-{
-    if (nLen == 0)
-        return false;
-
-    sal_uInt32 nHdSize, nType, nCount, nRgnSize, i;
-    rStream.ReadUInt32(nHdSize);
-    rStream.ReadUInt32(nType);
-    rStream.ReadUInt32(nCount);
-    rStream.ReadUInt32(nRgnSize);
-
-    if (   nCount > 0
-        && nType == RDH_RECTANGLES
-        && nLen >= ((nCount << 4) + (nHdSize - 16)))
-    {
-        sal_Int32 nx1, ny1, nx2, ny2;
-
-        for (i = 0; i < nCount; i++)
-        {
-            rStream.ReadInt32(nx1);
-            rStream.ReadInt32(ny1);
-            rStream.ReadInt32(nx2);
-            rStream.ReadInt32(ny2);
-
-            tools::Rectangle aRectangle(Point(nx1, ny1), Point(nx2, ny2));
-
-            tools::Polygon aPolygon(aRectangle);
-            tools::PolyPolygon aPolyPolyOr1(aPolygon);
-            tools::PolyPolygon aPolyPolyOr2(rPolyPoly);
-            rPolyPoly.GetUnion(aPolyPolyOr1, aPolyPolyOr2);
-            rPolyPoly = aPolyPolyOr2;
-        }
-        return true;
-    }
-    return false;
-}
-
-} // anonymous namespace
-
-EnhWMFReader::EnhWMFReader(SvStream& rStream,GDIMetaFile& rGDIMetaFile,FilterConfigItem* pConfigItem)
-    : WinMtf(rGDIMetaFile, rStream , pConfigItem)
-    , bRecordPath(false)
-    , nRecordCount(0)
-    , bEMFPlus(false)
-{}
-
-EnhWMFReader::~EnhWMFReader()
-{}
-
-void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC)
-{
-    if (!bEMFPlus) {
-        pOut->PassEMFPlusHeaderInfo();
-
-#if OSL_DEBUG_LEVEL > 1
-        // debug code - write the stream to debug file /tmp/emf-stream.emf
-        sal_uInt64 const pos = pWMF->Tell();
-        pWMF->Seek(0);
-        SvFileStream file( OUString( "/tmp/emf-stream.emf" ), StreamMode::WRITE | StreamMode::TRUNC );
-
-        pWMF->WriteStream(file);
-        file.Flush();
-        file.Close();
-
-        pWMF->Seek( pos );
-#endif
-
-    }
-    bEMFPlus = true;
-
-    sal_uInt64 const pos = pWMF->Tell();
-    void *buffer = malloc( length );
-    pOut->PassEMFPlus( buffer, pWMF->ReadBytes(buffer, length) );
-    free( buffer );
-    pWMF->Seek( pos );
-
-    bHaveDC = false;
-
-    // skip in SeekRel if impossibly unavailable
-    sal_uInt32 nRemainder = length;
-
-    const size_t nRequiredHeaderSize = 12;
-    while (nRemainder >= nRequiredHeaderSize)
-    {
-        sal_uInt16 type(0), flags(0);
-        sal_uInt32 size(0), dataSize(0);
-
-        pWMF->ReadUInt16( type ).ReadUInt16( flags ).ReadUInt32( size ).ReadUInt32( dataSize );
-        nRemainder -= nRequiredHeaderSize;
-
-        SAL_INFO ("vcl.emf", "\t\tEMF+ record type: " << std::hex << type << std::dec);
-
-        // Get Device Context
-        // TODO We should use  EmfPlusRecordType::GetDC instead
-        if( type == 0x4004 )
-        {
-            bHaveDC = true;
-            SAL_INFO ("vcl.emf", "\t\tEMF+ lock DC (device context)");
-        }
-
-        // Get the length of the remaining data of this record based
-        // on the alleged size
-        sal_uInt32 nRemainingRecordData = size >= nRequiredHeaderSize ?
-            size-nRequiredHeaderSize : 0;
-        // clip to available size
-        nRemainingRecordData = std::min(nRemainingRecordData, nRemainder);
-        pWMF->SeekRel(nRemainingRecordData);
-        nRemainder -= nRemainingRecordData;
-    }
-    pWMF->SeekRel(nRemainder);
-}
-
-/**
- * Reads polygons from the stream.
- * The \<class T> parameter is for the type of the points (sal_uInt32 or sal_uInt16).
- * The \<class Drawer> parameter is a c++11 lambda for the method that will draw the polygon.
- * skipFirst: if the first point read is the 0th point or the 1st point in the array.
- * */
-template <class T, class Drawer>
-void EnhWMFReader::ReadAndDrawPolygon(Drawer drawer, const bool skipFirst)
-{
-    sal_uInt32 nPoints(0), nStartIndex(0);
-    pWMF->SeekRel( 16 );
-    pWMF->ReadUInt32( nPoints );
-    if (skipFirst)
-    {
-        nPoints ++;
-        nStartIndex ++;
-    }
-
-    tools::Polygon aPolygon = ReadPolygon<T>(nStartIndex, nPoints);
-    drawer(pOut, aPolygon, skipFirst, bRecordPath);
-}
-
-/**
- * Reads polygons from the stream.
- * The \<class T> parameter is for the type of the points
- * nStartIndex: which is the starting index in the polygon of the first point read
- * nPoints: number of points
- * pWMF: the stream containing the polygons
- * */
-template <class T>
-tools::Polygon EnhWMFReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints)
-{
-    bool bRecordOk = nPoints <= SAL_MAX_UINT16;
-    SAL_WARN_IF(!bRecordOk, "vcl.emf", "polygon record has more polygons than we can handle");
-    if (!bRecordOk)
-        return tools::Polygon();
-
-    tools::Polygon aPolygon(nPoints);
-    for (sal_uInt32 i = nStartIndex ; i < nPoints && pWMF->good(); i++ )
-    {
-        T nX, nY;
-        *pWMF >> nX >> nY;
-        if (!pWMF->good())
-        {
-            SAL_WARN("vcl.emf", "short read on polygon, truncating");
-            aPolygon.SetSize(i);
-            break;
-        }
-        aPolygon[ i ] = Point( nX, nY );
-    }
-
-    return aPolygon;
-}
-
-/**
- * Reads a polyline from the WMF file and draws it
- * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
- * */
-template <class T>
-void EnhWMFReader::ReadAndDrawPolyLine()
-{
-    sal_uInt32  nPoints;
-    sal_uInt32  i, nNumberOfPolylines( 0 ), nCount( 0 );
-    pWMF->SeekRel( 0x10 ); // TODO Skipping Bounds. A 128-bit WMF RectL object (specifies the bounding rectangle in device units.)
-    pWMF->ReadUInt32( nNumberOfPolylines );
-    pWMF->ReadUInt32( nCount ); // total number of points in all polylines
-    if (pWMF->Tell() >= nEndPos)
-        return;
-
-    // taking the amount of points of each polygon, retrieving the total number of points
-    if ( pWMF->good() &&
-         ( nNumberOfPolylines < SAL_MAX_UINT32 / sizeof( sal_uInt16 ) ) &&
-         ( nNumberOfPolylines * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() )
-       )
-    {
-        std::unique_ptr< sal_uInt32[] > pnPolylinePointCount( new sal_uInt32[ nNumberOfPolylines ] );
-        for ( i = 0; i < nNumberOfPolylines && pWMF->good(); i++ )
-        {
-            pWMF->ReadUInt32( nPoints );
-            pnPolylinePointCount[ i ] = nPoints;
-        }
-        // Get polyline points:
-        for ( i = 0; ( i < nNumberOfPolylines ) && pWMF->good(); i++ )
-        {
-            tools::Polygon aPolygon = ReadPolygon< T >( 0, pnPolylinePointCount[ i ] );
-            pOut->DrawPolyLine( aPolygon, false, bRecordPath );
-        }
-    }
-}
-
-// these are referenced from inside the templates
-
-SvStream& operator>>(SvStream& rStream, sal_Int16 &n)
-{
-    return rStream.ReadInt16(n);
-}
-
-SvStream& operator>>(SvStream& rStream, sal_Int32 &n)
-{
-    return rStream.ReadInt32(n);
-}
-
-/**
- * Reads a poly polygon from the WMF file and draws it.
- * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32)
- * */
-template <class T>
-void EnhWMFReader::ReadAndDrawPolyPolygon()
-{
-    sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0);
-    pWMF->SeekRel( 0x10 );
-    // Number of polygons
-    pWMF->ReadUInt32( nPoly ).ReadUInt32( nGesPoints );
-    if (pWMF->Tell() >= nEndPos)
-        return;
-    if (!pWMF->good())
-        return;
-    //check against numeric overflowing
-    if (nGesPoints >= SAL_MAX_UINT32 / sizeof(Point))
-        return;
-    if (nPoly >= SAL_MAX_UINT32 / sizeof(sal_uInt16))
-        return;
-    if (nPoly * sizeof(sal_uInt16) > nEndPos - pWMF->Tell())
-        return;
-
-    // Get number of points in each polygon
-    std::vector<sal_uInt16> aPoints(nPoly);
-    for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i)
-    {
-        sal_uInt32 nPoints(0);
-        pWMF->ReadUInt32( nPoints );
-        aPoints[i] = (sal_uInt16)nPoints;
-    }
-    if ( pWMF->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - pWMF->Tell() ) )
-    {
-        // Get polygon points
-        tools::PolyPolygon aPolyPoly(nPoly, nPoly);
-        for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i)
-        {
-            const sal_uInt16 nPointCount(aPoints[i]);
-            std::vector<Point> aPtAry(nPointCount);
-            for (sal_uInt16 j = 0; j < nPointCount && pWMF->good(); ++j)
-            {
-                T nX(0), nY(0);
-                *pWMF >> nX >> nY;
-                aPtAry[j] = Point( nX, nY );
-                ++nReadPoints;
-            }
-
-            aPolyPoly.Insert(tools::Polygon(aPtAry.size(), aPtAry.data()));
-        }
-
-        pOut->DrawPolyPolygon(aPolyPoly, bRecordPath);
-    }
-
-    OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)");
-}
-
-bool EnhWMFReader::ReadEnhWMF()
-{
-    sal_uInt32  nStretchBltMode = 0;
-    sal_uInt32  nNextPos(0),
-                nW(0), nH(0), nColor(0), nIndex(0),
-                nDat32(0), nNom1(0), nDen1(0), nNom2(0), nDen2(0);
-    sal_Int32   nX32(0), nY32(0), nx32(0), ny32(0);
-
-    bool    bStatus = ReadHeader();
-    bool    bHaveDC = false;
-
-    static bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == nullptr );
-
-    while( bStatus && nRecordCount-- && pWMF->good())
-    {
-        sal_uInt32  nRecType(0), nRecSize(0);
-        pWMF->ReadUInt32(nRecType).ReadUInt32(nRecSize);
-
-        if ( !pWMF->good() || ( nRecSize < 8 ) || ( nRecSize & 3 ) )     // Parameters are always divisible by 4
-        {
-            bStatus = false;
-            break;
-        }
-
-        auto nCurPos = pWMF->Tell();
-
-        if (nEndPos < nCurPos - 8)
-        {
-            bStatus = false;
-            break;
-        }
-
-        const sal_uInt32 nMaxPossibleRecSize = nEndPos - (nCurPos - 8);
-        if (nRecSize > nMaxPossibleRecSize)
-        {
-            bStatus = false;
-            break;
-        }
-
-        nNextPos = nCurPos + (nRecSize - 8);
-
-        if(  !aBmpSaveList.empty()
-          && ( nRecType != EMR_STRETCHBLT )
-          && ( nRecType != EMR_STRETCHDIBITS )
-          ) {
-            pOut->ResolveBitmapActions( aBmpSaveList );
-        }
-
-        bool bFlag = false;
-
-        SAL_INFO ("vcl.emf", "0x" << std::hex << (nNextPos - nRecSize) <<  "-0x" << nNextPos << " " << record_type_name(nRecType) << " size: " <<  nRecSize << std::dec);
-
-        if( bEnableEMFPlus && nRecType == EMR_COMMENT ) {
-            sal_uInt32 length;
-
-            pWMF->ReadUInt32( length );
-
-            SAL_INFO("vcl.emf", "\tGDI comment, length: " << length);
-
-            if( pWMF->good() && length >= 4 && length <= pWMF->remainingSize() ) {
-                sal_uInt32 nCommentId;
-
-                pWMF->ReadUInt32( nCommentId );
-
-                SAL_INFO ("vcl.emf", "\t\tbegin " << (char)(nCommentId & 0xff) << (char)((nCommentId & 0xff00) >> 8) << (char)((nCommentId & 0xff0000) >> 16) << (char)((nCommentId & 0xff000000) >> 24) << " id: 0x" << std::hex << nCommentId << std::dec);
-
-                if( nCommentId == EMR_COMMENT_EMFPLUS && nRecSize >= 12 )
-                {
-                    // [MS-EMF] 2.3.3: DataSize includes both CommentIdentifier and CommentRecordParm fields.
-                    // We have already read 4-byte CommentIdentifier, so reduce length appropriately
-                    ReadEMFPlusComment( length-4, bHaveDC );
-                }
-                else if( nCommentId == EMR_COMMENT_PUBLIC && nRecSize >= 12 )
-                {
-                    // TODO: ReadGDIComment()
-                }
-                else if( nCommentId == EMR_COMMENT_EMFSPOOL && nRecSize >= 12 )
-                {
-                    // TODO Implement reading EMFSPOOL comment
-
-                }
-                else
-                {
-                    SAL_INFO ("vcl.emf", "\t\tunknown id: 0x" << std::hex << nCommentId << std::dec);
-                }
-            }
-        }
-        else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
-        {
-            switch( nRecType )
-            {
-                case EMR_POLYBEZIERTO :
-                    ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
-                                                   { pWinMtfOutput->DrawPolyBezier( rPolygon, aTo, aRecordPath ); }, true );
-                break;
-                case EMR_POLYBEZIER :
-                    ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
-                                                   { pWinMtfOutput->DrawPolyBezier( rPolygon, aTo, aRecordPath ); }, false );
-                break;
-
-                case EMR_POLYGON :
-                    ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool /*aTo*/, bool aRecordPath )
-                                                   { pWinMtfOutput->DrawPolygon( rPolygon, aRecordPath ); }, false );
-                break;
-
-                case EMR_POLYLINETO :
-                    ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
-                                                   { pWinMtfOutput->DrawPolyLine( rPolygon, aTo, aRecordPath ); }, true );
-                break;
-
-                case EMR_POLYLINE :
-                    ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath )
-                                                   { pWinMtfOutput->DrawPolyLine( rPolygon, aTo, aRecordPath ); }, false );
-                break;
-
-                case EMR_POLYPOLYLINE :
-                    ReadAndDrawPolyLine<sal_Int32>();
-                break;
-
-                case EMR_POLYPOLYGON :
-                    ReadAndDrawPolyPolygon<sal_Int32>();
-                break;
-
-                case EMR_SETWINDOWEXTEX :
-                {
-                    pWMF->ReadUInt32( nW ).ReadUInt32( nH );
-                    pOut->SetWinExt( Size( nW, nH ), true);
-                }
-                break;
-
-                case EMR_SETWINDOWORGEX :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
-                    pOut->SetWinOrg( Point( nX32, nY32 ), true);
-                }
-                break;
-
-                case EMR_SCALEWINDOWEXTEX :
-                {
-                    pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
-                    pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
-                }
-                break;
-
-                case EMR_SETVIEWPORTORGEX :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
-                    pOut->SetDevOrg( Point( nX32, nY32 ) );
-                }
-                break;
-
-                case EMR_SCALEVIEWPORTEXTEX :
-                {
-                    pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 );
-                    pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
-                }
-                break;
-
-                case EMR_SETVIEWPORTEXTEX :
-                {
-                    pWMF->ReadUInt32( nW ).ReadUInt32( nH );
-                    pOut->SetDevExt( Size( nW, nH ) );
-                }
-                break;
-
-                case EMR_EOF :
-                    nRecordCount = 0;
-                break;
-
-                case EMR_SETPIXELV :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
-                    pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() );
-                }
-                break;
-
-                case EMR_SETMAPMODE :
-                {
-                    sal_uInt32 nMapMode;
-                    pWMF->ReadUInt32( nMapMode );
-                    pOut->SetMapMode( nMapMode );
-                }
-                break;
-
-                case EMR_SETBKMODE :
-                {
-                    pWMF->ReadUInt32( nDat32 );
-                    pOut->SetBkMode( static_cast<BkMode>(nDat32) );
-                }
-                break;
-
-                case EMR_SETPOLYFILLMODE :
-                break;
-
-                case EMR_SETROP2 :
-                {
-                    pWMF->ReadUInt32( nDat32 );
-                    pOut->SetRasterOp( (WMFRasterOp)nDat32 );
-                }
-                break;
-
-                case EMR_SETSTRETCHBLTMODE :
-                {
-                    pWMF->ReadUInt32( nStretchBltMode );
-                }
-                break;
-
-                case EMR_SETTEXTALIGN :
-                {
-                    pWMF->ReadUInt32( nDat32 );
-                    pOut->SetTextAlign( nDat32 );
-                }
-                break;
-
-                case EMR_SETTEXTCOLOR :
-                {
-                    pOut->SetTextColor( ReadColor() );
-                }
-                break;
-
-                case EMR_SETBKCOLOR :
-                {
-                    pOut->SetBkColor( ReadColor() );
-                }
-                break;
-
-                case EMR_OFFSETCLIPRGN :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
-                    pOut->MoveClipRegion( Size( nX32, nY32 ) );
-                }
-                break;
-
-                case EMR_MOVETOEX :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
-                    pOut->MoveTo( Point( nX32, nY32 ), bRecordPath );
-                }
-                break;
-
-                case EMR_INTERSECTCLIPRECT :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
-                    pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
-                }
-                break;
-
-                case EMR_SAVEDC :
-                {
-                    pOut->Push();
-                }
-                break;
-
-                case EMR_RESTOREDC :
-                {
-                    pOut->Pop();
-                }
-                break;
-
-                case EMR_SETWORLDTRANSFORM :
-                {
-                    XForm aTempXForm;
-                    *pWMF >> aTempXForm;
-                    pOut->SetWorldTransform( aTempXForm );
-                }
-                break;
-
-                case EMR_MODIFYWORLDTRANSFORM :
-                {
-                    sal_uInt32  nMode;
-                    XForm   aTempXForm;
-                    *pWMF >> aTempXForm;
-                    pWMF->ReadUInt32( nMode );
-                    pOut->ModifyWorldTransform( aTempXForm, nMode );
-                }
-                break;
-
-                case EMR_SELECTOBJECT :
-                {
-                    pWMF->ReadUInt32( nIndex );
-                    pOut->SelectObject( nIndex );
-                }
-                break;
-
-                case EMR_CREATEPEN :
-                {
-                    pWMF->ReadUInt32( nIndex );
-                    if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
-                    {
-
-                        LineInfo    aLineInfo;
-                        sal_uInt32      nStyle;
-                        Size        aSize;
-                        // #fdo39428 Remove SvStream operator>>(long&)
-                        sal_Int32 nTmpW(0), nTmpH(0);
-
-                        pWMF->ReadUInt32( nStyle ).ReadInt32( nTmpW ).ReadInt32( nTmpH );
-                        aSize.Width() = nTmpW;
-                        aSize.Height() = nTmpH;
-
-                        if ( aSize.Width() )
-                            aLineInfo.SetWidth( aSize.Width() );
-
-                        bool bTransparent = false;
-                        switch( nStyle & PS_STYLE_MASK )
-                        {
-                            case PS_DASHDOTDOT :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 1 );
-                                aLineInfo.SetDotCount( 2 );
-                            break;
-                            case PS_DASHDOT :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 1 );
-                                aLineInfo.SetDotCount( 1 );
-                            break;
-                            case PS_DOT :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 0 );
-                                aLineInfo.SetDotCount( 1 );
-                            break;
-                            case PS_DASH :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 1 );
-                                aLineInfo.SetDotCount( 0 );
-                            break;
-                            case PS_NULL :
-                                bTransparent = true;
-                                aLineInfo.SetStyle( LineStyle::NONE );
-                            break;
-                            case PS_INSIDEFRAME :
-                            case PS_SOLID :
-                            default :
-                                aLineInfo.SetStyle( LineStyle::Solid );
-                        }
-                        switch( nStyle & PS_ENDCAP_STYLE_MASK )
-                        {
-                            case PS_ENDCAP_ROUND :
-                                if ( aSize.Width() )
-                                {
-                                    aLineInfo.SetLineCap( css::drawing::LineCap_ROUND );
-                                    break;
-                                }
-                                SAL_FALLTHROUGH;
-                            case PS_ENDCAP_SQUARE :
-                                if ( aSize.Width() )
-                                {
-                                    aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE );
-                                    break;
-                                }
-                                SAL_FALLTHROUGH;
-                            case PS_ENDCAP_FLAT :
-                            default :
-                                aLineInfo.SetLineCap( css::drawing::LineCap_BUTT );
-                        }
-                        switch( nStyle & PS_JOIN_STYLE_MASK )
-                        {
-                            case PS_JOIN_ROUND :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round );
-                            break;
-                            case PS_JOIN_MITER :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter );
-                            break;
-                            case PS_JOIN_BEVEL :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel );
-                            break;
-                            default :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE );
-                        }
-                        pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfLineStyle>( ReadColor(), aLineInfo, bTransparent ));
-                    }
-                }
-                break;
-
-                case EMR_EXTCREATEPEN :
-                {
-                    sal_Int32   elpHatch;
-                    sal_uInt32  offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries;
-                    Color       aColorRef;
-
-                    pWMF->ReadUInt32( nIndex );
-                    if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
-                    {
-                        pWMF->ReadUInt32( offBmi ).ReadUInt32( cbBmi ).ReadUInt32( offBits ).ReadUInt32( cbBits ). ReadUInt32( nStyle ).ReadUInt32( nWidth ).ReadUInt32( nBrushStyle );
-                         aColorRef = ReadColor();
-                         pWMF->ReadInt32( elpHatch ).ReadUInt32( elpNumEntries );
-
-                        LineInfo    aLineInfo;
-                        if ( nWidth )
-                            aLineInfo.SetWidth( nWidth );
-
-                        bool bTransparent = false;
-
-                        switch( nStyle & PS_STYLE_MASK )
-                        {
-                            case PS_DASHDOTDOT :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 1 );
-                                aLineInfo.SetDotCount( 2 );
-                            break;
-                            case PS_DASHDOT :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 1 );
-                                aLineInfo.SetDotCount( 1 );
-                            break;
-                            case PS_DOT :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 0 );
-                                aLineInfo.SetDotCount( 1 );
-                            break;
-                            case PS_DASH :
-                                aLineInfo.SetStyle( LineStyle::Dash );
-                                aLineInfo.SetDashCount( 1 );
-                                aLineInfo.SetDotCount( 0 );
-                            break;
-                            case PS_NULL :
-                                bTransparent = true;
-                                aLineInfo.SetStyle( LineStyle::NONE );
-                            break;
-
-                            case PS_INSIDEFRAME :
-                            case PS_SOLID :
-                            default :
-                                aLineInfo.SetStyle( LineStyle::Solid );
-                        }
-                        switch( nStyle & PS_ENDCAP_STYLE_MASK )
-                        {
-                            case PS_ENDCAP_ROUND :
-                                if ( aLineInfo.GetWidth() )
-                                {
-                                    aLineInfo.SetLineCap( css::drawing::LineCap_ROUND );
-                                    break;
-                                }
-                                SAL_FALLTHROUGH;
-                            case PS_ENDCAP_SQUARE :
-                                if ( aLineInfo.GetWidth() )
-                                {
-                                    aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE );
-                                    break;
-                                }
-                                SAL_FALLTHROUGH;
-                            case PS_ENDCAP_FLAT :
-                            default :
-                                aLineInfo.SetLineCap( css::drawing::LineCap_BUTT );
-                        }
-                        switch( nStyle & PS_JOIN_STYLE_MASK )
-                        {
-                            case PS_JOIN_ROUND :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round );
-                            break;
-                            case PS_JOIN_MITER :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter );
-                            break;
-                            case PS_JOIN_BEVEL :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel );
-                            break;
-                            default :
-                                aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE );
-                        }
-                        pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfLineStyle>( aColorRef, aLineInfo, bTransparent ));
-                    }
-                }
-                break;
-
-                case EMR_CREATEBRUSHINDIRECT :
-                {
-                    sal_uInt32  nStyle;
-                    pWMF->ReadUInt32( nIndex );
-                    if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
-                    {
-                        pWMF->ReadUInt32( nStyle );
-                        pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfFillStyle>( ReadColor(), ( nStyle == BS_HOLLOW ) ));
-                    }
-                }
-                break;
-
-                case EMR_DELETEOBJECT :
-                {
-                    pWMF->ReadUInt32( nIndex );
-                    if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
-                        pOut->DeleteObject( nIndex );
-                }
-                break;
-
-                case EMR_ELLIPSE :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
-                    pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) );
-                }
-                break;
-
-                case EMR_RECTANGLE :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 );
-                    pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
-                }
-                break;
-
-                case EMR_ROUNDRECT :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nW ).ReadUInt32( nH );
-                    Size aSize( Size( nW, nH ) );
-                    pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize );
-                }
-                break;
-
-                case EMR_ARC :
-                {
-                    sal_uInt32 nStartX, nStartY, nEndX, nEndY;
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
-                    pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
-                }
-                break;
-
-                case EMR_CHORD :
-                {
-                    sal_uInt32 nStartX, nStartY, nEndX, nEndY;
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
-                    pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
-                }
-                break;
-
-                case EMR_PIE :
-                {
-                    sal_uInt32 nStartX, nStartY, nEndX, nEndY;
-                    pWMF->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 ));
-
-                    // #i73608# OutputDevice deviates from WMF
-                    // semantics. start==end means full ellipse here.
-                    if( nStartX == nEndX && nStartY == nEndY )
-                        pOut->DrawEllipse( aRect );
-                    else
-                        pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
-                }
-                break;
-
-                case EMR_LINETO :
-                {
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 );
-                    pOut->LineTo( Point( nX32, nY32 ), bRecordPath );
-                }
-                break;
-
-                case EMR_ARCTO :
-                {
-                    sal_uInt32 nStartX, nStartY, nEndX, nEndY;
-                    pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY );
-                    pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), true );
-                }
-                break;
-
-                case EMR_BEGINPATH :
-                {
-                    pOut->ClearPath();
-                    bRecordPath = true;
-                }
-                break;
-
-                case EMR_ABORTPATH :
-                    pOut->ClearPath();
-                    SAL_FALLTHROUGH;
-                case EMR_ENDPATH :
-                    bRecordPath = false;
-                break;
-
-                case EMR_CLOSEFIGURE :
-                    pOut->ClosePath();
-                break;
-
-                case EMR_FILLPATH :
-                    pOut->StrokeAndFillPath( false, true );
-                break;
-
-                case EMR_STROKEANDFILLPATH :
-                    pOut->StrokeAndFillPath( true, true );
-                break;
-
-                case EMR_STROKEPATH :
-                    pOut->StrokeAndFillPath( true, false );
-                break;
-
-                case EMR_SELECTCLIPPATH :
-                {
-                    sal_Int32 nClippingMode;
-                    pWMF->ReadInt32(nClippingMode);
-                    pOut->SetClipPath(pOut->GetPathObj(), nClippingMode, true);
-                }
-                break;
-
-                case EMR_EXTSELECTCLIPRGN :
-                {
-                    sal_Int32 nClippingMode, cbRgnData;
-                    pWMF->ReadInt32(cbRgnData);
-                    pWMF->ReadInt32(nClippingMode);
-
-                    // This record's region data should be ignored if mode
-                    // is RGN_COPY - see EMF spec section 2.3.2.2
-                    if (nClippingMode == RGN_COPY)
-                    {
-                        pOut->SetDefaultClipPath();
-                    }
-                    else
-                    {
-                        tools::PolyPolygon aPolyPoly;
-                        if (cbRgnData)
-                            ImplReadRegion(aPolyPoly, *pWMF, nRecSize);
-                        pOut->SetClipPath(aPolyPoly, nClippingMode, false);
-                    }
-
-                }
-                break;
-
-                case EMR_ALPHABLEND:
-                {
-                    sal_Int32 xDest(0), yDest(0), cxDest(0), cyDest(0);
-
-                    BLENDFUNCTION aFunc;
-                    sal_Int32 xSrc(0), ySrc(0), cxSrc(0), cySrc(0);
-                    XForm xformSrc;
-                    sal_uInt32 BkColorSrc(0), iUsageSrc(0), offBmiSrc(0);
-                    sal_uInt32 cbBmiSrc(0), offBitsSrc(0), cbBitsSrc(0);
-
-                    sal_uInt32   nStart = pWMF->Tell() - 8;
-                    pWMF->SeekRel( 0x10 );
-
-                    pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest );
-                    *pWMF >> aFunc;
-                    pWMF->ReadInt32( xSrc ).ReadInt32( ySrc );
-                    *pWMF >> xformSrc;
-                    pWMF->ReadUInt32( BkColorSrc ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc )
-                               .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc ).ReadInt32( cxSrc ).ReadInt32( cySrc ) ;
-
-                    sal_uInt32  dwRop = SRCAND|SRCINVERT;
-                    tools::Rectangle   aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
-
-                    if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
-                        bStatus = false;
-                    else
-                    {
-                        const sal_uInt32 nSourceSize = cbBmiSrc + cbBitsSrc + 14;
-                        bool bSafeRead = nSourceSize <= (nEndPos - nStartPos);
-                        sal_uInt32 nDeltaToDIB5HeaderSize(0);
-                        const bool bReadAlpha(0x01 == aFunc.aAlphaFormat);
-                        if (bSafeRead && bReadAlpha)
-                        {
-                            // we need to read alpha channel data if AlphaFormat of BLENDFUNCTION is
-                            // AC_SRC_ALPHA (==0x01). To read it, create a temp DIB-File which is ready
-                            // for DIB-5 format
-                            const sal_uInt32 nHeaderSize = getDIBV5HeaderSize();
-                            if (cbBmiSrc > nHeaderSize)
-                                bSafeRead = false;
-                            else
-                                nDeltaToDIB5HeaderSize = nHeaderSize - cbBmiSrc;
-                        }
-                        if (bSafeRead)
-                        {
-                            const sal_uInt32 nTargetSize(cbBmiSrc + nDeltaToDIB5HeaderSize + cbBitsSrc + 14);
-                            char* pBuf = new char[ nTargetSize ];
-                            SvMemoryStream aTmp( pBuf, nTargetSize, StreamMode::READ | StreamMode::WRITE );
-
-                            aTmp.ObjectOwnsMemory( true );
-
-                            // write BM-Header (14 bytes)
-                            aTmp.WriteUChar( 'B' )
-                                .WriteUChar( 'M' )
-                                .WriteUInt32( cbBitsSrc )
-                                .WriteUInt16( 0 )
-                                .WriteUInt16( 0 )
-                                .WriteUInt32( cbBmiSrc + nDeltaToDIB5HeaderSize + 14 );
-
-                            // copy DIBInfoHeader from source (cbBmiSrc bytes)
-                            pWMF->Seek( nStart + offBmiSrc );
-                            pWMF->ReadBytes(pBuf + 14, cbBmiSrc);
-
-                            if (bReadAlpha)
-                            {
-                                // need to add values for all stuff that DIBV5Header is bigger
-                                // than DIBInfoHeader, all values are correctly initialized to zero,
-                                // so we can use memset here
-                                memset(pBuf + cbBmiSrc + 14, 0, nDeltaToDIB5HeaderSize);
-                            }
-
-                            // copy bitmap data from source (offBitsSrc bytes)
-                            pWMF->Seek( nStart + offBitsSrc );
-                            pWMF->ReadBytes(pBuf + 14 + nDeltaToDIB5HeaderSize + cbBmiSrc, cbBitsSrc);
-                            aTmp.Seek( 0 );
-
-                            // prepare to read and fill BitmapEx
-                            BitmapEx aBitmapEx;
-
-                            if(bReadAlpha)
-                            {
-                                Bitmap aBitmap;
-                                AlphaMask aAlpha;
-
-                                if(ReadDIBV5(aBitmap, aAlpha, aTmp))
-                                {
-                                    aBitmapEx = BitmapEx(aBitmap, aAlpha);
-                                }
-                            }
-                            else
-                            {
-                                Bitmap aBitmap;
-
-                                if(ReadDIB(aBitmap, aTmp, true))
-                                {
-                                    if(0xff != aFunc.aSrcConstantAlpha)
-                                    {
-                                        // add const alpha channel
-                                        aBitmapEx = BitmapEx(
-                                            aBitmap,
-                                            AlphaMask(aBitmap.GetSizePixel(), &aFunc.aSrcConstantAlpha));
-                                    }
-                                    else
-                                    {
-                                        // just use Bitmap
-                                        aBitmapEx = BitmapEx(aBitmap);
-                                    }
-                                }
-                            }
-
-                            if(!aBitmapEx.IsEmpty())
-                            {
-                                // test if it is sensible to crop
-                                if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
-                                    ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
-                                        ( xSrc + cxSrc < aBitmapEx.GetSizePixel().Width() ) &&
-                                            ( ySrc + cySrc < aBitmapEx.GetSizePixel().Height() ) )
-                                {
-                                    const tools::Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
-
-                                    aBitmapEx.Crop( aCropRect );
-                                }
-
-#ifdef DBG_UTIL
-                                static bool bDoSaveForVisualControl(false);
-
-                                if(bDoSaveForVisualControl)
-                                {
-                                    SvFileStream aNew("c:\\metafile_content.png", StreamMode::WRITE|StreamMode::TRUNC);
-                                    vcl::PNGWriter aPNGWriter(aBitmapEx);
-                                    aPNGWriter.Write(aNew);
-                                }
-#endif
-                                aBmpSaveList.emplace_back(new BSaveStruct(aBitmapEx, aRect, dwRop));
-                            }
-                        }
-                    }
-                }
-                break;
-
-                case EMR_BITBLT :   // PASSTHROUGH INTENDED
-                case EMR_STRETCHBLT :
-                {
-                    sal_Int32   xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
-                    sal_uInt32  dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
-                    XForm   xformSrc;
-
-                    sal_uInt32  nStart = pWMF->Tell() - 8;
-
-                    pWMF->SeekRel( 0x10 );
-                    pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ).ReadUInt32( dwRop ).ReadInt32( xSrc ).ReadInt32( ySrc )
-                            >> xformSrc;
-                    pWMF->ReadUInt32( nColor ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc )
-                               .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc );
-
-                    if ( nRecType == EMR_STRETCHBLT )
-                        pWMF->ReadInt32( cxSrc ).ReadInt32( cySrc );
-                    else
-                        cxSrc = cySrc = 0;
-
-                    Bitmap      aBitmap;
-                    tools::Rectangle   aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
-
-                    if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
-                        bStatus = false;
-                    else
-                    {
-                        sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
-                        if ( nSize <= ( nEndPos - nStartPos ) )
-                        {
-                            char* pBuf = new char[ nSize ];
-                            SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
-                            aTmp.ObjectOwnsMemory( true );
-                            aTmp.WriteUChar( 'B' )
-                                .WriteUChar( 'M' )
-                                .WriteUInt32( cbBitsSrc )
-                                .WriteUInt16( 0 )
-                                .WriteUInt16( 0 )
-                                .WriteUInt32( cbBmiSrc + 14 );
-                            pWMF->Seek( nStart + offBmiSrc );
-                            pWMF->ReadBytes(pBuf + 14, cbBmiSrc);
-                            pWMF->Seek( nStart + offBitsSrc );
-                            pWMF->ReadBytes(pBuf + 14 + cbBmiSrc, cbBitsSrc);
-                            aTmp.Seek( 0 );
-                            ReadDIB(aBitmap, aTmp, true);
-
-                            // test if it is sensible to crop
-                            if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
-                                ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
-                                    ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
-                                        ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
-                            {
-                                tools::Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
-                                aBitmap.Crop( aCropRect );
-                            }
-                            aBmpSaveList.emplace_back(new BSaveStruct(aBitmap, aRect, dwRop));
-                        }
-                    }
-                }
-                break;
-
-                case EMR_STRETCHDIBITS :
-                {
-                    sal_Int32   xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
-                    sal_uInt32  offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
-                    sal_uInt32  nStart = pWMF->Tell() - 8;
-
-                    pWMF->SeekRel( 0x10 );
-                    pWMF->ReadInt32( xDest )
-                         .ReadInt32( yDest )
-                         .ReadInt32( xSrc )
-                         .ReadInt32( ySrc )
-                         .ReadInt32( cxSrc )
-                         .ReadInt32( cySrc )
-                         .ReadUInt32( offBmiSrc )
-                         .ReadUInt32( cbBmiSrc )
-                         .ReadUInt32( offBitsSrc )
-                         .ReadUInt32( cbBitsSrc )
-                         .ReadUInt32( iUsageSrc )
-                         .ReadUInt32( dwRop )
-                         .ReadInt32( cxDest )
-                         .ReadInt32( cyDest );
-
-                    Bitmap      aBitmap;
-                    tools::Rectangle   aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) );
-
-                    if (  ((SAL_MAX_UINT32 - 14)             < cbBitsSrc)
-                       || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc )
-                       )
-                    {
-                        bStatus = false;
-                    }
-                    else
-                    {
-                        sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
-                        if ( nSize <= ( nEndPos - nStartPos ) )
-                        {
-                            char* pBuf = new char[ nSize ];
-                            SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
-                            aTmp.ObjectOwnsMemory( true );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list