summaryrefslogtreecommitdiff
path: root/emfio
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2020-11-12 21:48:44 +0100
committerTomaž Vajngerl <quikee@gmail.com>2020-11-14 18:10:09 +0100
commitb0b78838e795fcd7f3c53e7f74fb32b2921a5ccb (patch)
treeed63a09c5f52a11805b1bc1783b110f71654202f /emfio
parentfc351e37d6513be91c03d9a81e977a817d65206d (diff)
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@gmail.com>
Diffstat (limited to 'emfio')
-rw-r--r--emfio/qa/cppunit/emf/EmfImportTest.cxx81
-rw-r--r--emfio/qa/cppunit/emf/data/TextMapMode.emfbin0 -> 46588 bytes
-rw-r--r--emfio/source/reader/mtftools.cxx35
3 files changed, 92 insertions, 24 deletions
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
--- /dev/null
+++ b/emfio/qa/cppunit/emf/data/TextMapMode.emf
Binary files 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();
}