28#include <officecfg/Office/Common.hxx>
30#include <unicode/ubidi.h>
31#include <unicode/uchar.h>
40 std::swap(
m_pImpl, rOther.m_pImpl);
41 std::swap(m_pExtraImpls, rOther.m_pExtraImpls);
48 std::swap(
m_pImpl, rOther.m_pImpl);
49 std::swap(m_pExtraImpls, rOther.m_pExtraImpls);
90 m_pExtraImpls.reset(
new std::vector<std::unique_ptr<SalLayoutGlyphsImpl>>);
104 return copy.release();
105 bool rtl = front().IsRTLGlyph();
115 sal_Int32 beginPos =
index;
125 pos = std::partition_point(
131 pos = std::partition_point(
137 if (
pos->charPos() != beginPos)
141 if (
rtl &&
pos->charPos() +
pos->charCount() > beginPos + 1)
156 && (
rtl ?
pos->charPos() -
pos->charCount() >= endPos
157 :
pos->charPos() +
pos->charCount() <= endPos))
159 if (
pos->IsRTLGlyph() !=
rtl)
164 if (
pos->charCount() == 0 &&
pos->origWidth() == 0)
167 copy->back().setLinearPos(
copy->back().linearPos() - zeroPoint);
174 if (
rtl ?
pos->charPos() +
pos->charCount() != endPos + 1 :
pos->charPos() != endPos)
179 return copy.release();
197 if (
pos->IsUnsafeToBreak() || (
pos->IsInCluster() && !
pos->IsClusterStart()))
205 if (!
GetFont()->mxFontMetric->CompareDeviceIndependentFontAttributes(
206 *other->
GetFont()->mxFontMetric))
210 if (empty() || other->empty())
211 return empty() == other->empty();
212 if (
size() != other->size())
216 if (!(*
this)[
pos].isLayoutEquivalent((*other)[
pos]))
236 ? officecfg::Office::Common::Cache::Font::GlyphsCacheSize::get()
241static UBiDiDirection
getBiDiDirection(
const OUString& text, sal_Int32 index, sal_Int32 len)
247 UBiDiDirection direction = UBIDI_NEUTRAL;
250 switch (u_charDirection(
text.iterateCodePoints(&
index)))
253 case U_LEFT_TO_RIGHT:
254 if (direction == UBIDI_RTL)
256 direction = UBIDI_LTR;
258 case U_RIGHT_TO_LEFT:
259 case U_RIGHT_TO_LEFT_ARABIC:
260 if (direction == UBIDI_LTR)
262 direction = UBIDI_RTL;
273 sal_Int32 index, sal_Int32 len)
280 if (direction == UBIDI_MIXED)
283 for (
int level = 0;; ++level)
286 if (sourceLevel ==
nullptr)
289 if ((direction == UBIDI_LTR && sourceRtl) || (direction == UBIDI_RTL && !sourceRtl))
293 if (cloned ==
nullptr)
308 for (
int level = 0;; ++level)
312 if (l1 ==
nullptr || l2 ==
nullptr)
324 sal_Int32 nIndex, sal_Int32 nLen,
tools::Long nLogicWidth,
337 if (it->second.IsValid())
344 bool resetLastSubstringKey =
true;
347 bool skipGlyphSubsets
349 if ((
nIndex != 0 || nLen !=
text.getLength()) && !skipGlyphSubsets)
376 static const bool bAbortOnFontSubstitute = [] {
377 const char* pEnv = getenv(
"SAL_NON_APPLICATION_FONT_USE");
378 return pEnv && strcmp(pEnv,
"abort") == 0;
400 resetLastSubstringKey =
false;
412 std::shared_ptr<const vcl::text::TextLayoutCache> tmpLayoutCache;
413 if (layoutCache ==
nullptr)
416 layoutCache = tmpLayoutCache.get();
420 std::unique_ptr<SalLayout> layout
430 if (resetLastSubstringKey)
439 std::shared_ptr<const vcl::text::TextLayoutCache> tmpLayoutCache;
440 if (layoutCache ==
nullptr)
443 layoutCache = tmpLayoutCache.get();
445 std::unique_ptr<SalLayout> layout
488 , fontMetric(outputDevice->GetFontMetric())
493 , mapMode(outputDevice->GetMapMode())
494 ,
rtl(outputDevice->IsRTLEnabled())
495 , layoutMode(outputDevice->GetLayoutMode())
496 , digitLanguage(outputDevice->GetDigitLanguage())
536 && fontMetric.EqualIgnoreColor(other.
fontMetric)
544 for (
int level = 0;; ++level)
550 cost +=
sizeof(*impl);
551 cost +=
impl->size() *
sizeof(
impl->front());
FontPitch GetPitch() const
size_t GetHashValueIgnoreColor() const
bool NeedsArtificialBold() const
void GetScale(double *nXScale, double *nYScale) const
bool NeedsArtificialItalic() const
const vcl::font::FontSelectPattern & GetFontSelectPattern() const
size_t GetHashValue() const
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
LogicalFontInstance const * GetFontInstance() const
SAL_DLLPRIVATE SalLayoutFlags GetBiDiLayoutFlags(std::u16string_view rStr, const sal_Int32 nMinIndex, const sal_Int32 nEndIndex) const
vcl::text::ComplexTextLayoutFlags GetLayoutMode() const
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), tools::Long nLogicWidth=0, KernArraySpan aKernArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::text::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
A cache for SalLayoutGlyphs objects.
std::optional< CachedGlyphsKey > mLastTemporaryKey
void SetCacheGlyphsWhenDoingFallbackFonts(bool bOK)
Normally, we cannot cache glyphs when doing font fallback, because the font fallbacks can cache durin...
SalLayoutGlyphs mLastTemporaryGlyphs
static SalLayoutGlyphsCache * self()
std::optional< CachedGlyphsKey > mLastSubstringKey
bool mbCacheGlyphsWhenDoingFallbackFonts
const SalLayoutGlyphs * GetLayoutGlyphs(VclPtr< const OutputDevice > outputDevice, const OUString &text, const vcl::text::TextLayoutCache *layoutCache=nullptr)
GlyphsCache mCachedGlyphs
SalLayoutGlyphsImpl(LogicalFontInstance &rFontInstance)
void SetFlags(SalLayoutFlags flags)
SalLayoutFlags GetFlags() const
rtl::Reference< LogicalFontInstance > m_rFontInstance
SalLayoutGlyphsImpl * clone() const
bool isSafeToBreak(const_iterator pos, bool rtl) const
bool isLayoutEquivalent(const SalLayoutGlyphsImpl *other) const
SalLayoutGlyphsImpl * cloneCharRange(sal_Int32 index, sal_Int32 length) const
const rtl::Reference< LogicalFontInstance > & GetFont() const
SalLayoutGlyphsImpl * Impl(unsigned int nLevel) const
void AppendImpl(SalLayoutGlyphsImpl *pImpl)
SalLayoutGlyphs & operator=(const SalLayoutGlyphs &)=delete
std::unique_ptr< SalLayoutGlyphsImpl > m_pImpl
std::unique_ptr< std::vector< std::unique_ptr< SalLayoutGlyphsImpl > > > m_pExtraImpls
reference_type * get() const
Get the body.
void insert(key_value_pair_t &rPair)
list_const_iterator_t const_iterator
list_const_iterator_t end() const
list_const_iterator_t begin() const
list_const_iterator_t find(const Key &key)
const OUString & GetFamilyName() const
static std::shared_ptr< const vcl::text::TextLayoutCache > Create(OUString const &)
basegfx::B2DPoint DevicePoint
static SalLayoutGlyphs makeGlyphsSubset(const SalLayoutGlyphs &source, const OutputDevice *outputDevice, const OUString &text, sal_Int32 index, sal_Int32 len)
static UBiDiDirection getBiDiDirection(const OUString &text, sal_Int32 index, sal_Int32 len)
static void checkGlyphsEqual(const SalLayoutGlyphs &g1, const SalLayoutGlyphs &g2)
void copy(const fs::path &src, const fs::path &dest)
std::enable_if_t<(sizeof(N)==4)> hash_combine(N &nSeed, T const *pValue, size_t nCount)
enumrange< T >::Iterator begin(enumrange< T >)
bool operator==(const CachedGlyphsKey &other) const
vcl::text::ComplexTextLayoutFlags layoutMode
LanguageType digitLanguage
CachedGlyphsKey(const VclPtr< const OutputDevice > &dev, OUString t, sal_Int32 i, sal_Int32 l, tools::Long w)
size_t operator()(const SalLayoutGlyphs &) const
UNDERLYING_TYPE get() const