vcl/source/gdi/CommonSalLayout.cxx |   22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

New commits:
commit fcd817175711137c49793018dc9761f13326c863
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Thu Jun 26 00:56:54 2025 +0300
Commit:     Khaled Hosny <kha...@libreoffice.org>
CommitDate: Sat Jun 28 16:22:08 2025 +0200

    tdf#126111: Don’t do glyph fallback for PUA codepoints
    
    Private Use Area codepoints are codepoints that Unicode reserves for
    private use, so they are typically tied to a specific font and a PUA
    code point in a different font can be a totally different symbol, so
    applying glyph fallback here is unlikely to give a sensible result.
    
    The bug documents in question misuse PUA codepoints not supported by the
    requested font to get an empty box (the font’s .notdef glyph), which
    would only happens if no glyph fallabck is done (or no font on the
    system supports this PUA code point).
    
    This fixes only the case when requested font is present and we do glyph
    fallback. If the requested font is missing, then we might still get PUA
    glyphs from the fallback font.
    
    Change-Id: I4688d098b40263e83bc9f2df1833cdc6286b7092
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187012
    Tested-by: Jenkins
    Reviewed-by: Khaled Hosny <kha...@libreoffice.org>

diff --git a/vcl/source/gdi/CommonSalLayout.cxx 
b/vcl/source/gdi/CommonSalLayout.cxx
index b40851a2f18c..e6ec3a176ce5 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -369,8 +369,16 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
         m_GlyphItems = *pGlyphs;
 
         for(const GlyphItem& item : m_GlyphItems)
+        {
             if(!item.glyphId())
-                aFallbackRuns.AddPos(item.charPos(), item.IsRTLGlyph());
+            {
+                sal_Int32 nCurrCharPos = item.charPos();
+                auto aCurrChar = rArgs.mrStr.iterateCodePoints(&nCurrCharPos, 
0);
+                // tdf#126111: fallback is meaningless for PUA codepoints
+                if (u_charType(aCurrChar) != U_PRIVATE_USE_CHAR)
+                    aFallbackRuns.AddPos(item.charPos(), item.IsRTLGlyph());
+            }
+        }
 
         for (const auto& rRun : aFallbackRuns)
         {
@@ -742,9 +750,15 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
                     if (nOrigCharPos >= rArgs.mnDrawMinCharPos
                         && nOrigCharPos < rArgs.mnDrawEndCharPos)
                     {
-                        aFallbackRuns.AddPos(nOrigCharPos, bRightToLeft);
-                        if (SalLayoutFlags::ForFallback & rArgs.mnFlags)
-                            continue;
+                        sal_Int32 nCurrCharPos = nOrigCharPos;
+                        auto aCurrChar = 
rArgs.mrStr.iterateCodePoints(&nCurrCharPos, 0);
+                        // tdf#126111: fallback is meaningless for PUA 
codepoints
+                        if (u_charType(aCurrChar) != U_PRIVATE_USE_CHAR)
+                        {
+                            aFallbackRuns.AddPos(nOrigCharPos, bRightToLeft);
+                            if (SalLayoutFlags::ForFallback & rArgs.mnFlags)
+                                continue;
+                        }
                     }
                 }
 

Reply via email to