28#include <officecfg/Office/Common.hxx>
31#include <unicode/ubidi.h>
32#include <unicode/uchar.h>
41 std::swap(
m_pImpl, rOther.m_pImpl);
42 std::swap(m_pExtraImpls, rOther.m_pExtraImpls);
49 std::swap(
m_pImpl, rOther.m_pImpl);
50 std::swap(m_pExtraImpls, rOther.m_pExtraImpls);
91 m_pExtraImpls.reset(
new std::vector<std::unique_ptr<SalLayoutGlyphsImpl>>);
105 return copy.release();
106 bool rtl = front().IsRTLGlyph();
116 sal_Int32 beginPos =
index;
126 pos = std::partition_point(
132 pos = std::partition_point(
138 if (
pos->charPos() != beginPos)
143 if (
rtl && (
pos->charPos() +
pos->charCount() > beginPos + 1 ||
pos->IsInCluster()))
159 && (
rtl ?
pos->charPos() -
pos->charCount() >= endPos
160 :
pos->charPos() +
pos->charCount() <= endPos))
162 if (
pos->IsRTLGlyph() !=
rtl)
167 if (
pos->charCount() == 0 &&
pos->origWidth() == 0)
170 copy->back().setLinearPos(
copy->back().linearPos() - zeroPoint);
177 if (
rtl ?
pos->charPos() +
pos->charCount() != endPos + 1 :
pos->charPos() != endPos)
182 return copy.release();
200 if (
pos->IsUnsafeToBreak() || (
pos->IsInCluster() && !
pos->IsClusterStart()))
208 if (!
GetFont()->mxFontMetric->CompareDeviceIndependentFontAttributes(
209 *other->
GetFont()->mxFontMetric))
213 if (empty() || other->empty())
214 return empty() == other->empty();
215 if (
size() != other->size())
219 if (!(*
this)[
pos].isLayoutEquivalent((*other)[
pos]))
239 ? officecfg::Office::Common::Cache::Font::GlyphsCacheSize::get()
244static UBiDiDirection
getBiDiDirection(std::u16string_view text, sal_Int32 index, sal_Int32 len)
250 UBiDiDirection direction = UBIDI_NEUTRAL;
256 case U_LEFT_TO_RIGHT:
257 if (direction == UBIDI_RTL)
259 direction = UBIDI_LTR;
261 case U_RIGHT_TO_LEFT:
262 case U_RIGHT_TO_LEFT_ARABIC:
263 if (direction == UBIDI_LTR)
265 direction = UBIDI_RTL;
275 const OutputDevice* outputDevice, std::u16string_view text,
276 sal_Int32 index, sal_Int32 len)
283 if (direction == UBIDI_MIXED)
286 for (
int level = 0;; ++level)
289 if (sourceLevel ==
nullptr)
292 if ((direction == UBIDI_LTR && sourceRtl) || (direction == UBIDI_RTL && !sourceRtl))
296 if (cloned ==
nullptr)
311 for (
int level = 0;; ++level)
315 if (l1 ==
nullptr || l2 ==
nullptr)
327 sal_Int32 nIndex, sal_Int32 nLen,
tools::Long nLogicWidth,
336 if (it->second.IsValid())
343 bool resetLastSubstringKey =
true;
346 bool skipGlyphSubsets
348 if ((
nIndex != 0 || nLen !=
text.getLength()) && !skipGlyphSubsets)
375 static const bool bAbortOnFontSubstitute = [] {
376 const char* pEnv = getenv(
"SAL_NON_APPLICATION_FONT_USE");
377 return pEnv && strcmp(pEnv,
"abort") == 0;
399 resetLastSubstringKey =
false;
411 std::shared_ptr<const vcl::text::TextLayoutCache> tmpLayoutCache;
412 if (layoutCache ==
nullptr)
415 layoutCache = tmpLayoutCache.get();
419 std::unique_ptr<SalLayout> layout
429 if (resetLastSubstringKey)
438 std::shared_ptr<const vcl::text::TextLayoutCache> tmpLayoutCache;
439 if (layoutCache ==
nullptr)
442 layoutCache = tmpLayoutCache.get();
444 std::unique_ptr<SalLayout> layout
487 , fontMetric(outputDevice->GetFontMetric())
492 , mapMode(outputDevice->GetMapMode())
493 ,
rtl(outputDevice->IsRTLEnabled())
494 , layoutMode(outputDevice->GetLayoutMode())
495 , digitLanguage(outputDevice->GetDigitLanguage())
535 && fontMetric.EqualIgnoreColor(other.
fontMetric)
543 for (
int level = 0;; ++level)
549 cost +=
sizeof(*impl);
550 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)
static std::shared_ptr< const vcl::text::TextLayoutCache > Create(OUString const &)
static SalLayoutGlyphs makeGlyphsSubset(const SalLayoutGlyphs &source, const OutputDevice *outputDevice, std::u16string_view text, sal_Int32 index, sal_Int32 len)
static void checkGlyphsEqual(const SalLayoutGlyphs &g1, const SalLayoutGlyphs &g2)
static UBiDiDirection getBiDiDirection(std::u16string_view text, sal_Int32 index, sal_Int32 len)
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 >)
sal_uInt32 iterateCodePoints(std::u16string_view string, sal_Int32 *indexUtf16, sal_Int32 incrementCodePoints=1)
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