svx/source/svdraw/svdpdf.cxx |   62 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 51 insertions(+), 11 deletions(-)

New commits:
commit 1b8060117c4a853f5c33d99d31915b5688e8edb9
Author:     Caolán McNamara <[email protected]>
AuthorDate: Tue Oct 21 21:07:28 2025 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Wed Oct 22 14:43:17 2025 +0200

    stash and elide global font matrix and overwrite local one with it
    
    rather than let both of them pass through, where conversion to
    otf of input with:
    
    /FontMatrix [0.0005 0 0 0.0005 0 0] def
    ...
    ...
    %ADOBeginFontDict
    ...
    /FontMatrix [1 0 0 1 0 0] def
    
    otherwise then results in output of otf with UnitsPerEm of 1 which then
    freetype rejects as invalid and so nothing is rendered.
    
    Change-Id: I037a2bea1b1caf5259af40c59cc529afe63db998
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192809
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx
index 4d1bf340573e..5d10a93302b1 100644
--- a/svx/source/svdraw/svdpdf.cxx
+++ b/svx/source/svdraw/svdpdf.cxx
@@ -968,8 +968,12 @@ static bool isSimpleFamilyName(std::string_view Weight)
            || Weight == "BoldItalic";
 }
 
-static void rewriteBrokenFontName(std::string_view brokenName, 
std::string_view brokenCIDName,
-                                  std::string_view fixedName, const OUString& 
pfaCIDUrl)
+// a) change brokenName/brokenCIDName if present to fixedName
+// b) remove preamble FontMatrix and overwrite following ones in the 
%ADOBeginFontDict
+// section with that content instead to avoid generating fonts with unusual 
UnitsPerEm
+// of 1 that freetype will reject
+static void rewriteFont(std::string_view brokenName, std::string_view 
brokenCIDName,
+                        std::string_view fixedName, const OUString& pfaCIDUrl)
 {
     OUString oldCIDUrl = pfaCIDUrl + ".broken";
     if (osl::File::move(pfaCIDUrl, oldCIDUrl) != osl::File::E_None)
@@ -978,6 +982,12 @@ static void rewriteBrokenFontName(std::string_view 
brokenName, std::string_view
         return;
     }
 
+    const bool rewriteNames = !brokenName.empty();
+
+    bool fontDict = false;
+
+    OString sGlobalMatrix;
+
     const OString sBrokenFontLine = "/FontName /"_ostr + brokenName + " 
def"_ostr;
     const OString sFixedFontLine = "/FontName /"_ostr + fixedName + " 
def"_ostr;
 
@@ -989,16 +999,40 @@ static void rewriteBrokenFontName(std::string_view 
brokenName, std::string_view
     OString sLine;
     while (input.ReadLine(sLine))
     {
-        if (sLine == sBrokenFontLine)
+        if (rewriteNames)
         {
-            output.WriteLine(sFixedFontLine);
-            continue;
+            if (sLine == sBrokenFontLine)
+            {
+                output.WriteLine(sFixedFontLine);
+                continue;
+            }
+            else if (sLine == sBrokenCIDFontLine)
+            {
+                output.WriteLine(sFixedCIDFontLine);
+                continue;
+            }
         }
-        else if (sLine == sBrokenCIDFontLine)
+
+        if (sLine.startsWith("%ADOBeginFontDict"))
+            fontDict = true;
+        else if (sLine.startsWith("/FontMatrix "))
         {
-            output.WriteLine(sFixedCIDFontLine);
-            continue;
+            if (!fontDict)
+            {
+                // Global case, stash and don't emit the global matrix
+                sGlobalMatrix = sLine;
+                continue;
+            }
+
+            if (!sGlobalMatrix.isEmpty())
+            {
+                // Local case, emit the global matrix instead if
+                // there was one, otherwise emit the local matrix
+                output.WriteLine(sGlobalMatrix);
+                continue;
+            }
         }
+
         output.WriteLine(sLine);
         if (sLine.startsWith("%%BeginData"))
         {
@@ -1026,7 +1060,7 @@ static bool toPfaCID(SubSetInfo& rSubSetInfo, const 
OUString& fileUrl,
     OUString toMergedMapUrl = fileUrl + u".tomergedmap";
 
     OString version, Notice, FullName, FamilyName, CIDFontName, 
CIDFontVersion, srcFontType,
-        glyphTag;
+        glyphTag, FontMatrix;
     OString brokenFontName;
     FontName = postScriptName.toUtf8();
     std::map<sal_Int32, OString> glyphIndexToName;
@@ -1066,6 +1100,8 @@ static bool toPfaCID(SubSetInfo& rSubSetInfo, const 
OUString& fileUrl,
             continue;
         if (extractEntry(sLine, "Weight", Weight))
             continue;
+        if (extractEntry(sLine, "FontMatrix", FontMatrix))
+            continue;
         if (extractEntry(sLine, "sup.srcFontType", srcFontType))
             continue;
         if (extractEntry(sLine, "## glyph[tag]", glyphTag))
@@ -1217,8 +1253,12 @@ static bool toPfaCID(SubSetInfo& rSubSetInfo, const 
OUString& fileUrl,
         }
     }
 
-    if (!brokenFontName.isEmpty())
-        rewriteBrokenFontName(brokenFontName, CIDFontName, FontName, 
pfaCIDUrl);
+    if (!brokenFontName.isEmpty() || !FontMatrix.isEmpty())
+    {
+        // If the fontname isn't as expected, or if there is a
+        // font matrix present then we rewrite the font.
+        rewriteFont(brokenFontName, CIDFontName, FontName, pfaCIDUrl);
+    }
 
     return true;
 }

Reply via email to