diff options
-rw-r--r-- | emfio/inc/wmfreader.hxx | 1 | ||||
-rw-r--r-- | emfio/qa/cppunit/wmf/data/TestBigPPI.wmf | bin | 0 -> 3842 bytes | |||
-rw-r--r-- | emfio/qa/cppunit/wmf/wmfimporttest.cxx | 23 | ||||
-rw-r--r-- | emfio/source/reader/wmfreader.cxx | 24 |
4 files changed, 44 insertions, 4 deletions
diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx index f7788d53651c..5c6979550ef4 100644 --- a/emfio/inc/wmfreader.hxx +++ b/emfio/inc/wmfreader.hxx @@ -33,6 +33,7 @@ namespace emfio private: sal_uInt16 mnUnitsPerInch; sal_uInt32 mnRecSize; + bool mbPlaceable; // embedded EMF data std::optional<std::vector<sal_uInt8>> mpEMFStream; diff --git a/emfio/qa/cppunit/wmf/data/TestBigPPI.wmf b/emfio/qa/cppunit/wmf/data/TestBigPPI.wmf Binary files differnew file mode 100644 index 000000000000..e120af2790db --- /dev/null +++ b/emfio/qa/cppunit/wmf/data/TestBigPPI.wmf diff --git a/emfio/qa/cppunit/wmf/wmfimporttest.cxx b/emfio/qa/cppunit/wmf/wmfimporttest.cxx index a85876e03a7d..c5b2ddbc3205 100644 --- a/emfio/qa/cppunit/wmf/wmfimporttest.cxx +++ b/emfio/qa/cppunit/wmf/wmfimporttest.cxx @@ -52,6 +52,7 @@ public: void testEmfProblem(); void testEmfLineStyles(); void testWorldTransformFontSize(); + void testBigPPI(); void testTdf93750(); void testTdf99402(); void testTdf39894(); @@ -66,6 +67,7 @@ public: CPPUNIT_TEST(testEmfProblem); CPPUNIT_TEST(testEmfLineStyles); CPPUNIT_TEST(testWorldTransformFontSize); + CPPUNIT_TEST(testBigPPI); CPPUNIT_TEST(testTdf93750); CPPUNIT_TEST(testTdf99402); CPPUNIT_TEST(testTdf39894); @@ -310,6 +312,27 @@ void WmfTest::testWorldTransformFontSize() assertXPath(pDoc, "/metafile/font[4]", "weight", "normal"); } +void WmfTest::testBigPPI() +{ + // Test that PPI is reduced from 2540 to 96 (width from META_SETWINDOWEXT) to make the graphic + // bigger + SvFileStream aFileStream(getFullUrl(u"TestBigPPI.wmf"), StreamMode::READ); + GDIMetaFile aGDIMetaFile; + ReadWindowMetafile(aFileStream, aGDIMetaFile); + + MetafileXmlDump dumper; + dumper.filterAllActionTypes(); + dumper.filterActionType(MetaActionType::FONT, false); + xmlDocUniquePtr pDoc = dumpAndParse(dumper, aGDIMetaFile); + + CPPUNIT_ASSERT(pDoc); + + // If the PPI was not reduced the width and height would be <100 which is too small + // Related: tdf#150888 + assertXPath(pDoc, "/metafile", "width", "2540"); + assertXPath(pDoc, "/metafile", "height", "2143"); +} + void WmfTest::testTdf93750() { SvFileStream aFileStream(getFullUrl(u"tdf93750.emf"), StreamMode::READ); diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx index 8a54b21f0580..33ef9dd3d0e1 100644 --- a/emfio/source/reader/wmfreader.cxx +++ b/emfio/source/reader/wmfreader.cxx @@ -1351,11 +1351,11 @@ namespace emfio tools::Rectangle aPlaceableBound; - bool bPlaceable = nPlaceableMetaKey == 0x9ac6cdd7L; + mbPlaceable = nPlaceableMetaKey == 0x9ac6cdd7L; - SAL_INFO("emfio", "Placeable: \"" << (bPlaceable ? "yes" : "no") << "\""); + SAL_INFO("emfio", "Placeable: \"" << (mbPlaceable ? "yes" : "no") << "\""); - if (bPlaceable) + if (mbPlaceable) { //TODO do some real error handling here sal_Int16 nVal(0); @@ -1608,9 +1608,10 @@ namespace emfio Point aViewportOrg(0,0); std::optional<Size> aViewportExt; + MappingMode eMapMode = MappingMode::MM_ANISOTROPIC; + if (nEnd - nPos) { - MappingMode eMapMode = MappingMode::MM_ANISOTROPIC; sal_uInt16 nFunction; sal_uInt32 nRSize; @@ -1952,6 +1953,21 @@ namespace emfio if (aWinExt) { rPlaceableBound = tools::Rectangle(aWinOrg, *aWinExt); + if (mbPlaceable && eMapMode == MM_ANISOTROPIC) + { + // It seems that (in MM_ANISOTROPIC WMFs) the "inch" field (PPI) in META_PLACEABLE is + // ignored and instead competitor office suites decide what it should be arbitrarily + // Could have to do with MM_ANISOTROPICs definition: + // Logical units are mapped to arbitrary units with arbitrarily scaled axes. + // The issue is that when PPI is bigger than the window size, the image appears + // tiny (smaller than an inch squared). + // A solution is to scale PPI down in such images to an arbitrary amount that makes + // the image visible: + auto nWidth = rPlaceableBound.GetWidth(); + auto nHeight = rPlaceableBound.GetHeight(); + if (mnUnitsPerInch > nWidth && mnUnitsPerInch > nHeight) + mnUnitsPerInch = std::max(nWidth, nHeight); + } SAL_INFO("emfio", "Window dimension " " left: " << rPlaceableBound.Left() << " top: " << rPlaceableBound.Top() << " right: " << rPlaceableBound.Right() << " bottom: " << rPlaceableBound.Bottom()); |