svx/source/svdraw/svdpdf.cxx | 111 +++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 35 deletions(-)
New commits: commit fb506617849091789ba72a335e1448f8776cfde7 Author: Caolán McNamara <[email protected]> AuthorDate: Wed Oct 15 19:36:28 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Sun Oct 26 12:06:47 2025 +0100 provide fallback toUnicode using name key via Adobe Standard Change-Id: I0ad9fd6b868bf00d3e98c41ff63589648db579e9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192462 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192984 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 0229846f7faf..9f3811a91473 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1272,6 +1272,7 @@ struct ToUnicodeData std::vector<OString> bfcharlines; std::vector<OString> bfcharranges; + // For the pdf provided mapping from the font to unicode ToUnicodeData(const std::vector<uint8_t>& toUnicodeData) { SvMemoryStream aInCMap(const_cast<uint8_t*>(toUnicodeData.data()), toUnicodeData.size(), @@ -1300,20 +1301,41 @@ struct ToUnicodeData } } } + + // For name keyed fonts without toUnicode data where we + // can assume the font encoding is Adobe Standard and + // reverse map from the name indexes so we can forward + // map to unicode + ToUnicodeData(std::map<int, int>& nameIndexToGlyph) + { + for (const auto & [ adobe, glyphid ] : nameIndexToGlyph) + { + if (glyphid == 0) + continue; + + const char cChar(adobe); + OUString sUni(&cChar, 1, RTL_TEXTENCODING_ADOBE_STANDARD); + sal_Unicode mappedChar = sUni.toChar(); + + OStringBuffer aBuffer("<"); + appendFourByteHex(aBuffer, adobe); + aBuffer.append("> <"); + appendFourByteHex(aBuffer, mappedChar); + aBuffer.append(">"); + bfcharlines.push_back(aBuffer.toString()); + } + } }; } static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features, - std::string_view FontName, - const std::vector<uint8_t>& toUnicodeData, bool bNameKeyed, + std::string_view FontName, ToUnicodeData& tud, bool bNameKeyed, std::map<int, int>& nameIndexToGlyph, SubSetInfo& rSubSetInfo) { SvFileStream CMap(CMapUrl, StreamMode::READWRITE | StreamMode::TRUNC); CMap.WriteBytes(cmapprefix, std::size(cmapprefix) - 1); - ToUnicodeData tud(toUnicodeData); - sal_Int32 mergeOffset = 1; //Leave space for notdef for (const auto& count : rSubSetInfo.aComponents) mergeOffset += count.nGlyphCount; @@ -1689,8 +1711,16 @@ EmbeddedFontInfo ImpSdrPdfImport::convertToOTF(sal_Int64 prefix, SubSetInfo& rSu bool bCMap = true; if (!toUnicodeData.empty()) { - buildCMapAndFeatures(CMapUrl, Features, FontName, toUnicodeData, bNameKeyed, - nameIndexToGlyph, rSubSetInfo); + ToUnicodeData tud(toUnicodeData); + buildCMapAndFeatures(CMapUrl, Features, FontName, tud, bNameKeyed, nameIndexToGlyph, + rSubSetInfo); + } + else if (bNameKeyed) + { + SAL_INFO("sd.filter", "There is no CMap, assuming Adobe Standard encoding."); + ToUnicodeData tud(nameIndexToGlyph); + buildCMapAndFeatures(CMapUrl, Features, FontName, tud, bNameKeyed, nameIndexToGlyph, + rSubSetInfo); } else { commit c93df20557dfa41b91356d01b49ecbc6e69d0975 Author: Caolán McNamara <[email protected]> AuthorDate: Wed Oct 15 17:27:08 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Sun Oct 26 12:06:38 2025 +0100 split out current use as new class and ctor Change-Id: Ifb387d6d1a00aa5c1338a37f08349efe2116aa3a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192461 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192983 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> diff --git a/svx/source/svdraw/svdpdf.cxx b/svx/source/svdraw/svdpdf.cxx index 0e2e61a78111..0229846f7faf 100644 --- a/svx/source/svdraw/svdpdf.cxx +++ b/svx/source/svdraw/svdpdf.cxx @@ -1265,43 +1265,54 @@ const char cmapsuffix[] = "endcmap " "end " "end "; -static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features, - std::string_view FontName, - const std::vector<uint8_t>& toUnicodeData, bool bNameKeyed, - std::map<int, int>& nameIndexToGlyph, SubSetInfo& rSubSetInfo) +namespace +{ +struct ToUnicodeData { - SvFileStream CMap(CMapUrl, StreamMode::READWRITE | StreamMode::TRUNC); - - CMap.WriteBytes(cmapprefix, std::size(cmapprefix) - 1); - - SvMemoryStream aInCMap(const_cast<uint8_t*>(toUnicodeData.data()), toUnicodeData.size(), - StreamMode::READ); - std::vector<OString> bfcharlines; std::vector<OString> bfcharranges; - OString sLine; - while (aInCMap.ReadLine(sLine)) + ToUnicodeData(const std::vector<uint8_t>& toUnicodeData) { - if (sLine.endsWith("beginbfchar")) + SvMemoryStream aInCMap(const_cast<uint8_t*>(toUnicodeData.data()), toUnicodeData.size(), + StreamMode::READ); + + OString sLine; + while (aInCMap.ReadLine(sLine)) { - while (aInCMap.ReadLine(sLine)) + if (sLine.endsWith("beginbfchar")) { - if (sLine.endsWith("endbfchar")) - break; - bfcharlines.push_back(sLine); + while (aInCMap.ReadLine(sLine)) + { + if (sLine.endsWith("endbfchar")) + break; + bfcharlines.push_back(sLine); + } } - } - else if (sLine.endsWith("beginbfrange")) - { - while (aInCMap.ReadLine(sLine)) + else if (sLine.endsWith("beginbfrange")) { - if (sLine.endsWith("endbfrange")) - break; - bfcharranges.push_back(sLine); + while (aInCMap.ReadLine(sLine)) + { + if (sLine.endsWith("endbfrange")) + break; + bfcharranges.push_back(sLine); + } } } } +}; +} + +static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features, + std::string_view FontName, + const std::vector<uint8_t>& toUnicodeData, bool bNameKeyed, + std::map<int, int>& nameIndexToGlyph, SubSetInfo& rSubSetInfo) +{ + SvFileStream CMap(CMapUrl, StreamMode::READWRITE | StreamMode::TRUNC); + + CMap.WriteBytes(cmapprefix, std::size(cmapprefix) - 1); + + ToUnicodeData tud(toUnicodeData); sal_Int32 mergeOffset = 1; //Leave space for notdef for (const auto& count : rSubSetInfo.aComponents) @@ -1310,11 +1321,11 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features std::map<sal_Int32, OString> ligatureGlyphToChars; std::vector<sal_Int32> glyphs; - if (!bfcharranges.empty()) + if (!tud.bfcharranges.empty()) { std::vector<OString> cidranges; - for (const auto& charrange : bfcharranges) + for (const auto& charrange : tud.bfcharranges) { assert(charrange[0] == '<'); sal_Int32 nEnd = charrange.indexOf('>', 1); @@ -1340,7 +1351,7 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features OStringBuffer aBuffer("<"); appendFourByteHex(aBuffer, nGlyphRangeStart); aBuffer.append("> " + sChars); - bfcharlines.push_back(aBuffer.toString()); + tud.bfcharlines.push_back(aBuffer.toString()); continue; } @@ -1360,7 +1371,7 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features aBuffer.append("> <"); appendFourByteHex(aBuffer, nCharRangeStart); aBuffer.append(">"); - bfcharlines.push_back(aBuffer.toString()); + tud.bfcharlines.push_back(aBuffer.toString()); continue; } @@ -1387,11 +1398,11 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features } } - if (!bfcharlines.empty()) + if (!tud.bfcharlines.empty()) { - OString beginline = OString::number(bfcharlines.size()) + " begincidchar"; + OString beginline = OString::number(tud.bfcharlines.size()) + " begincidchar"; CMap.WriteLine(beginline); - for (const auto& charline : bfcharlines) + for (const auto& charline : tud.bfcharlines) { assert(charline[0] == '<'); sal_Int32 nEnd = charline.indexOf('>', 1); @@ -1421,7 +1432,7 @@ static void buildCMapAndFeatures(const OUString& CMapUrl, SvFileStream& Features } CMap.WriteLine("endcidchar"); - rSubSetInfo.aComponents.back().nGlyphCount = bfcharlines.size(); + rSubSetInfo.aComponents.back().nGlyphCount = tud.bfcharlines.size(); } CMap.WriteBytes(cmapsuffix, std::size(cmapsuffix) - 1);
