[Libreoffice-commits] core.git: drawinglayer/source

Bartosz Kosiorek gang65 at poczta.onet.pl
Thu Nov 16 20:56:16 UTC 2017


 drawinglayer/source/tools/emfpbrush.cxx         |    4 
 drawinglayer/source/tools/emfpcustomlinecap.cxx |    2 
 drawinglayer/source/tools/emfphelperdata.cxx    |   68 +++---------
 drawinglayer/source/tools/emfphelperdata.hxx    |    5 
 drawinglayer/source/tools/emfppath.cxx          |   32 -----
 drawinglayer/source/tools/emfppath.hxx          |    4 
 drawinglayer/source/tools/emfpregion.cxx        |  133 ++++++++++++++++--------
 drawinglayer/source/tools/emfpregion.hxx        |   21 ++-
 8 files changed, 131 insertions(+), 138 deletions(-)

New commits:
commit d0c4cee7e5ad00363d264aec0011a4b07983b19d
Author: Bartosz Kosiorek <gang65 at poczta.onet.pl>
Date:   Sun Nov 5 00:02:49 2017 +0100

    tdf#113704 Implement proper reading of the EmfPlusRegionNode
    
    Regions are specified as a binary tree of region nodes, and each node must
    either be a terminal node or specify one or two child nodes.
    
    Nodes contains two child nodes:
      RegionNodeDataTypeAnd = 0x00000001,
      RegionNodeDataTypeOr = 0x00000002,
      RegionNodeDataTypeXor = 0x00000003,
      RegionNodeDataTypeExclude = 0x00000004,
      RegionNodeDataTypeComplement = 0x00000005,
    
    Terminal nodes:
      RegionNodeDataTypeRect = 0x10000000,
      RegionNodeDataTypePath = 0x10000001,
      RegionNodeDataTypeEmpty = 0x10000002,
      RegionNodeDataTypeInfinite = 0x10000003
    
    RegionNode must contain at least one element.
    
    Change-Id: I668e5892701b979f09bcf5bbce44a43226676192
    Reviewed-on: https://gerrit.libreoffice.org/44324
    Reviewed-by: Bartosz Kosiorek <gang65 at poczta.onet.pl>
    Tested-by: Bartosz Kosiorek <gang65 at poczta.onet.pl>

diff --git a/drawinglayer/source/tools/emfpbrush.cxx b/drawinglayer/source/tools/emfpbrush.cxx
index c6444631e1af..4d743d10b684 100644
--- a/drawinglayer/source/tools/emfpbrush.cxx
+++ b/drawinglayer/source/tools/emfpbrush.cxx
@@ -181,7 +181,7 @@ namespace emfplushelper
                     SAL_INFO("drawinglayer", "EMF+\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec);
 
                     path = new EMFPPath(pathPoints);
-                    path->Read(s, pathFlags, rR);
+                    path->Read(s, pathFlags);
 
                     s.Seek(pos + pathLength);
 
@@ -198,7 +198,7 @@ namespace emfplushelper
                     sal_uInt64 const pos = s.Tell();
                     SAL_INFO("drawinglayer", "EMF+\t use boundary, points: " << boundaryPointCount);
                     path = new EMFPPath(boundaryPointCount);
-                    path->Read(s, 0x0, rR);
+                    path->Read(s, 0x0);
 
                     s.Seek(pos + 8 * boundaryPointCount);
 
diff --git a/drawinglayer/source/tools/emfpcustomlinecap.cxx b/drawinglayer/source/tools/emfpcustomlinecap.cxx
index 4357276a18f8..91eeb4ea8c52 100644
--- a/drawinglayer/source/tools/emfpcustomlinecap.cxx
+++ b/drawinglayer/source/tools/emfpcustomlinecap.cxx
@@ -81,7 +81,7 @@ namespace emfplushelper
         SAL_INFO("drawinglayer", "EMF+\t\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec);
 
         EMFPPath path(pathPoints);
-        path.Read(s, pathFlags, rR);
+        path.Read(s, pathFlags);
         polygon = path.GetPolygon(rR, false);
         mbIsFilled = bFill;
 
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx
index 6d9a8a499f8c..9d2c7db10008 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -138,14 +138,14 @@ namespace emfplushelper
                 SAL_INFO("drawinglayer", "EMF+\theader: 0x" << std::hex << header << " points: " << std::dec << points << " additional flags: 0x" << std::hex << pathFlags << std::dec);
                 EMFPPath *path;
                 maEMFPObjects[index].reset(path = new EMFPPath(points));
-                path->Read(rObjectStream, pathFlags, *this);
+                path->Read(rObjectStream, pathFlags);
                 break;
             }
             case EmfPlusObjectTypeRegion:
             {
                 EMFPRegion *region;
                 maEMFPObjects[index].reset(region = new EMFPRegion());
-                region->Read(rObjectStream);
+                region->ReadRegion(rObjectStream, *this);
                 break;
             }
             case EmfPlusObjectTypeImage:
@@ -700,74 +700,52 @@ namespace emfplushelper
     {
     }
 
-    void EmfPlusHelperData::combineClip(int combineMode, ::basegfx::B2DPolyPolygon const & polygon)
+    ::basegfx::B2DPolyPolygon const EmfPlusHelperData::combineClip(::basegfx::B2DPolyPolygon const & leftPolygon, int combineMode, ::basegfx::B2DPolyPolygon const & rightPolygon)
     {
+        basegfx::B2DPolyPolygon aClippedPolyPolygon;
         switch (combineMode)
         {
         case EmfPlusCombineModeReplace:
         {
-            HandleNewClipRegion(polygon, mrTargetHolders, mrPropertyHolders);
+            aClippedPolyPolygon = rightPolygon;
             break;
         }
         case EmfPlusCombineModeIntersect:
         {
-            const basegfx::B2DPolyPolygon aOriginalPolyPolygon(
-                        mrPropertyHolders.Current().getClipPolyPolygon());
-
-            basegfx::B2DPolyPolygon aClippedPolyPolygon;
-            if (aOriginalPolyPolygon.count())
+            if (leftPolygon.count())
             {
                 aClippedPolyPolygon = basegfx::utils::clipPolyPolygonOnPolyPolygon(
-                            aOriginalPolyPolygon,
-                            polygon,
+                            leftPolygon,
+                            rightPolygon,
                             true,
                             false);
             }
-
-            HandleNewClipRegion(aClippedPolyPolygon, mrTargetHolders, mrPropertyHolders);
             break;
         }
         case EmfPlusCombineModeUnion:
         {
-            basegfx::B2DPolyPolygon aOriginalPolyPolygon(
-                        mrPropertyHolders.Current().getClipPolyPolygon());
-
-            aOriginalPolyPolygon = ::basegfx::utils::solvePolygonOperationOr(aOriginalPolyPolygon, polygon);
-            HandleNewClipRegion(aOriginalPolyPolygon, mrTargetHolders, mrPropertyHolders);
-
+            aClippedPolyPolygon = ::basegfx::utils::solvePolygonOperationOr(leftPolygon, rightPolygon);
             break;
         }
         case EmfPlusCombineModeXOR:
         {
-            basegfx::B2DPolyPolygon aOriginalPolyPolygon(
-                        mrPropertyHolders.Current().getClipPolyPolygon());
-
-            aOriginalPolyPolygon = ::basegfx::utils::solvePolygonOperationXor(aOriginalPolyPolygon, polygon);
-            HandleNewClipRegion(aOriginalPolyPolygon, mrTargetHolders, mrPropertyHolders);
-
+            aClippedPolyPolygon = ::basegfx::utils::solvePolygonOperationXor(leftPolygon, rightPolygon);
             break;
         }
         case EmfPlusCombineModeExclude:
         {
             // Replaces the existing region with the part of itself that is not in the new region.
-            basegfx::B2DPolyPolygon aOriginalPolyPolygon(
-                        mrPropertyHolders.Current().getClipPolyPolygon());
-
-            aOriginalPolyPolygon = ::basegfx::utils::solvePolygonOperationDiff(aOriginalPolyPolygon, polygon);
-            HandleNewClipRegion(aOriginalPolyPolygon, mrTargetHolders, mrPropertyHolders);
+            aClippedPolyPolygon = ::basegfx::utils::solvePolygonOperationDiff(leftPolygon, rightPolygon);
             break;
         }
         case EmfPlusCombineModeComplement:
         {
             // Replaces the existing region with the part of the new region that is not in the existing region.
-            basegfx::B2DPolyPolygon aOriginalPolyPolygon(
-                        mrPropertyHolders.Current().getClipPolyPolygon());
-
-            aOriginalPolyPolygon = ::basegfx::utils::solvePolygonOperationDiff(polygon, aOriginalPolyPolygon);
-            HandleNewClipRegion(aOriginalPolyPolygon, mrTargetHolders, mrPropertyHolders);
+            aClippedPolyPolygon = ::basegfx::utils::solvePolygonOperationDiff(rightPolygon, leftPolygon);
             break;
         }
         }
+        return aClippedPolyPolygon;
     }
 
     void EmfPlusHelperData::processEmfPlusData(
@@ -1048,7 +1026,7 @@ namespace emfplushelper
                         SAL_INFO("drawinglayer", "EMF+\t: " << ((flags & 0x8000) ? "color" : "brush index") << " 0x" << std::hex << brushIndexOrColor << std::dec);
 
                         EMFPPath path(points, true);
-                        path.Read(rMS, flags, *this);
+                        path.Read(rMS, flags);
 
                         EMFPPlusFillPolygon(path.GetPolygon(*this), flags & 0x8000, brushIndexOrColor);
 
@@ -1060,7 +1038,7 @@ namespace emfplushelper
                         rMS.ReadUInt32(points);
                         SAL_INFO("drawinglayer", "EMF+ DrawLines in slot: " << (flags & 0xff) << " points: " << points);
                         EMFPPath path(points, true);
-                        path.Read(rMS, flags, *this);
+                        path.Read(rMS, flags);
 
                         // 0x2000 bit indicates whether to draw an extra line between the last point
                         // and the first point, to close the shape.
@@ -1549,7 +1527,7 @@ namespace emfplushelper
                                         mappedPoint.getX() + mappedSize.getX(),
                                         mappedPoint.getY() + mappedSize.getY()))));
 
-                        combineClip(combineMode, polyPolygon);
+                        HandleNewClipRegion(combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), combineMode, polyPolygon), mrTargetHolders, mrPropertyHolders);
                         break;
                     }
                     case EmfPlusRecordTypeSetClipPath:
@@ -1562,7 +1540,7 @@ namespace emfplushelper
                         ::basegfx::B2DPolyPolygon& clipPoly(path.GetPolygon(*this));
                         // clipPoly.transform(rState.mapModeTransform);
 
-                        combineClip(combineMode, clipPoly);
+                        HandleNewClipRegion( combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), combineMode, clipPoly), mrTargetHolders, mrPropertyHolders);
                         break;
                     }
                     case EmfPlusRecordTypeSetClipRegion:
@@ -1572,17 +1550,7 @@ namespace emfplushelper
                         SAL_INFO("drawinglayer", "EMF+\tregion in slot: " << (flags & 0xff) << " combine mode: " << combineMode);
                         EMFPRegion *region = static_cast<EMFPRegion*>(maEMFPObjects[flags & 0xff].get());
 
-                        // reset clip
-                        if (region && region->parts == 0 && region->initialState == EmfPlusRegionInitialStateInfinite)
-                        {
-                            // use existing tooling from wmfemfhelper
-                            HandleNewClipRegion(::basegfx::B2DPolyPolygon(), mrTargetHolders, mrPropertyHolders);
-                            // updateClipping(::basegfx::B2DPolyPolygon(), rFactoryParms, combineMode == 1);
-                        }
-                        else
-                        {
-                            SAL_WARN("drawinglayer", "EMF+\tTODO");
-                        }
+                        HandleNewClipRegion(combineClip(mrPropertyHolders.Current().getClipPolyPolygon(), combineMode, region->regionPolyPolygon), mrTargetHolders, mrPropertyHolders);
                         break;
                     }
                     case EmfPlusRecordTypeOffsetClip:
diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx
index 8c91e4edadb0..98a90ab49b36 100644
--- a/drawinglayer/source/tools/emfphelperdata.hxx
+++ b/drawinglayer/source/tools/emfphelperdata.hxx
@@ -66,6 +66,7 @@ namespace emfplushelper
     #define EmfPlusRecordTypeSetRenderingOrigin 0x401D
     #define EmfPlusRecordTypeSetAntiAliasMode 0x401E
     #define EmfPlusRecordTypeSetTextRenderingHint 0x401F
+    //TODO EmfPlusSetTextContrast 0x4020
     #define EmfPlusRecordTypeSetInterpolationMode 0x4021
     #define EmfPlusRecordTypeSetPixelOffsetMode 0x4022
     //TODO EmfPlusRecordTypeSetCompositingMode 0x4023
@@ -104,8 +105,6 @@ namespace emfplushelper
     #define EmfPlusObjectTypeImageAttributes 0x800
     #define EmfPlusObjectTypeCustomLineCap 0x900
 
-    #define EmfPlusRegionInitialStateInfinite 0x10000003
-
     enum UnitType
     {
         UnitTypeWorld = 0x00,
@@ -242,7 +241,6 @@ namespace emfplushelper
 
         // helper functions
         ::basegfx::BColor EMFPGetBrushColorOrARGBColor(sal_uInt16 flags, sal_uInt32 brushIndexOrColor) const;
-        void combineClip(int combineMode, ::basegfx::B2DPolyPolygon const & polygon);
 
     public:
         EmfPlusHelperData(
@@ -262,6 +260,7 @@ namespace emfplushelper
         // readers
         static void ReadRectangle(SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
         static bool readXForm(SvStream& rIn, basegfx::B2DHomMatrix& rTarget);
+        ::basegfx::B2DPolyPolygon const combineClip(::basegfx::B2DPolyPolygon const & leftPolygon, int combineMode, ::basegfx::B2DPolyPolygon const & rightPolygon);
     };
 }
 
diff --git a/drawinglayer/source/tools/emfppath.cxx b/drawinglayer/source/tools/emfppath.cxx
index 00245d523123..8e0d2b159a20 100644
--- a/drawinglayer/source/tools/emfppath.cxx
+++ b/drawinglayer/source/tools/emfppath.cxx
@@ -17,29 +17,11 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <com/sun/star/rendering/PathCapType.hpp>
-#include <com/sun/star/rendering/PathJoinType.hpp>
-#include <com/sun/star/rendering/TexturingMode.hpp>
-#include <com/sun/star/rendering/XCanvas.hpp>
-#include <basegfx/utils/canvastools.hxx>
-#include <basegfx/utils/gradienttools.hxx>
-#include <basegfx/utils/tools.hxx>
-#include <basegfx/numeric/ftools.hxx>
 #include <basegfx/point/b2dpoint.hxx>
-#include <basegfx/vector/b2dsize.hxx>
-#include <basegfx/range/b2drange.hxx>
-#include <basegfx/range/b2drectangle.hxx>
-#include <basegfx/polygon/b2dlinegeometry.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/polygon/b2dpolygontools.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dpolypolygontools.hxx>
-#include <vcl/canvastools.hxx>
 #include "emfppath.hxx"
 
-using namespace ::com::sun::star;
-using namespace ::basegfx;
-
 namespace emfplushelper
 {
     EMFPPath::EMFPPath (sal_Int32 _nPoints, bool bLines)
@@ -60,8 +42,7 @@ namespace emfplushelper
     {
     }
 
-    // TODO: remove rR argument when debug code is no longer needed
-    void EMFPPath::Read (SvStream& s, sal_uInt32 pathFlags, EmfPlusHelperData const & rR)
+    void EMFPPath::Read (SvStream& s, sal_uInt32 pathFlags)
     {
         for (int i = 0; i < nPoints; i ++)
         {
@@ -99,16 +80,7 @@ namespace emfplushelper
             }
         }
 
-        aPolygon.clear ();
-
-#if OSL_DEBUG_LEVEL > 1
-        const ::basegfx::B2DRectangle aBounds (::basegfx::utils::getRange (GetPolygon (rR)));
-
-        SAL_INFO ("drawinglayer",
-                    "EMF+\tpolygon bounding box: " << aBounds.getMinX () << "," << aBounds.getMinY () << aBounds.getWidth () << "x" << aBounds.getHeight () << " (mapped)");
-#else
-        (void) rR; // avoid warnings
-#endif
+        aPolygon.clear();
     }
 
     ::basegfx::B2DPolyPolygon& EMFPPath::GetPolygon (EmfPlusHelperData const & rR, bool bMapIt, bool bAddLineToCloseShape)
diff --git a/drawinglayer/source/tools/emfppath.hxx b/drawinglayer/source/tools/emfppath.hxx
index 81bdcc406a13..98996f834dd9 100644
--- a/drawinglayer/source/tools/emfppath.hxx
+++ b/drawinglayer/source/tools/emfppath.hxx
@@ -21,7 +21,6 @@
 #define INCLUDED_DRAWINGLAYER_SOURCE_TOOLS_EMFPPATH_HXX
 
 #include "emfphelperdata.hxx"
-#include <memory>
 
 namespace emfplushelper
 {
@@ -36,8 +35,7 @@ namespace emfplushelper
 
         virtual ~EMFPPath() override;
 
-        // TODO: remove rR argument when debug code is no longer needed
-        void Read(SvStream& s, sal_uInt32 pathFlags, EmfPlusHelperData const & rR);
+        void Read(SvStream& s, sal_uInt32 pathFlags);
 
         ::basegfx::B2DPolyPolygon& GetPolygon(EmfPlusHelperData const & rR, bool bMapIt = true, bool bAddLineToCloseShape = false);
     };
diff --git a/drawinglayer/source/tools/emfpregion.cxx b/drawinglayer/source/tools/emfpregion.cxx
index fb043f29a493..940723617ead 100644
--- a/drawinglayer/source/tools/emfpregion.cxx
+++ b/drawinglayer/source/tools/emfpregion.cxx
@@ -17,76 +17,121 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include <com/sun/star/rendering/PathCapType.hpp>
-#include <com/sun/star/rendering/PathJoinType.hpp>
-#include <com/sun/star/rendering/TexturingMode.hpp>
-#include <com/sun/star/rendering/XCanvas.hpp>
-#include <basegfx/utils/canvastools.hxx>
-#include <basegfx/utils/gradienttools.hxx>
-#include <basegfx/utils/tools.hxx>
-#include <basegfx/numeric/ftools.hxx>
 #include <basegfx/point/b2dpoint.hxx>
 #include <basegfx/vector/b2dsize.hxx>
-#include <basegfx/range/b2drange.hxx>
 #include <basegfx/range/b2drectangle.hxx>
-#include <basegfx/polygon/b2dlinegeometry.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
-#include <vcl/canvastools.hxx>
 #include "emfpregion.hxx"
-
-using namespace ::com::sun::star;
-using namespace ::basegfx;
+#include "emfppath.hxx"
 
 namespace emfplushelper
 {
     EMFPRegion::EMFPRegion()
-        : parts(0)
-        , combineMode(nullptr)
-        , initialState(0)
-        , ix(0.0)
-        , iy(0.0)
-        , iw(0.0)
-        , ih(0.0)
     {
     }
 
     EMFPRegion::~EMFPRegion()
     {
-        if (combineMode)
-        {
-            delete[] combineMode;
-            combineMode = nullptr;
-        }
     }
 
-    void EMFPRegion::Read(SvStream& s)
+    ::basegfx::B2DPolyPolygon EMFPRegion::ReadRegionNode(SvStream& s, EmfPlusHelperData& rR)
     {
-        sal_uInt32 header;
-        s.ReadUInt32(header).ReadInt32(parts);
-        SAL_INFO("drawinglayer", "EMF+\tregion");
-        SAL_INFO("drawinglayer", "EMF+\theader: 0x" << std::hex << header << " parts: " << parts << std::dec);
+        // Regions are specified as a binary tree of region nodes, and each node must either be a terminal node
+        // (RegionNodeDataTypeRect, RegionNodeDataTypePath, RegionNodeDataTypeEmpty, RegionNodeDataTypeInfinite)
+        // or specify one or two child nodes
+        // (RegionNodeDataTypeAnd, RegionNodeDataTypeOr, RegionNodeDataTypeXor,
+        // RegionNodeDataTypeExclude, RegionNodeDataTypeComplement).
+        sal_uInt32 dataType;
+        ::basegfx::B2DPolyPolygon polygon;
+        s.ReadUInt32(dataType);
+        SAL_INFO("drawinglayer", "EMF+\t Region node data type 0x" << std::hex << dataType << std::dec);
 
-        if (parts)
+        switch (dataType)
+        {
+        case RegionNodeDataTypeAnd: // CombineModeIntersect
+        case RegionNodeDataTypeOr: // CombineModeUnion
+        case RegionNodeDataTypeXor: // CombineModeXOR
+        case RegionNodeDataTypeExclude: // CombineModeExclude
+        case RegionNodeDataTypeComplement: // CombineModeComplement
+        {
+            ::basegfx::B2DPolyPolygon leftPolygon = ReadRegionNode(s, rR);
+            ::basegfx::B2DPolyPolygon rightPolygon = ReadRegionNode(s, rR);
+            polygon = rR.combineClip(leftPolygon, dataType, rightPolygon);
+            break;
+        }
+        case RegionNodeDataTypeRect:
         {
-            if (parts<0 || sal_uInt32(parts)>SAL_MAX_INT32 / sizeof(sal_Int32))
-            {
-                parts = SAL_MAX_INT32 / sizeof(sal_Int32);
-            }
+            float dx, dy, dw, dh;
+            s.ReadFloat(dx).ReadFloat(dy).ReadFloat(dw).ReadFloat(dh);
+            SAL_INFO("drawinglayer", "EMF+\t\t RegionNodeDataTypeRect x:" << dx << ", y:" << dy <<
+                     ", width:" << dw << ", height:" << dh);
+
+            ::basegfx::B2DPoint mappedPoint(rR.Map(dx, dy));
+            ::basegfx::B2DSize mappedSize(rR.MapSize(dw, dh));
+
+            ::basegfx::B2DPolyPolygon polyPolygon(
+                ::basegfx::B2DPolygon(
+                    ::basegfx::utils::createPolygonFromRect(
+                        ::basegfx::B2DRectangle(
+                            mappedPoint.getX(),
+                            mappedPoint.getY(),
+                            mappedPoint.getX() + mappedSize.getX(),
+                            mappedPoint.getY() + mappedSize.getY()))));
+            polygon = polyPolygon;
+            break;
+        }
+        case RegionNodeDataTypePath:
+        {
+            sal_Int32 pathLength;
+            s.ReadInt32(pathLength);
+            SAL_INFO("drawinglayer", "EMF+\t\t RegionNodeDataTypePath, Path Length: " << pathLength << " bytes");
+
+            sal_uInt32 header, pathFlags;
+            sal_Int32 points;
 
-            combineMode = new sal_Int32[parts];
+            s.ReadUInt32(header).ReadInt32(points).ReadUInt32(pathFlags);
+            SAL_INFO("drawinglayer", "EMF+\t\t header: 0x" << std::hex << header <<
+                     " points: " << std::dec << points << " additional flags: 0x" << std::hex << pathFlags << std::dec);
 
-            for (int i = 0; i < parts; i++)
-            {
-                s.ReadInt32(combineMode[i]);
-                SAL_INFO("drawinglayer", "EMF+\tcombine mode [" << i << "]: 0x" << std::hex << combineMode[i] << std::dec);
-            }
+            EMFPPath path(points);
+            path.Read(s, pathFlags);
+            polygon = path.GetPolygon(rR);
+            break;
         }
+        case RegionNodeDataTypeEmpty:
+        {
+            SAL_INFO("drawinglayer", "EMF+\t\t RegionNodeDataTypeEmpty");
+            SAL_WARN("drawinglayer", "EMF+\t\t TODO we need to set empty polygon here");
+            polygon = ::basegfx::B2DPolyPolygon();
+
+            break;
+        }
+        case RegionNodeDataTypeInfinite:
+        {
+            SAL_INFO("drawinglayer", "EMF+\t\t RegionNodeDataTypeInfinite");
+            polygon = ::basegfx::B2DPolyPolygon();
+            break;
+        }
+        default:
+        {
+            SAL_WARN("drawinglayer", "EMF+\t\t Unhandled region type: 0x" << std::hex << dataType << std::dec);
+            polygon = ::basegfx::B2DPolyPolygon();
+        }
+        }
+        return polygon;
+    }
+
+    void EMFPRegion::ReadRegion(SvStream& s, EmfPlusHelperData& rR)
+    {
+        sal_uInt32 header, count;
+        s.ReadUInt32(header).ReadUInt32(count);
+        // An array should be RegionNodeCount+1 of EmfPlusRegionNode objects.
+        SAL_INFO("drawinglayer", "EMF+\t version: 0x" << std::hex << header << std::dec << ", region node count: " << count);
 
-        s.ReadInt32(initialState);
-        SAL_INFO("drawinglayer", "EMF+\tinitial state: 0x" << std::hex << initialState << std::dec);
+        regionPolyPolygon = ReadRegionNode(s, rR);
     }
 }
 
diff --git a/drawinglayer/source/tools/emfpregion.hxx b/drawinglayer/source/tools/emfpregion.hxx
index 67689634d9e9..a027d9c62b37 100644
--- a/drawinglayer/source/tools/emfpregion.hxx
+++ b/drawinglayer/source/tools/emfpregion.hxx
@@ -24,16 +24,27 @@
 
 namespace emfplushelper
 {
+    typedef enum
+    {
+        RegionNodeDataTypeAnd = 0x00000001,
+        RegionNodeDataTypeOr = 0x00000002,
+        RegionNodeDataTypeXor = 0x00000003,
+        RegionNodeDataTypeExclude = 0x00000004,
+        RegionNodeDataTypeComplement = 0x00000005,
+        RegionNodeDataTypeRect = 0x10000000,
+        RegionNodeDataTypePath = 0x10000001,
+        RegionNodeDataTypeEmpty = 0x10000002,
+        RegionNodeDataTypeInfinite = 0x10000003
+    } RegionNodeDataType;
+
     struct EMFPRegion : public EMFPObject
     {
-        sal_Int32 parts;
-        sal_Int32 *combineMode;
-        sal_Int32 initialState;
-        float ix, iy, iw, ih;
+        ::basegfx::B2DPolyPolygon regionPolyPolygon;
 
         EMFPRegion();
         virtual ~EMFPRegion() override;
-        void Read(SvStream& s);
+        void ReadRegion(SvStream& s, EmfPlusHelperData& rR);
+        ::basegfx::B2DPolyPolygon ReadRegionNode(SvStream& s, EmfPlusHelperData& rR);
     };
 }
 


More information about the Libreoffice-commits mailing list