include/svx/EnhancedCustomShape2d.hxx             |    9 +-
 svx/source/customshapes/EnhancedCustomShape2d.cxx |   90 +++++++++++-----------
 2 files changed, 50 insertions(+), 49 deletions(-)

New commits:
commit c4e96e685c553327e83dc46f937d44b9f7c0c004
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Mon Jul 15 14:06:35 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon Jul 15 18:46:40 2024 +0200

    delay parsing of formula in EnhancedCustomShape2d
    
    We create a bunch of temporary copies of these during layout in writer,
    and we don't appear to need the equation results at that point.
    
    Speeds up display of a complex DOCX file load by 10%
    
    Change-Id: Ic5870931caba13cd79b07617d04b70616f06c5b4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170498
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins

diff --git a/include/svx/EnhancedCustomShape2d.hxx 
b/include/svx/EnhancedCustomShape2d.hxx
index 3947da9c31c4..ba638b0be900 100644
--- a/include/svx/EnhancedCustomShape2d.hxx
+++ b/include/svx/EnhancedCustomShape2d.hxx
@@ -104,12 +104,13 @@ class SVXCORE_DLLPUBLIC EnhancedCustomShape2d final : 
public SfxItemSet
 
         */
         struct SAL_DLLPRIVATE EquationResult {
-            bool bReady;
-            double fValue;
+            mutable bool bParsed = false;
+            bool bReady = false;
+            double fValue = 0;
+            mutable std::shared_ptr< EnhancedCustomShape::ExpressionNode > 
xNode;
         };
         css::uno::Sequence< OUString >                                         
              m_seqEquations;
-        std::vector< std::shared_ptr< EnhancedCustomShape::ExpressionNode > >  
                         m_vNodesSharedPtr;
-        std::vector< EquationResult >                                          
                         m_vEquationResults;
+        std::vector< EquationResult >                                          
              m_vEquationResults;
 
         css::uno::Sequence< css::drawing::EnhancedCustomShapeSegment >         
   m_seqSegments;
         css::uno::Sequence< css::drawing::EnhancedCustomShapeParameterPair>    
   m_seqCoordinates;
diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx 
b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index 8bbd3a2bd555..bc640da6af2d 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -853,23 +853,7 @@ 
EnhancedCustomShape2d::EnhancedCustomShape2d(SdrObjCustomShape& rSdrObjCustomSha
     if ( !nLength )
         return;
 
-    m_vNodesSharedPtr.resize( nLength );
     m_vEquationResults.resize( nLength );
-    for ( sal_Int32 i = 0; i < nLength; i++ )
-    {
-        m_vEquationResults[ i ].bReady = false;
-        try
-        {
-            m_vNodesSharedPtr[ i ] = 
EnhancedCustomShape::FunctionParser::parseFunction( m_seqEquations[ i ], *this 
);
-        }
-        catch ( EnhancedCustomShape::ParseError& )
-        {
-            SAL_INFO(
-                "svx",
-                "error: equation number: " << i << ", parser failed ("
-                    << m_seqEquations[i] << ")");
-        }
-    }
 }
 
 using EnhancedCustomShape::ExpressionFunct;
@@ -916,39 +900,55 @@ double EnhancedCustomShape2d::GetEquationValueAsDouble( 
const sal_Int32 nIndex )
 {
     double fNumber = 0.0;
     static sal_uInt32 nLevel = 0;
-    if ( nIndex < static_cast<sal_Int32>(m_vNodesSharedPtr.size()) )
+    if ( nIndex >= static_cast<sal_Int32>(m_vEquationResults.size()) )
+        return fNumber;
+
+    if (!m_vEquationResults[nIndex].bParsed)
     {
-        if ( m_vNodesSharedPtr[ nIndex ] ) {
-            nLevel ++;
-            try
-            {
-                if ( m_vEquationResults[ nIndex ].bReady )
-                    fNumber = m_vEquationResults[ nIndex ].fValue;
-                else {
-                    // cast to non const, so that we can optimize by caching
-                    // equation results, without changing all the const in the 
stack
-                    struct EquationResult &aResult = 
const_cast<EnhancedCustomShape2d*>(this)->m_vEquationResults[ nIndex ];
-
-                    fNumber = aResult.fValue = (*m_vNodesSharedPtr[ nIndex 
])();
-                    aResult.bReady = true;
-
-                    SAL_INFO("svx", "equation " << nLevel << " (level: " << 
m_seqEquations[nIndex] << "): "
-                             << fNumber << " --> " << 
180.0*fNumber/10800000.0);
-                }
-                if ( !std::isfinite( fNumber ) )
-                    fNumber = 0.0;
-            }
-            catch ( ... )
-            {
-                SAL_WARN("svx", 
"EnhancedCustomShape2d::GetEquationValueAsDouble failed");
+        m_vEquationResults[nIndex].bParsed = true;
+        try
+        {
+            m_vEquationResults[nIndex].xNode = 
EnhancedCustomShape::FunctionParser::parseFunction( m_seqEquations[ nIndex ], 
*this );
+        }
+        catch ( EnhancedCustomShape::ParseError& )
+        {
+            SAL_INFO(
+                "svx",
+                "error: equation number: " << nIndex << ", parser failed ("
+                    << m_seqEquations[nIndex] << ")");
+        }
+    }
+    if ( m_vEquationResults[ nIndex ].xNode )
+    {
+        nLevel ++;
+        try
+        {
+            if ( m_vEquationResults[ nIndex ].bReady )
+                fNumber = m_vEquationResults[ nIndex ].fValue;
+            else {
+                // cast to non const, so that we can optimize by caching
+                // equation results, without changing all the const in the 
stack
+                struct EquationResult &aResult = 
const_cast<EnhancedCustomShape2d*>(this)->m_vEquationResults[ nIndex ];
+
+                fNumber = aResult.fValue = (*m_vEquationResults[ nIndex 
].xNode)();
+                aResult.bReady = true;
+
+                SAL_INFO("svx", "equation " << nLevel << " (level: " << 
m_seqEquations[nIndex] << "): "
+                         << fNumber << " --> " << 180.0*fNumber/10800000.0);
             }
-            nLevel --;
+            if ( !std::isfinite( fNumber ) )
+                fNumber = 0.0;
         }
-        SAL_INFO(
-            "svx",
-            "?" << nIndex << " --> " << fNumber << " (angle: "
-                << 180.0*fNumber/10800000.0 << ")");
+        catch ( ... )
+        {
+            SAL_WARN("svx", "EnhancedCustomShape2d::GetEquationValueAsDouble 
failed");
+        }
+        nLevel --;
     }
+    SAL_INFO(
+        "svx",
+        "?" << nIndex << " --> " << fNumber << " (angle: "
+            << 180.0*fNumber/10800000.0 << ")");
 
     return fNumber;
 }

Reply via email to