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);

Reply via email to