vcl/inc/impglyphitem.hxx        |    1 +
 vcl/source/gdi/impglyphitem.cxx |   30 ++++++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

New commits:
commit 5caa7f44b861876afa5b3b8f71e3848abd8875e6
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Wed May 11 16:32:52 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Wed May 11 19:00:42 2022 +0200

    fix HB_GLYPH_FLAG_UNSAFE_TO_BREAK for RTL in cloneCharRange() (tdf#148954)
    
    I got the meaning wrong, when the docs talk about beginning of a cluster,
    that refers to text, not glyphs, so this needs to be backwards too.
    
    Change-Id: I12ef775b033100405e3332d5611844cefb6b5a85
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134173
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/vcl/inc/impglyphitem.hxx b/vcl/inc/impglyphitem.hxx
index e86c2652100a..18764cede500 100644
--- a/vcl/inc/impglyphitem.hxx
+++ b/vcl/inc/impglyphitem.hxx
@@ -153,6 +153,7 @@ public:
 #endif
 
 private:
+    bool isSafeToBreak(const_iterator pos, bool rtl) const;
     rtl::Reference<LogicalFontInstance> m_rFontInstance;
     SalLayoutFlags mnFlags = SalLayoutFlags::NONE;
 };
diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx
index 43f102102210..648696a55107 100644
--- a/vcl/source/gdi/impglyphitem.cxx
+++ b/vcl/source/gdi/impglyphitem.cxx
@@ -128,9 +128,7 @@ SalLayoutGlyphsImpl* 
SalLayoutGlyphsImpl::cloneCharRange(sal_Int32 index, sal_In
     // (for non-RTL charPos is always the start of a multi-character glyph).
     if (rtl && pos->charPos() + pos->charCount() > beginPos + 1)
         return nullptr;
-    // Don't create a subset if it's not safe to break at the beginning or end 
of the sequence
-    // (https://harfbuzz.github.io/harfbuzz-hb-buffer.html#hb-glyph-flags-t).
-    if (pos->IsUnsafeToBreak() || (pos->IsInCluster() && 
!pos->IsClusterStart()))
+    if (!isSafeToBreak(pos, rtl))
         return nullptr;
     // LinearPos needs adjusting to start at xOffset/yOffset for the first 
item,
     // that's how it's computed in GenericSalLayout::LayoutText().
@@ -163,7 +161,7 @@ SalLayoutGlyphsImpl* 
SalLayoutGlyphsImpl::cloneCharRange(sal_Int32 index, sal_In
         // that we're not cutting in the middle of a multi-character glyph.
         if (rtl ? pos->charPos() + pos->charCount() != endPos + 1 : 
pos->charPos() != endPos)
             return nullptr;
-        if (pos->IsUnsafeToBreak() || (pos->IsInCluster() && 
!pos->IsClusterStart()))
+        if (!isSafeToBreak(pos, rtl))
             return nullptr;
     }
     // HACK: If mode is se to be RTL, but the last glyph is a non-RTL space,
@@ -179,6 +177,30 @@ SalLayoutGlyphsImpl* 
SalLayoutGlyphsImpl::cloneCharRange(sal_Int32 index, sal_In
     return copy.release();
 }
 
+bool SalLayoutGlyphsImpl::isSafeToBreak(const_iterator pos, bool rtl) const
+{
+    if (rtl)
+    {
+        // RTL is more complicated, because HB_GLYPH_FLAG_UNSAFE_TO_BREAK 
talks about beginning
+        // of a cluster, which refers to the text, not glyphs. This function 
is called
+        // for the first glyph of the subset and the first glyph after the 
subset, but since
+        // the glyphs are backwards, and we need the beginning of cluster at 
the start of the text
+        // and beginning of the cluster after the text, we need to check 
glyphs before this position.
+        if (pos == begin())
+            return true;
+        --pos;
+        while (pos >= begin() && (pos->IsInCluster() && 
!pos->IsClusterStart()))
+            --pos;
+        if (pos < begin())
+            return true;
+    }
+    // Don't create a subset if it's not safe to break at the beginning or end 
of the sequence
+    // (https://harfbuzz.github.io/harfbuzz-hb-buffer.html#hb-glyph-flags-t).
+    if (pos->IsUnsafeToBreak() || (pos->IsInCluster() && 
!pos->IsClusterStart()))
+        return false;
+    return true;
+}
+
 #ifdef DBG_UTIL
 bool SalLayoutGlyphsImpl::isEqual(const SalLayoutGlyphsImpl* other) const
 {

Reply via email to