include/vcl/outdev.hxx | 6 ++++-- sw/source/core/txtnode/fntcache.cxx | 4 ++-- vcl/source/outdev/text.cxx | 17 ++++++++++------- 3 files changed, 16 insertions(+), 11 deletions(-)
New commits: commit e17e122b5cd33dfff37c2031d8150b145b0664f7 Author: Khaled Hosny <kha...@aliftype.com> AuthorDate: Fri Jul 11 11:34:43 2025 +0300 Commit: Khaled Hosny <kha...@libreoffice.org> CommitDate: Sat Jul 12 09:43:48 2025 +0200 Don’t calculate text bounds needlessly in OutputDevice::GetTextArray() Calculating text bounds can be a costly operation (e.g. for fonts with CFF table since it has to be calculated from outlines), and leads to loading potentially large font tables (which is especially an issue on macOS where we copy font table data when loading, unlike other platforms where HarfBuzz mmap’s the file). It seems that the text bounds are only used in one place, so this change calculates the bounds only when requested. Change-Id: Ib9017a58dda30b4cc07ceec087cbf4ad45d56d00 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187683 Tested-by: Jenkins Reviewed-by: Khaled Hosny <kha...@libreoffice.org> diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index a5dd08218c75..706b19a86481 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1056,7 +1056,8 @@ public: sal_Int32 nIndex = 0, sal_Int32 nLen = -1, bool bCaret = false, vcl::text::TextLayoutCache const* = nullptr, - SalLayoutGlyphs const* const pLayoutCache = nullptr) const; + SalLayoutGlyphs const* const pLayoutCache = nullptr, + bool bBounds = false) const; void DrawPartialTextArray(const Point& rStartPt, const OUString& rStr, KernArraySpan aKernArray, std::span<const sal_Bool> pKashidaAry, sal_Int32 nIndex, @@ -1068,7 +1069,8 @@ public: sal_Int32 nPartIndex, sal_Int32 nPartLen, bool bCaret = false, const vcl::text::TextLayoutCache* = nullptr, - const SalLayoutGlyphs* pLayoutCache = nullptr) const; + const SalLayoutGlyphs* pLayoutCache = nullptr, + bool bBounds = false) const; SAL_DLLPRIVATE void GetCaretPositions( const OUString&, KernArray& rCaretXArray, sal_Int32 nIndex, sal_Int32 nLen, diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx index c1f6c75147e0..f2b5ef476c78 100644 --- a/sw/source/core/txtnode/fntcache.cxx +++ b/sw/source/core/txtnode/fntcache.cxx @@ -765,14 +765,14 @@ static void GetTextArray(const SwDrawTextInfo& rExtraInf, const OutputDevice& rD const SalLayoutGlyphs* pLayoutCache = SalLayoutGlyphsCache::self()->GetLayoutGlyphs( &rDevice, rStr, nContextBegin, nContextLen, nIndex, nIndex + nLen, 0, layoutCache); stMetrics = rDevice.GetPartialTextArray(rStr, &rDXAry, nContextBegin, nContextLen, nIndex, - nLen, bCaret, layoutCache, pLayoutCache); + nLen, bCaret, layoutCache, pLayoutCache, true); } else { const SalLayoutGlyphs* pLayoutCache = SalLayoutGlyphsCache::self()->GetLayoutGlyphs( &rDevice, rStr, nIndex, nLen, 0, layoutCache); stMetrics - = rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, bCaret, layoutCache, pLayoutCache); + = rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, bCaret, layoutCache, pLayoutCache, true); } if (stMetrics.aBounds.has_value()) diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx index d16c776d1df4..4aac96d13d1a 100644 --- a/vcl/source/outdev/text.cxx +++ b/vcl/source/outdev/text.cxx @@ -787,17 +787,17 @@ vcl::TextArrayMetrics OutputDevice::GetTextArray(const OUString& rStr, KernArray* pKernArray, sal_Int32 nIndex, sal_Int32 nLen, bool bCaret, vcl::text::TextLayoutCache const* const pLayoutCache, - SalLayoutGlyphs const* const pSalLayoutCache) const + SalLayoutGlyphs const* const pSalLayoutCache, bool bBounds) const { return GetPartialTextArray(rStr, pKernArray, nIndex, nLen, nIndex, nLen, bCaret, pLayoutCache, - pSalLayoutCache); + pSalLayoutCache, bBounds); } vcl::TextArrayMetrics OutputDevice::GetPartialTextArray(const OUString& rStr, KernArray* pKernArray, sal_Int32 nIndex, sal_Int32 nLen, sal_Int32 nPartIndex, sal_Int32 nPartLen, bool bCaret, const vcl::text::TextLayoutCache* pLayoutCache, - const SalLayoutGlyphs* pSalLayoutCache) const + const SalLayoutGlyphs* pSalLayoutCache, bool bBounds) const { if (nIndex >= rStr.getLength()) { @@ -901,11 +901,14 @@ OutputDevice::GetPartialTextArray(const OUString& rStr, KernArray* pKernArray, s vcl::TextArrayMetrics stReturnValue; - basegfx::B2DRectangle stRect; - if (pSalLayout->GetBoundRect(stRect)) + if (bBounds) { - auto stRect2 = SalLayout::BoundRect2Rectangle(stRect); - stReturnValue.aBounds = ImplDevicePixelToLogic(stRect2); + basegfx::B2DRectangle stRect; + if (pSalLayout->GetBoundRect(stRect)) + { + auto stRect2 = SalLayout::BoundRect2Rectangle(stRect); + stReturnValue.aBounds = ImplDevicePixelToLogic(stRect2); + } } stReturnValue.nWidth = ImplDevicePixelToLogicWidthDouble(nWidth);