summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emfio/inc/wmfreader.hxx1
-rw-r--r--emfio/qa/cppunit/wmf/data/TestBigPPI.wmfbin0 -> 3842 bytes
-rw-r--r--emfio/qa/cppunit/wmf/wmfimporttest.cxx23
-rw-r--r--emfio/source/reader/wmfreader.cxx24
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
new file mode 100644
index 000000000000..e120af2790db
--- /dev/null
+++ b/emfio/qa/cppunit/wmf/data/TestBigPPI.wmf
Binary files differ
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());