drawinglayer/source/tools/emfphelperdata.cxx                    |    4 
 drawinglayer/source/tools/emfppen.cxx                           |   23 +++-
 drawinglayer/source/tools/emfppen.hxx                           |    2 
 drawinglayer/source/tools/primitive2dxmldump.cxx                |    5 +
 emfio/qa/cppunit/emf/EmfImportTest.cxx                          |   50 
++++++++++
 emfio/qa/cppunit/emf/data/TestEmfPlusDrawPathWithMiterLimit.emf |binary
 6 files changed, 76 insertions(+), 8 deletions(-)

New commits:
commit e709ebe42ad06974b822366e4eea1a6c2ee61e10
Author:     Bartosz Kosiorek <gan...@poczta.onet.pl>
AuthorDate: Wed May 11 12:54:48 2022 +0200
Commit:     Bartosz Kosiorek <gan...@poczta.onet.pl>
CommitDate: Fri May 13 13:49:18 2022 +0200

    tdf#142261 EMF+ Add support for Miter Limit
    
    With this commit the Miter is properly implemented,
    according to [EMF-PLUS] documentation:
    
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-emfplus/5ef071f3-f503-4f16-b027-7c4bcf2d1d81
    
    The formula for stroke miter limit is described here:
    https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit
    
    Change-Id: Ida87063cc045460e61ffae118f64cf133c810dbf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134164
    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 c5b282998d71..4d0db58c026b 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -596,8 +596,8 @@ namespace emfplushelper
         const double transformedPenWidth = mdExtractedYScale * pen->penWidth;
         drawinglayer::attribute::LineAttribute lineAttribute(
             pen->GetColor().getBColor(), transformedPenWidth, 
pen->GetLineJoinType(),
-            css::drawing::LineCap_BUTT,
-            basegfx::deg2rad(15.0)); // TODO Add MiterLimit support
+            css::drawing::LineCap_BUTT, //TODO implement PenDataDashedLineCap 
supportr here
+            pen->fMiterMinimumAngle);
 
         drawinglayer::attribute::LineStartEndAttribute aStart;
         if (pen->penDataFlags & EmfPlusPenDataStartCap)
diff --git a/drawinglayer/source/tools/emfppen.cxx 
b/drawinglayer/source/tools/emfppen.cxx
index b0408f8d0e80..ec073d56ea59 100644
--- a/drawinglayer/source/tools/emfppen.cxx
+++ b/drawinglayer/source/tools/emfppen.cxx
@@ -58,7 +58,7 @@ namespace emfplushelper
         , startCap(0)
         , endCap(0)
         , lineJoin(0)
-        , miterLimit(0.0)
+        , fMiterMinimumAngle(basegfx::deg2rad(5.0))
         , dashStyle(0)
         , dashCap(0)
         , dashOffset(0.0)
@@ -286,13 +286,26 @@ namespace emfplushelper
 
         if (penDataFlags & PenDataMiterLimit)
         {
+            float miterLimit;
             s.ReadFloat(miterLimit);
-            SAL_WARN("drawinglayer.emf", "EMF+\t\tTODO PenDataMiterLimit: " << 
std::dec << miterLimit);
+
+            // EMF+ JoinTypeMiterClipped is working as our B2DLineJoin::Miter
+            // For EMF+ LineJoinTypeMiter we are simulating it by changing 
angle
+            if (lineJoin == EmfPlusLineJoinTypeMiter)
+                miterLimit = 3.0 * miterLimit;
+            // asin angle must be in range [-1, 1]
+            if (abs(miterLimit) > 1.0)
+                fMiterMinimumAngle = 2.0 * asin(1.0 / miterLimit);
+            else
+                // enable miter limit for all angles
+                fMiterMinimumAngle = basegfx::deg2rad(180.0);
+            SAL_INFO("drawinglayer.emf",
+                     "EMF+\t\t MiterLimit: " << std::dec << miterLimit
+                                             << ", Miter minimum angle (rad): 
" << fMiterMinimumAngle);
         }
         else
-        {
-            miterLimit = 0;
-        }
+            fMiterMinimumAngle = basegfx::deg2rad(5.0);
+
 
         if (penDataFlags & PenDataLineStyle)
         {
diff --git a/drawinglayer/source/tools/emfppen.hxx 
b/drawinglayer/source/tools/emfppen.hxx
index cad849e4f278..6a7929f332f8 100644
--- a/drawinglayer/source/tools/emfppen.hxx
+++ b/drawinglayer/source/tools/emfppen.hxx
@@ -105,7 +105,7 @@ namespace emfplushelper
         sal_Int32 startCap;
         sal_Int32 endCap;
         sal_Int32 lineJoin;
-        float miterLimit;
+        double fMiterMinimumAngle;
         sal_Int32 dashStyle;
         sal_Int32 dashCap;
         float dashOffset;
diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx 
b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 886ffbf7fdd3..4e35d599876f 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -167,8 +167,12 @@ void writeLineAttribute(::tools::XmlWriter& rWriter,
             rWriter.attribute("linejoin", "Bevel");
             break;
         case basegfx::B2DLineJoin::Miter:
+        {
             rWriter.attribute("linejoin", "Miter");
+            rWriter.attribute("miterangle",
+                              
basegfx::rad2deg(rLineAttribute.getMiterMinimumAngle()));
             break;
+        }
         case basegfx::B2DLineJoin::Round:
             rWriter.attribute("linejoin", "Round");
             break;
@@ -191,6 +195,7 @@ void writeLineAttribute(::tools::XmlWriter& rWriter,
             rWriter.attribute("linecap", "Unknown");
             break;
     }
+
     rWriter.endElement();
 }
 
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx 
b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index f83688745e02..6c5e77bb67dd 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -67,6 +67,7 @@ class Test : public test::BootstrapFixture, public 
XmlTestTools, public unotest:
     void TestFillRegion();
     void TestEmfPlusGetDC();
     void TestEmfPlusSave();
+    void TestEmfPlusDrawPathWithMiterLimit();
     void TestExtTextOutOpaqueAndClipTransform();
 
     void TestBitBltStretchBltWMF();
@@ -115,6 +116,7 @@ public:
     CPPUNIT_TEST(TestFillRegion);
     CPPUNIT_TEST(TestEmfPlusGetDC);
     CPPUNIT_TEST(TestEmfPlusSave);
+    CPPUNIT_TEST(TestEmfPlusDrawPathWithMiterLimit);
     CPPUNIT_TEST(TestExtTextOutOpaqueAndClipTransform);
 
     CPPUNIT_TEST(TestBitBltStretchBltWMF);
@@ -1019,6 +1021,54 @@ void Test::TestEmfPlusSave()
                        "12832.6557236512,4907.54325697157");
 }
 
+void Test::TestEmfPlusDrawPathWithMiterLimit()
+{
+    // tdf#142261 EMF+ records: DrawPath, TranslateWorldTransform, Object 
(Brush, Pen, Path)
+    // Check if Miter is correctly set for Lines
+    Primitive2DSequence aSequence
+        = 
parseEmf(u"emfio/qa/cppunit/emf/data/TestEmfPlusDrawPathWithMiterLimit.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 + "polypolygonstroke", 3);
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"color", "#c800c8");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"width", "1057");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"linejoin", "Miter");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/line", 
"miterangle", "5");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[1]/stroke", 0);
+
+    assertXPath(pDocument, aXPathPrefix + "unifiedtransparence", 3);
+    assertXPath(pDocument, aXPathPrefix + "unifiedtransparence[1]", 
"transparence", "85");
+    assertXPath(pDocument, aXPathPrefix + 
"unifiedtransparence[1]/polypolygonstroke/line", "color",
+                "#6400c8");
+    assertXPath(pDocument, aXPathPrefix + 
"unifiedtransparence[1]/polypolygonstroke/line", "width",
+                "1057");
+    assertXPath(pDocument, aXPathPrefix + 
"unifiedtransparence[1]/polypolygonstroke/line",
+                "linejoin", "Miter");
+    assertXPath(pDocument, aXPathPrefix + 
"unifiedtransparence[1]/polypolygonstroke/line",
+                "miterangle", "19");
+    assertXPath(pDocument, aXPathPrefix + "unifiedtransparence[2]", 
"transparence", "69");
+    assertXPath(pDocument, aXPathPrefix + 
"unifiedtransparence[2]/polypolygonstroke/line",
+                "miterangle", "19");
+    assertXPath(pDocument, aXPathPrefix + "unifiedtransparence[3]", 
"transparence", "53");
+    assertXPath(pDocument, aXPathPrefix + 
"unifiedtransparence[3]/polypolygonstroke/line",
+                "miterangle", "19");
+
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"color", "#0000ff");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"width", "1057");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"linejoin", "Miter");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/line", 
"miterangle", "60");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[2]/stroke", 0);
+
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/line", 
"color", "#0000ff");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/line", 
"width", "1057");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/line", 
"linejoin", "Miter");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/line", 
"miterangle", "60");
+    assertXPath(pDocument, aXPathPrefix + "polypolygonstroke[3]/stroke", 0);
+}
+
 void Test::TestExtTextOutOpaqueAndClipTransform()
 {
     // tdf#142495 EMF records: SETBKCOLOR, SELECTOBJECT, EXTTEXTOUTW, 
MODIFYWORLDTRANSFORM, CREATEFONTINDIRECT.
diff --git a/emfio/qa/cppunit/emf/data/TestEmfPlusDrawPathWithMiterLimit.emf 
b/emfio/qa/cppunit/emf/data/TestEmfPlusDrawPathWithMiterLimit.emf
new file mode 100644
index 000000000000..e8e46486384b
Binary files /dev/null and 
b/emfio/qa/cppunit/emf/data/TestEmfPlusDrawPathWithMiterLimit.emf differ

Reply via email to