emfio/inc/wmfreader.hxx                  |    1 +
 emfio/qa/cppunit/wmf/data/TestBigPPI.wmf |binary
 emfio/qa/cppunit/wmf/wmfimporttest.cxx   |   23 +++++++++++++++++++++++
 emfio/source/reader/wmfreader.cxx        |   25 +++++++++++++++++++++----
 4 files changed, 45 insertions(+), 4 deletions(-)

New commits:
commit df11fc4994e73f676fae317e8fc278dceef0e7d3
Author:     Paris Oplopoios <paris.oplopo...@collabora.com>
AuthorDate: Wed Oct 19 16:57:11 2022 +0300
Commit:     Christian Lohmaier <lohmaier+libreoff...@googlemail.com>
CommitDate: Wed Oct 26 12:46:38 2022 +0200

    tdf#150888 Scale down PPI if it would result in a tiny image
    
    The reason for the blurry document in tdf#150888 is that the image is
    tiny. PPI is 2540 in that image but when using the window bounding box
    (96, 81) this results in a very small image that the .odt then scales up
    which makes it blurry.
    
    Apart from that, when opening the extracted .wmf in Draw it's also very
    small, around 0.04" squared.
    
    Because MM_ANISOTROPICs definition allows for arbritrary scaling, when
    an image would be smaller than an inch squared the PPI is scaled down to
    either the images width or height. This makes the extracted WMF match
    the size of competitor office suites and fix the blur bug without
    breaking past tests.
    
    Change-Id: I11eab879848d9308f818708a91fd9eb91fc65200
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141533
    Tested-by: Jenkins
    Tested-by: Tomaž Vajngerl <qui...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit a03a47bb0791d88fedb2650bca412c28469b0b27)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141775
    Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com>

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
Binary files /dev/null and b/emfio/qa/cppunit/wmf/data/TestBigPPI.wmf differ
diff --git a/emfio/qa/cppunit/wmf/wmfimporttest.cxx 
b/emfio/qa/cppunit/wmf/wmfimporttest.cxx
index d6533d8ba07c..33cf3f546c92 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();
@@ -65,6 +66,7 @@ public:
     CPPUNIT_TEST(testEmfProblem);
     CPPUNIT_TEST(testEmfLineStyles);
     CPPUNIT_TEST(testWorldTransformFontSize);
+    CPPUNIT_TEST(testBigPPI);
     CPPUNIT_TEST(testTdf93750);
     CPPUNIT_TEST(testTdf99402);
     CPPUNIT_TEST(testTdf39894);
@@ -308,6 +310,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 c4d21b3231b1..f17654097ba0 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -1412,11 +1412,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);
@@ -1669,9 +1669,10 @@ namespace emfio
         Point aViewportOrg(0,0);
         std::optional<Size>  aViewportExt;
 
+        sal_Int16 nMapMode = MM_ANISOTROPIC;
+
         if (nEnd - nPos)
         {
-            sal_Int16 nMapMode = MM_ANISOTROPIC;
             sal_uInt16 nFunction;
             sal_uInt32 nRSize;
 
@@ -2001,6 +2002,21 @@ namespace emfio
         if (aWinExt)
         {
             rPlaceableBound = tools::Rectangle(aWinOrg, *aWinExt);
+            if (mbPlaceable && nMapMode == 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());
@@ -2035,6 +2051,7 @@ namespace emfio
         : MtfTools(rGDIMetaFile, rStreamWMF)
         , mnUnitsPerInch(96)
         , mnRecSize(0)
+        , mbPlaceable(false)
         , mnEMFRecCount(0)
         , mnEMFRec(0)
         , mnEMFSize(0)

Reply via email to