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

Bartosz Kosiorek (via logerrit) logerrit at kemper.freedesktop.org
Sat Nov 14 17:11:05 UTC 2020


 drawinglayer/source/tools/primitive2dxmldump.cxx |   45 ++++++++++++
 emfio/qa/cppunit/emf/EmfImportTest.cxx           |   81 ++++++++++++++++++-----
 emfio/qa/cppunit/emf/data/TextMapMode.emf        |binary
 emfio/source/reader/mtftools.cxx                 |   35 +++++++--
 4 files changed, 137 insertions(+), 24 deletions(-)

New commits:
commit b0b78838e795fcd7f3c53e7f74fb32b2921a5ccb
Author:     Bartosz Kosiorek <gang65 at poczta.onet.pl>
AuthorDate: Thu Nov 12 21:48:44 2020 +0100
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Sat Nov 14 18:10:09 2020 +0100

    tdf#35986 tdf#92315 tdf#116335 tdf#116622 Add support for MapMode TEXT
    
    To properly import some EMF files, the proper implementation of MapMode Text
    needs to be done according to MS documentation.
    I have also added regression tests.
    
    Change-Id: Id788294a498b93bebb62118d13ea545f80a60f01
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105771
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
index b9c4e2f83d1d..7a19e0486c89 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -16,6 +16,7 @@
 #include <memory>
 #include <sal/log.hxx>
 
+#include <drawinglayer/primitive2d/pointarrayprimitive2d.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
 #include <drawinglayer/primitive2d/Tools.hxx>
 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
@@ -206,7 +207,50 @@ void Primitive2dXmlDump::decomposeAndWrite(
                 rWriter.endElement();
             }
             break;
+            case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D:
+            {
+                const PointArrayPrimitive2D& rPointArrayPrimitive2D = dynamic_cast<const PointArrayPrimitive2D&>(*pBasePrimitive);
+                rWriter.startElement("pointarray");
+
+                rWriter.attribute("color", convertColorToString(rPointArrayPrimitive2D.getRGBColor()));
+
+                const std::vector< basegfx::B2DPoint > aPositions = rPointArrayPrimitive2D.getPositions();
+                for (std::vector<basegfx::B2DPoint>::const_iterator iter = aPositions.begin(); iter != aPositions.end(); ++iter)
+                {
+                    rWriter.startElement("point");
+                    rWriter.attribute("x", OUString::number(iter->getX()));
+                    rWriter.attribute("y", OUString::number(iter->getY()));
+                    rWriter.endElement();
+                }
+
+                rWriter.endElement();
+            }
+            break;
+            case PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D:
+            {
+                const PolygonStrokePrimitive2D& rPolygonStrokePrimitive2D = dynamic_cast<const PolygonStrokePrimitive2D&>(*pBasePrimitive);
+                rWriter.startElement("polygonstroke");
+
+                rWriter.startElement("polygon");
+                rWriter.content(basegfx::utils::exportToSvgPoints(rPolygonStrokePrimitive2D.getB2DPolygon()));
+                rWriter.endElement();
+
+                rWriter.startElement("line");
+                const drawinglayer::attribute::LineAttribute& aLineAttribute = rPolygonStrokePrimitive2D.getLineAttribute();
+                rWriter.attribute("color", convertColorToString(aLineAttribute.getColor()));
+                rWriter.attribute("width", aLineAttribute.getWidth());
+
+                rWriter.endElement();
+
+                rWriter.startElement("stroke");
+                const drawinglayer::attribute::StrokeAttribute& aStrokeAttribute = rPolygonStrokePrimitive2D.getStrokeAttribute();
+                rWriter.attribute("fulldotdashlen", aStrokeAttribute.getFullDotDashLen());
+                //rWriter.attribute("dotdasharray", aStrokeAttribute.getDotDashArray());
+                rWriter.endElement();
 
+                rWriter.endElement();
+            }
+            break;
             case PRIMITIVE2D_ID_POLYPOLYGONSTROKEPRIMITIVE2D:
             {
                 const PolyPolygonStrokePrimitive2D& rPolyPolygonStrokePrimitive2D = dynamic_cast<const PolyPolygonStrokePrimitive2D&>(*pBasePrimitive);
@@ -434,6 +478,7 @@ void Primitive2dXmlDump::decomposeAndWrite(
             {
                 rWriter.startElement("unhandled");
                 rWriter.attribute("id", OUStringToOString(sCurrentElementTag, RTL_TEXTENCODING_UTF8));
+                rWriter.attribute("idNumber", nId);
                 drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
                 pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
                                                    drawinglayer::geometry::ViewInformation2D());
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 9c03f92eb061..94914da60f8a 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -44,13 +44,12 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest:
 {
     uno::Reference<lang::XComponent> mxComponent;
 
-    void checkRectPrimitive(Primitive2DSequence const & rPrimitive);
-
-    void testWorking();
+    void testPolyPolygon();
     void TestDrawString();
     void TestDrawStringTransparent();
     void TestDrawLine();
     void TestLinearGradient();
+    void TestTextMapMode();
     void TestPdfInEmf();
 
     Primitive2DSequence parseEmf(const OUString& aSource);
@@ -61,11 +60,12 @@ public:
     uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
 
     CPPUNIT_TEST_SUITE(Test);
-    CPPUNIT_TEST(testWorking);
+    CPPUNIT_TEST(testPolyPolygon);
     CPPUNIT_TEST(TestDrawString);
     CPPUNIT_TEST(TestDrawStringTransparent);
     CPPUNIT_TEST(TestDrawLine);
     CPPUNIT_TEST(TestLinearGradient);
+    CPPUNIT_TEST(TestTextMapMode);
     CPPUNIT_TEST(TestPdfInEmf);
     CPPUNIT_TEST_SUITE_END();
 };
@@ -105,24 +105,39 @@ Primitive2DSequence Test::parseEmf(const OUString& aSource)
     return xEmfParser->getDecomposition(aInputStream, aPath, aEmptyValues);
 }
 
-void Test::checkRectPrimitive(Primitive2DSequence const & rPrimitive)
+void Test::testPolyPolygon()
 {
+    Primitive2DSequence aSequence = parseEmf("/emfio/qa/cppunit/emf/data/fdo79679-2.emf");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
     drawinglayer::Primitive2dXmlDump dumper;
-    xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(rPrimitive));
+    xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
 
     CPPUNIT_ASSERT (pDocument);
 
-    // emfio: add examples (later)
-    // assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00cc00"); // rect background color
-    // assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "height", "100"); // rect background height
-    // assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "width", "100"); // rect background width
-}
+    // Chart axis
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygon", "path", "m0 0h19746v14817h-19746z");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygoncolor", 2);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygoncolor[1]", "color", "#ffffff");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygoncolor[1]/polypolygon", "path", "m0 0h19780v14851h-19780z");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygoncolor[2]/polypolygon", "path", "m2574 13194v-12065h15303v12065z");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polygonstroke", 116);
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/mask/polygonstroke[1]/polygon", "2574,13194 2574,1129 17877,1129 17877,13194");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polygonstroke[1]/line", "color", "#ffffff");
+
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/mask/polygonstroke[10]/polygon", "8674,13194 8674,1129");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polygonstroke[10]/line", "color", "#000000");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/textsimpleportion", 28);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/textsimpleportion[6]", "width", "459");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/textsimpleportion[6]", "x", "9908");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/textsimpleportion[6]", "text", "0.5");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/textsimpleportion[6]", "fontcolor", "#000000");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/pointarray", 98);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/pointarray[1]", "color", "#000000");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/pointarray[1]/point", "x", "2574");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/pointarray[1]/point", "y", "1129");
 
-void Test::testWorking()
-{
-    Primitive2DSequence aSequenceRect = parseEmf("/emfio/qa/cppunit/emf/data/fdo79679-2.emf");
-    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRect.getLength()));
-    checkRectPrimitive(aSequenceRect);
 }
 
 void Test::TestDrawString()
@@ -221,6 +236,40 @@ void Test::TestLinearGradient()
     assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]/polypolygon", "path", "m7615.75822989746 0.216110019646294h7615.75822989746v7610.21611001965h-7615.75822989746z");
 }
 
+void Test::TestTextMapMode()
+{
+    // Check import of EMF image with records: SETMAPMODE with MM_TEXT MapMode, POLYLINE16, EXTCREATEPEN, EXTTEXTOUTW
+    // MM_TEXT is mapped to one device pixel. Positive x is to the right; positive y is down.
+    Primitive2DSequence aSequence = parseEmf("/emfio/qa/cppunit/emf/data/TextMapMode.emf");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence));
+    CPPUNIT_ASSERT (pDocument);
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor", 2);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[1]", "color", "#ffffff");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygoncolor[1]/polypolygon", "path", "m0 0h3542v4647h-3542z");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", 20);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion[1]", "text", "N");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion[1]", "fontcolor", "#4a70e3");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion[1]", "x", "2099");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion[1]", "y", "1859");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke", 138);
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonstroke[1]/polygon", "2142,1638 2142,1489");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke[1]/line", "color", "#4a70e3");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke[1]/line", "width", "11");
+
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonstroke[10]/polygon", "1967,1029 1869,952");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke[10]/line", "color", "#4a70e3");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke[10]/line", "width", "11");
+
+    assertXPathContent(pDocument, "/primitive2D/metafile/transform/polygonstroke[20]/polygon", "2710,1113 2873,1330");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke[20]/line", "color", "#666666");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/polygonstroke[20]/line", "width", "11");
+}
+
 void Test::TestPdfInEmf()
 {
     // Load a PPTX file, which has a shape, with a bitmap fill, which is an EMF, containing a PDF.
diff --git a/emfio/qa/cppunit/emf/data/TextMapMode.emf b/emfio/qa/cppunit/emf/data/TextMapMode.emf
new file mode 100644
index 000000000000..e0bbf73e2783
Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TextMapMode.emf differ
diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx
index 4b12f38675ce..cd3110ba9cbc 100644
--- a/emfio/source/reader/mtftools.cxx
+++ b/emfio/source/reader/mtftools.cxx
@@ -374,10 +374,13 @@ namespace emfio
                         {
                             fX2 -= mnWinOrgX;
                             fY2 -= mnWinOrgY;
-                            fX2 /= mnWinExtX;
-                            fY2 /= mnWinExtY;
-                            fX2 *= mnDevWidth;
-                            fY2 *= mnDevHeight;
+                            if ( mnMapMode != MM_TEXT )
+                            {
+                                fX2 /= mnWinExtX;
+                                fY2 /= mnWinExtY;
+                                fX2 *= mnDevWidth;
+                                fY2 *= mnDevHeight;
+                            }
                             fX2 += mnDevOrgX;
                             fY2 += mnDevOrgY;   // fX2, fY2 now in device units
                             fX2 *= static_cast<double>(mnMillX) * 100.0 / static_cast<double>(mnPixX);
@@ -464,10 +467,13 @@ namespace emfio
                         }
                         else
                         {
-                            fWidth /= mnWinExtX;
-                            fHeight /= mnWinExtY;
-                            fWidth *= mnDevWidth;
-                            fHeight *= mnDevHeight;
+                            if ( mnMapMode != MM_TEXT )
+                            {
+                                fWidth /= mnWinExtX;
+                                fHeight /= mnWinExtY;
+                                fWidth *= mnDevWidth;
+                                fHeight *= mnDevHeight;
+                            }
                             fWidth *= static_cast<double>(mnMillX) * 100.0 / static_cast<double>(mnPixX);
                             fHeight *= static_cast<double>(mnMillY) * 100.0 / static_cast<double>(mnPixY);
                         }
@@ -2131,6 +2137,12 @@ namespace emfio
         pSave->maPathObj = maPathObj;
         pSave->maClipPath = maClipPath;
 
+        SAL_INFO("emfio", "\t\t GfxMode: " << mnGfxMode);
+        SAL_INFO("emfio", "\t\t MapMode: " << mnMapMode);
+        SAL_INFO("emfio", "\t\t WinOrg: " << mnWinOrgX << ", " << mnWinOrgY);
+        SAL_INFO("emfio", "\t\t WinExt: " << mnWinExtX << " x " << mnWinExtY);
+        SAL_INFO("emfio", "\t\t DevOrg: " << mnDevOrgX << ", " << mnDevOrgY);
+        SAL_INFO("emfio", "\t\t DevWidth/Height: " << mnDevWidth << " x " << mnDevHeight);
         mvSaveStack.push_back( pSave );
     }
 
@@ -2180,6 +2192,13 @@ namespace emfio
             mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
             meLatestRasterOp = meRasterOp;
         }
+
+        SAL_INFO("emfio", "\t\t GfxMode: " << mnGfxMode);
+        SAL_INFO("emfio", "\t\t MapMode: " << mnMapMode);
+        SAL_INFO("emfio", "\t\t WinOrg: " << mnWinOrgX << ", " << mnWinOrgY);
+        SAL_INFO("emfio", "\t\t WinExt: " << mnWinExtX << " x " << mnWinExtY);
+        SAL_INFO("emfio", "\t\t DevOrg: " << mnDevOrgX << ", " << mnDevOrgY);
+        SAL_INFO("emfio", "\t\t DevWidth/Height: " << mnDevWidth << " x " << mnDevHeight);
         mvSaveStack.pop_back();
     }
 


More information about the Libreoffice-commits mailing list