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 {