summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-04-27 12:27:52 +0200
committerLuboš Luňák <l.lunak@collabora.com>2022-04-27 22:45:52 +0200
commit3a407fc49490a348a8147a59dae242aa21708c31 (patch)
tree01abb84df8af57665e099aa30629b91c87a9a1f0
parent6d36d7185b025c77db9dcccea1861d37dd6bcc1b (diff)
make SalLayoutFlags match after makeGlyphsSubset()
SalLayoutFlags::BiDiStrong would be set by ImplLayout() if the entire subset had no RTL, but the entire string may not be that, so when creating a subset make sure to also set this flag. Similarly SalLayoutFlags::KashidaJustification should be set only if any glyph in the range has GlyphItemFlags::ALLOW_KASHIDA. Change-Id: I0aa2526f2fdd0c6a6b905ad0cb4040ee556529a8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133502 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--include/vcl/outdev.hxx4
-rw-r--r--vcl/source/gdi/impglyphitem.cxx27
-rw-r--r--vcl/source/outdev/text.cxx53
3 files changed, 59 insertions, 25 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 7dacb68d55ad..bf4985622fad 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -1078,6 +1078,10 @@ public:
const SalLayoutGlyphs* pGlyphs = nullptr) const;
static std::shared_ptr<const vcl::text::TextLayoutCache> CreateTextLayoutCache(OUString const&);
+ SAL_DLLPRIVATE SalLayoutFlags GetBiDiLayoutFlags( std::u16string_view rStr,
+ const sal_Int32 nMinIndex,
+ const sal_Int32 nEndIndex ) const;
+
protected:
SAL_DLLPRIVATE void ImplInitTextLineSize();
SAL_DLLPRIVATE void ImplInitAboveTextLineSize();
diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx
index 83c044ce176c..5c4acbc6859c 100644
--- a/vcl/source/gdi/impglyphitem.cxx
+++ b/vcl/source/gdi/impglyphitem.cxx
@@ -164,8 +164,9 @@ SalLayoutGlyphsCache* SalLayoutGlyphsCache::self()
return cache.get();
}
-static SalLayoutGlyphs makeGlyphsSubset(const SalLayoutGlyphs& source, sal_Int32 index,
- sal_Int32 len)
+static SalLayoutGlyphs makeGlyphsSubset(const SalLayoutGlyphs& source,
+ const OutputDevice* outputDevice, std::u16string_view text,
+ sal_Int32 index, sal_Int32 len)
{
SalLayoutGlyphs ret;
for (int level = 0;; ++level)
@@ -177,6 +178,25 @@ static SalLayoutGlyphs makeGlyphsSubset(const SalLayoutGlyphs& source, sal_Int32
// If the glyphs range cannot be cloned, bail out.
if (cloned == nullptr)
return SalLayoutGlyphs();
+ // If the entire string is mixed LTR/RTL but the subset is only LTR,
+ // then make sure the flags match that, otherwise checkGlyphsEqual()
+ // would assert on flags being different.
+ cloned->SetFlags(cloned->GetFlags()
+ | outputDevice->GetBiDiLayoutFlags(text, index, index + len));
+ // SalLayoutFlags::KashidaJustification is set only if any glyph
+ // in the range has GlyphItemFlags::ALLOW_KASHIDA (otherwise unset it).
+ bool hasKashida = false;
+ for (const GlyphItem& item : *cloned)
+ {
+ if (item.AllowKashida())
+ {
+ assert(cloned->GetFlags() & SalLayoutFlags::KashidaJustification);
+ hasKashida = true;
+ break;
+ }
+ }
+ if (!hasKashida)
+ cloned->SetFlags(cloned->GetFlags() & ~SalLayoutFlags::KashidaJustification);
ret.AppendImpl(cloned);
}
return ret;
@@ -236,7 +256,8 @@ SalLayoutGlyphsCache::GetLayoutGlyphs(VclPtr<const OutputDevice> outputDevice, c
GlyphsCache::const_iterator itWhole = mCachedGlyphs.find(keyWhole);
if (itWhole != mCachedGlyphs.end() && itWhole->second.IsValid())
{
- mLastTemporaryGlyphs = makeGlyphsSubset(itWhole->second, nIndex, nLen);
+ mLastTemporaryGlyphs
+ = makeGlyphsSubset(itWhole->second, outputDevice, text, nIndex, nLen);
if (mLastTemporaryGlyphs.IsValid())
{
mLastTemporaryKey = std::move(key);
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 840341502beb..7d3662d0604d 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -1170,28 +1170,7 @@ vcl::text::ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
if( nEndIndex < nMinIndex )
nEndIndex = nMinIndex;
- if( mnTextLayoutMode & vcl::text::ComplexTextLayoutFlags::BiDiRtl )
- nLayoutFlags |= SalLayoutFlags::BiDiRtl;
- if( mnTextLayoutMode & vcl::text::ComplexTextLayoutFlags::BiDiStrong )
- nLayoutFlags |= SalLayoutFlags::BiDiStrong;
- else if( !(mnTextLayoutMode & vcl::text::ComplexTextLayoutFlags::BiDiRtl) )
- {
- // Disable Bidi if no RTL hint and only known LTR codes used.
- bool bAllLtr = true;
- for (sal_Int32 i = nMinIndex; i < nEndIndex; i++)
- {
- // [0x0000, 0x052F] are Latin, Greek and Cyrillic.
- // [0x0370, 0x03FF] has a few holes as if Unicode 10.0.0, but
- // hopefully no RTL character will be encoded there.
- if (rStr[i] > 0x052F)
- {
- bAllLtr = false;
- break;
- }
- }
- if (bAllLtr)
- nLayoutFlags |= SalLayoutFlags::BiDiStrong;
- }
+ nLayoutFlags |= GetBiDiLayoutFlags( rStr, nMinIndex, nEndIndex );
if( !maFont.IsKerning() )
nLayoutFlags |= SalLayoutFlags::DisableKerning;
@@ -1251,6 +1230,36 @@ vcl::text::ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
return aLayoutArgs;
}
+SalLayoutFlags OutputDevice::GetBiDiLayoutFlags( std::u16string_view rStr,
+ const sal_Int32 nMinIndex,
+ const sal_Int32 nEndIndex ) const
+{
+ SalLayoutFlags nLayoutFlags = SalLayoutFlags::NONE;
+ if( mnTextLayoutMode & vcl::text::ComplexTextLayoutFlags::BiDiRtl )
+ nLayoutFlags |= SalLayoutFlags::BiDiRtl;
+ if( mnTextLayoutMode & vcl::text::ComplexTextLayoutFlags::BiDiStrong )
+ nLayoutFlags |= SalLayoutFlags::BiDiStrong;
+ else if( !(mnTextLayoutMode & vcl::text::ComplexTextLayoutFlags::BiDiRtl) )
+ {
+ // Disable Bidi if no RTL hint and only known LTR codes used.
+ bool bAllLtr = true;
+ for (sal_Int32 i = nMinIndex; i < nEndIndex; i++)
+ {
+ // [0x0000, 0x052F] are Latin, Greek and Cyrillic.
+ // [0x0370, 0x03FF] has a few holes as if Unicode 10.0.0, but
+ // hopefully no RTL character will be encoded there.
+ if (rStr[i] > 0x052F)
+ {
+ bAllLtr = false;
+ break;
+ }
+ }
+ if (bAllLtr)
+ nLayoutFlags |= SalLayoutFlags::BiDiStrong;
+ }
+ return nLayoutFlags;
+}
+
static OutputDevice::FontMappingUseData* fontMappingUseData = nullptr;
static inline bool IsTrackingFontMappingUse()