diff options
-rw-r--r-- | include/vcl/outdev.hxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/impglyphitem.cxx | 27 | ||||
-rw-r--r-- | vcl/source/outdev/text.cxx | 53 |
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() |