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

Reply via email to