drawinglayer/source/tools/emfphelperdata.cxx             |   64 +++++++++++----
 drawinglayer/source/tools/emfphelperdata.hxx             |    4 
 emfio/qa/cppunit/emf/EmfImportTest.cxx                   |   48 +++++++++++
 emfio/qa/cppunit/emf/data/TestEmfPlusFillClosedCurve.emf |binary
 4 files changed, 98 insertions(+), 18 deletions(-)

New commits:
commit 2156c1090d318b4d28bc14537754bea73507d501
Author:     Bartosz Kosiorek <gan...@poczta.onet.pl>
AuthorDate: Sun May 15 00:09:44 2022 +0200
Commit:     Bartosz Kosiorek <gan...@poczta.onet.pl>
CommitDate: Mon May 16 17:26:20 2022 +0200

    tdf#143876 EMF+ Add DrawClosedCurve and FillClosedCurve support
    
    With this commit EmfPlusDrawClosedCurve and EmfPlusFillClosedCurve
    support was added. There is still missing Filling Mode (it
    is always set to Even Odd Alternate:
    https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule )
    and Tension support for spline bends.
    The graphics is displayed as Tension=0.
    A value of Tension=0 specifies that the spline is a sequence of straight 
lines.
    As the value increases, the curve becomes more rounded.
    For more information, see [SPLINE77] and [PETZOLD].
    
    Change-Id: Ibccfd584e3d55cd0ca8a29da9f450916d56705d5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134333
    Tested-by: Jenkins
    Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl>

diff --git a/drawinglayer/source/tools/emfphelperdata.cxx 
b/drawinglayer/source/tools/emfphelperdata.cxx
index 0734dad6d6ea..231e86e7c767 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -80,6 +80,7 @@ namespace emfplushelper
             case EmfPlusRecordTypeDrawRects: return 
"EmfPlusRecordTypeDrawRects";
             case EmfPlusRecordTypeFillPolygon: return 
"EmfPlusRecordTypeFillPolygon";
             case EmfPlusRecordTypeDrawLines: return 
"EmfPlusRecordTypeDrawLines";
+            case EmfPlusRecordTypeFillClosedCurve: return 
"EmfPlusRecordTypeFillClosedCurve";
             case EmfPlusRecordTypeFillEllipse: return 
"EmfPlusRecordTypeFillEllipse";
             case EmfPlusRecordTypeDrawEllipse: return 
"EmfPlusRecordTypeDrawEllipse";
             case EmfPlusRecordTypeFillPie: return "EmfPlusRecordTypeFillPie";
@@ -89,6 +90,7 @@ namespace emfplushelper
             case EmfPlusRecordTypeFillPath: return "EmfPlusRecordTypeFillPath";
             case EmfPlusRecordTypeDrawPath: return "EmfPlusRecordTypeDrawPath";
             case EmfPlusRecordTypeDrawBeziers: return 
"EmfPlusRecordTypeDrawBeziers";
+            case EmfPlusRecordTypeDrawClosedCurve: return 
"EmfPlusRecordTypeDrawClosedCurve";
             case EmfPlusRecordTypeDrawImage: return 
"EmfPlusRecordTypeDrawImage";
             case EmfPlusRecordTypeDrawImagePoints: return 
"EmfPlusRecordTypeDrawImagePoints";
             case EmfPlusRecordTypeDrawString: return 
"EmfPlusRecordTypeDrawString";
@@ -610,8 +612,11 @@ namespace emfplushelper
         if (pen->GetColor().IsTransparent())
         {
             drawinglayer::primitive2d::Primitive2DContainer aContainer;
-            if ((pen->penDataFlags & EmfPlusPenDataStartCap)
-                || (pen->penDataFlags & EmfPlusPenDataEndCap))
+            if (aStart.isDefault() && aEnd.isDefault())
+                
aContainer.append(drawinglayer::primitive2d::Primitive2DReference(
+                    new 
drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+                        polygon, lineAttribute, 
pen->GetStrokeAttribute(mdExtractedXScale))));
+            else
             {
                 aContainer.resize(polygon.count());
                 for (sal_uInt32 i = 0; i < polygon.count(); i++)
@@ -620,18 +625,17 @@ namespace emfplushelper
                             polygon.getB2DPolygon(i), lineAttribute,
                             pen->GetStrokeAttribute(mdExtractedXScale), 
aStart, aEnd));
             }
-            else
-                
aContainer.append(drawinglayer::primitive2d::Primitive2DReference(
-                    new 
drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
-                        polygon, lineAttribute, 
pen->GetStrokeAttribute(mdExtractedXScale))));
             mrTargetHolders.Current().append(
                 new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                     std::move(aContainer), (255 - pen->GetColor().GetAlpha()) 
/ 255.0));
         }
         else
         {
-            if ((pen->penDataFlags & EmfPlusPenDataStartCap)
-                || (pen->penDataFlags & EmfPlusPenDataEndCap))
+            if (aStart.isDefault() && aEnd.isDefault())
+                mrTargetHolders.Current().append(
+                    new 
drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
+                        polygon, lineAttribute, 
pen->GetStrokeAttribute(mdExtractedXScale)));
+            else
                 for (sal_uInt32 i = 0; i < polygon.count(); i++)
                 {
                     mrTargetHolders.Current().append(
@@ -639,10 +643,6 @@ namespace emfplushelper
                             polygon.getB2DPolygon(i), lineAttribute,
                             pen->GetStrokeAttribute(mdExtractedXScale), 
aStart, aEnd));
                 }
-            else
-                mrTargetHolders.Current().append(
-                    new 
drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D(
-                        polygon, lineAttribute, 
pen->GetStrokeAttribute(mdExtractedXScale)));
         }
 
         if ((pen->penDataFlags & EmfPlusPenDataCustomStartCap) && 
(pen->customStartCap->polygon.begin()->count() > 1))
@@ -1393,26 +1393,24 @@ namespace emfplushelper
                     }
                     case EmfPlusRecordTypeFillPolygon:
                     {
-                        const sal_uInt8 index = flags & 0xff;
                         sal_uInt32 brushIndexOrColor, points;
 
                         rMS.ReadUInt32(brushIndexOrColor);
                         rMS.ReadUInt32(points);
-                        SAL_INFO("drawinglayer.emf", "EMF+\t FillPolygon in 
slot: " << index << " points: " << points);
+                        SAL_INFO("drawinglayer.emf", "EMF+\t Points: " << 
points);
                         SAL_INFO("drawinglayer.emf", "EMF+\t " << ((flags & 
0x8000) ? "Color" : "Brush index") << " : 0x" << std::hex << brushIndexOrColor 
<< std::dec);
 
                         EMFPPath path(points, true);
                         path.Read(rMS, flags);
 
                         EMFPPlusFillPolygon(path.GetPolygon(*this), flags & 
0x8000, brushIndexOrColor);
-
                         break;
                     }
                     case EmfPlusRecordTypeDrawLines:
                     {
                         sal_uInt32 points;
                         rMS.ReadUInt32(points);
-                        SAL_INFO("drawinglayer.emf", "EMF+\t DrawLines in 
slot: " << (flags & 0xff) << " points: " << points);
+                        SAL_INFO("drawinglayer.emf", "EMF+\t Points: " << 
points);
                         EMFPPath path(points, true);
                         path.Read(rMS, flags);
 
@@ -1482,6 +1480,40 @@ namespace emfplushelper
                         }
                         break;
                     }
+                    case EmfPlusRecordTypeDrawClosedCurve:
+                    case EmfPlusRecordTypeFillClosedCurve:
+                    {
+                        // Silent MSVC warning C4701: potentially 
uninitialized local variable 'brushIndexOrColor' used
+                        sal_uInt32 brushIndexOrColor = 999, points;
+                        float aTension;
+                        if (type == EmfPlusRecordTypeFillClosedCurve)
+                        {
+                            rMS.ReadUInt32(brushIndexOrColor);
+                            SAL_INFO("drawinglayer.emf",
+                                "EMF+\t Fill Mode: " << (flags & 0x2000 ? 
"Winding" : "Alternate"));
+                        }
+                        rMS.ReadFloat(aTension);
+                        rMS.ReadUInt32(points);
+                        SAL_WARN("drawinglayer.emf",
+                                 "EMF+\t Tension: " << aTension << " Points: " 
<< points);
+                        SAL_WARN_IF(aTension != 0, "drawinglayer.emf",
+                                    "EMF+\t TODO Add support for tension 
different than 0");
+                        SAL_INFO("drawinglayer.emf",
+                                 "EMF+\t " << (flags & 0x8000 ? "Color" : 
"Brush index") << " : 0x"
+                                           << std::hex << brushIndexOrColor << 
std::dec);
+
+                        EMFPPath path(points, true);
+                        path.Read(rMS, flags);
+                        if (type == EmfPlusRecordTypeFillClosedCurve)
+                            EMFPPlusFillPolygon(path.GetPolygon(*this, /* 
bMapIt */ true,
+                                                                
/*bAddLineToCloseShape */ true),
+                                                flags & 0x8000, 
brushIndexOrColor);
+                        else
+                            EMFPPlusDrawPolygon(path.GetPolygon(*this, /* 
bMapIt */ true,
+                                                                
/*bAddLineToCloseShape */ true),
+                                                flags & 0xff);
+                        break;
+                    }
                     case EmfPlusRecordTypeDrawImage:
                     case EmfPlusRecordTypeDrawImagePoints:
                     {
diff --git a/drawinglayer/source/tools/emfphelperdata.hxx 
b/drawinglayer/source/tools/emfphelperdata.hxx
index 796cbff03387..ef870f31e687 100644
--- a/drawinglayer/source/tools/emfphelperdata.hxx
+++ b/drawinglayer/source/tools/emfphelperdata.hxx
@@ -54,8 +54,8 @@ namespace emfplushelper
     #define EmfPlusRecordTypeFillRegion 0x4013
     #define EmfPlusRecordTypeFillPath 0x4014
     #define EmfPlusRecordTypeDrawPath 0x4015
-    //TODO EmfPlusRecordTypeFillClosedCurve 0x4016
-    //TODO EmfPlusRecordTypeDrawClosedCurve 0x4017
+    #define EmfPlusRecordTypeFillClosedCurve 0x4016
+    #define EmfPlusRecordTypeDrawClosedCurve 0x4017
     //TODO EmfPlusRecordTypeDrawCurve 0x4018
     #define EmfPlusRecordTypeDrawBeziers 0x4019
     #define EmfPlusRecordTypeDrawImage 0x401A
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx 
b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 6c5e77bb67dd..cf999c2dff6e 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -68,6 +68,7 @@ class Test : public test::BootstrapFixture, public 
XmlTestTools, public unotest:
     void TestEmfPlusGetDC();
     void TestEmfPlusSave();
     void TestEmfPlusDrawPathWithMiterLimit();
+    void TestEmfPlusFillClosedCurve();
     void TestExtTextOutOpaqueAndClipTransform();
 
     void TestBitBltStretchBltWMF();
@@ -117,6 +118,7 @@ public:
     CPPUNIT_TEST(TestEmfPlusGetDC);
     CPPUNIT_TEST(TestEmfPlusSave);
     CPPUNIT_TEST(TestEmfPlusDrawPathWithMiterLimit);
+    CPPUNIT_TEST(TestEmfPlusFillClosedCurve);
     CPPUNIT_TEST(TestExtTextOutOpaqueAndClipTransform);
 
     CPPUNIT_TEST(TestBitBltStretchBltWMF);
@@ -1069,6 +1071,52 @@ void Test::TestEmfPlusDrawPathWithMiterLimit()
     assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/stroke", 0);
 }
 
+void Test::TestEmfPlusFillClosedCurve()
+{
+    // tdf#143876 EMF+ records: SetWorldTransform, FillClosedCurve, 
DrawClosedCurve
+    Primitive2DSequence aSequence
+        = 
parseEmf(u"emfio/qa/cppunit/emf/data/TestEmfPlusFillClosedCurve.emf");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = 
dumper.dumpAndParse(Primitive2DContainer(aSequence));
+    CPPUNIT_ASSERT(pDocument);
+
+    assertXPath(pDocument, aXPathPrefix + "polypolygoncolor", 2);
+    assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]", "color", 
"#808080");
+    assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[1]/polypolygon", 
"path",
+                "m18202.841744243 13758.4401790456 1269.96570308672 "
+                
"3175.02465670283-2539.93140617345-2116.68310446856h2539.93140617345l-2539."
+                "93140617345 2116.68310446856z");
+
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke", 2);
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"color", "#000000");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"width", "10");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"linejoin", "Miter");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"miterangle", "3");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"linecap", "BUTT");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/polypolygon", 
"path",
+                "m18202.841744243 13758.4401790456 1269.96570308672 "
+                
"3175.02465670283-2539.93140617345-2116.68310446856h2539.93140617345l-2539."
+                "93140617345 2116.68310446856z");
+
+    assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]", "color", 
"#808080");
+    //TODO Check path with implemented Winding
+    assertXPath(pDocument, aXPathPrefix + "polypolygoncolor[2]/polypolygon", 
"path",
+                "m22012.7388535032 13758.4401790456 1269.96570308672 "
+                
"3175.02465670283-2539.93140617344-2116.68310446856h2539.93140617344l-2539."
+                "93140617344 2116.68310446856z");
+
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"color", "#000000");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"width", "10");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"linejoin", "Miter");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"miterangle", "3");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"linecap", "BUTT");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/polypolygon", 
"path",
+                "m22012.7388535032 13758.4401790456 1269.96570308672 "
+                
"3175.02465670283-2539.93140617344-2116.68310446856h2539.93140617344l-2539."
+                "93140617344 2116.68310446856z");
+}
+
 void Test::TestExtTextOutOpaqueAndClipTransform()
 {
     // tdf#142495 EMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUTW, 
MODIFYWORLDTRANSFORM, CREATEFONTINDIRECT.
diff --git a/emfio/qa/cppunit/emf/data/TestEmfPlusFillClosedCurve.emf 
b/emfio/qa/cppunit/emf/data/TestEmfPlusFillClosedCurve.emf
new file mode 100644
index 000000000000..ad9140a770d0
Binary files /dev/null and 
b/emfio/qa/cppunit/emf/data/TestEmfPlusFillClosedCurve.emf differ

Reply via email to