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; }
