vcl/source/gdi/pdfwriter_impl.cxx |   39 +++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

New commits:
commit bc3f6c3a47411a3b5dafadca4e5c55cd24e30662
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Tue Aug 22 10:47:33 2023 +0300
Commit:     خالد حسني <kha...@libreoffice.org>
CommitDate: Tue Aug 22 11:45:31 2023 +0200

    tdf#155610: Workaround Acrobat bug with Type 3 fonts and unusual UPEM
    
    Adobe Acrobat seems to have a bug with Type 3 fonts with unusual UPEM,
    the common 1000 and 2048 UPEM work fine, but Sitka has 2250 UPEM and
    Acrobat handles the advance widths in this case incorrectly and
    everything gets cramped up with gaps when we re-start glyph positioning.
    
    Workaround this by always using 0.001 scale in FontMatrix (equivalent to
    1000 UPEM) and scale everything if the font’s UPEM is different.
    
    Change-Id: I80d25a16456f04bb00304b22b967688fa8260a83
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155935
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 4cda5a09b287..fe93cabe0897 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -2580,13 +2580,14 @@ bool PDFWriterImpl::emitType3Font(const 
vcl::font::PhysicalFontFace* pFace,
             + OString::number(aSubsetInfo.m_aFontBBox.Bottom() + 1)
             + "]\n");
 
-        auto nScale = 1. / pFace->UnitsPerEm();
-        aLine.append(
-            "/FontMatrix["
-            + OString::number(nScale)
-            + " 0 0 "
-            + OString::number(nScale)
-            + " 0 0]\n");
+        // tdf#155610
+        // Adobe Acrobat does not seem to like certain UPEMs, so instead of
+        // setting the FontMatrix scale relative to the UPEM, we always set to
+        // 0.001 (1000 UPEM) and scale everything if the font’s UPEM is
+        // different.
+        double fScale = 1000. / pFace->UnitsPerEm();
+
+        aLine.append("/FontMatrix[0.001 0 0 0.001 0 0]\n");
 
         sal_Int32 pGlyphStreams[256] = {};
         aLine.append("/CharProcs<<\n");
@@ -2615,7 +2616,8 @@ bool PDFWriterImpl::emitType3Font(const 
vcl::font::PhysicalFontFace* pFace,
             "/Widths[");
         for (auto i = 0u; i < nGlyphs; i++)
         {
-            aLine.append(OString::number(pWidths[i]) + " ");
+            appendDouble(pWidths[i] * fScale, aLine);
+            aLine.append(" ");
         }
         aLine.append("]\n");
 
@@ -2645,8 +2647,8 @@ bool PDFWriterImpl::emitType3Font(const 
vcl::font::PhysicalFontFace* pFace,
         std::list<StreamRedirect> aOutputStreams;
 
         // Scale for glyph outlines.
-        double fScaleX = GetDPIX() / 72.;
-        double fScaleY = GetDPIY() / 72.;
+        double fScaleX = (GetDPIX() / 72.) * fScale;
+        double fScaleY = (GetDPIY() / 72.) * fScale;
 
         for (auto i = 1u; i < nGlyphs; i++)
         {
@@ -2654,7 +2656,8 @@ bool PDFWriterImpl::emitType3Font(const 
vcl::font::PhysicalFontFace* pFace,
             if (!updateObject(nStream))
                 return false;
             OStringBuffer aContents(1024);
-            aContents.append(OString::number(pWidths[i]) + " 0 d0\n");
+            appendDouble(pWidths[i] * fScale, aContents);
+            aContents.append(" 0 d0\n");
 
             const auto& rGlyph = rSubset.m_aMapping.find(pGlyphIds[i])->second;
             const auto& rLayers = rGlyph.getColorLayers();
@@ -2691,8 +2694,10 @@ bool PDFWriterImpl::emitType3Font(const 
vcl::font::PhysicalFontFace* pFace,
                 }
                 aContents.append(
                     "BT "
-                    "/F" + OString::number(rLayer.m_nFontID) + " "
-                    + OString::number(pFace->UnitsPerEm()) + " Tf "
+                    "/F" + OString::number(rLayer.m_nFontID) + " ");
+                appendDouble(pFace->UnitsPerEm() * fScale, aContents);
+                aContents.append(
+                    " Tf "
                     "<");
                 appendHex(rLayer.m_nSubsetGlyphID, aContents);
                 aContents.append(
@@ -2712,11 +2717,11 @@ bool PDFWriterImpl::emitType3Font(const 
vcl::font::PhysicalFontFace* pFace,
                                                     aUsedBitmaps, 
aResourceDict, aOutputStreams);
 
                 auto nObject = aBitmapEmit.m_aReferenceXObject.getObject();
+                aContents.append("q ");
+                appendDouble(aRect.GetWidth() * fScale, aContents);
+                aContents.append(" 0 0 ");
+                appendDouble(aRect.GetHeight() * fScale, aContents);
                 aContents.append(
-                    "q "
-                    + OString::number(aRect.GetWidth())
-                    + " 0 0 "
-                    + OString::number(aRect.GetHeight())
                     + " "
                     + OString::number(aRect.getX())
                     + " "

Reply via email to