sc/source/filter/inc/richstring.hxx        |   29 +++++++--------
 sc/source/filter/inc/richstringcontext.hxx |    2 -
 sc/source/filter/inc/worksheethelper.hxx   |    2 -
 sc/source/filter/oox/richstring.cxx        |   55 ++++++++++++++---------------
 sc/source/filter/oox/richstringcontext.cxx |   12 +++---
 sc/source/filter/oox/worksheethelper.cxx   |    2 -
 6 files changed, 50 insertions(+), 52 deletions(-)

New commits:
commit f6378ed693960c852537c101faa85264c73643bf
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Tue Jul 5 14:07:20 2022 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Tue Jul 5 17:50:09 2022 +0200

    compact the RichStringPortion class
    
    Which reduces peak memory load from 548M to 495M when loading
    a large spreadsheet
    
    Change-Id: I74adfddd1722bba7a9dfae6dd0135e5f2b78b1a7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136826
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sc/source/filter/inc/richstring.hxx 
b/sc/source/filter/inc/richstring.hxx
index 71b393c1db41..fe0d0f2f527a 100644
--- a/sc/source/filter/inc/richstring.hxx
+++ b/sc/source/filter/inc/richstring.hxx
@@ -35,20 +35,20 @@ namespace oox { class SequenceInputStream; }
 namespace oox::xls {
 
 /** Contains text data and font attributes for a part of a rich formatted 
string. */
-class RichStringPortion : public WorkbookHelper
+class RichStringPortion
 {
 public:
-    explicit            RichStringPortion( const WorkbookHelper& rHelper );
+    RichStringPortion();
 
     /** Sets text data for this portion. */
     void                setText( const OUString& rText );
     /** Creates and returns a new font formatting object. */
-    FontRef const &     createFont();
+    FontRef const &     createFont(const WorkbookHelper& rHelper);
     /** Links this portion to a font object from the global font list. */
     void                setFontId( sal_Int32 nFontId );
 
     /** Final processing after import of all strings. */
-    void                finalizeImport();
+    void                finalizeImport(const WorkbookHelper& rHelper);
 
     /** Returns the text data of this portion. */
     const OUString& getText() const { return maText; }
@@ -71,8 +71,6 @@ private:
     bool                mbConverted;    /// Without repeatedly convert
 };
 
-typedef std::shared_ptr< RichStringPortion > RichStringPortionRef;
-
 /** Represents a position in a rich-string containing current font identifier.
 
     This object stores the position of a formatted character in a rich-string
@@ -210,10 +208,10 @@ class RichString : public WorkbookHelper
 public:
     explicit            RichString( const WorkbookHelper& rHelper );
 
-    /** Appends and returns a portion object for a plain string (t element). */
-    RichStringPortionRef importText();
-    /** Appends and returns a portion object for a new formatting run (r 
element). */
-    RichStringPortionRef importRun();
+    /** Appends and returns an index of a portion object for a plain string (t 
element). */
+    sal_Int32 importText();
+    /** Appends and returns an index of a portion object for a new formatting 
run (r element). */
+    sal_Int32 importRun();
     /** Appends and returns a phonetic text object for a new phonetic run (rPh 
element). */
     RichStringPhoneticRef importPhoneticRun( const AttributeList& rAttribs );
     /** Imports phonetic settings from the rPhoneticPr element. */
@@ -234,12 +232,14 @@ public:
     /** Converts the string and writes it into the passed XText, replace old 
contents of the text object,.
         @param rxText  The XText interface of the target object.
      */
-    void                convert( const css::uno::Reference< css::text::XText 
>& rxText ) const;
-    std::unique_ptr<EditTextObject> convert( ScEditEngineDefaulter& rEE, const 
oox::xls::Font* pFont ) const;
+    void                convert( const css::uno::Reference< css::text::XText 
>& rxText );
+    std::unique_ptr<EditTextObject> convert( ScEditEngineDefaulter& rEE, const 
oox::xls::Font* pFont );
+
+    RichStringPortion& getPortion(sal_Int32 nPortionIdx) { return 
maTextPortions[nPortionIdx]; }
 
 private:
     /** Creates, appends, and returns a new empty string portion. */
-    RichStringPortionRef createPortion();
+    sal_Int32 createPortion();
     /** Creates, appends, and returns a new empty phonetic text portion. */
     RichStringPhoneticRef createPhonetic();
 
@@ -249,10 +249,9 @@ private:
     void                createPhoneticPortions( const OUString& rText, 
PhoneticPortionModelList& rPortions, sal_Int32 nBaseLen );
 
 private:
-    typedef RefVector< RichStringPortion >  PortionVector;
     typedef RefVector< RichStringPhonetic > PhoneticVector;
 
-    PortionVector       maTextPortions; /// String portions with font data.
+    std::vector<RichStringPortion>  maTextPortions; /// String portions with 
font data.
     PhoneticSettings    maPhonSettings; /// Phonetic settings for this string.
     PhoneticVector      maPhonPortions; /// Phonetic text portions.
 };
diff --git a/sc/source/filter/inc/richstringcontext.hxx 
b/sc/source/filter/inc/richstringcontext.hxx
index 83e2fa4cc070..b944bfa84b9d 100644
--- a/sc/source/filter/inc/richstringcontext.hxx
+++ b/sc/source/filter/inc/richstringcontext.hxx
@@ -37,7 +37,7 @@ protected:
 
 private:
     RichStringRef       mxString;       /// Processed string.
-    RichStringPortionRef mxPortion;     /// Processed portion in the string.
+    sal_Int32           mnPortionIdx = -1;     /// Processed portion in the 
string.
     RichStringPhoneticRef mxPhonetic;   /// Processed phonetic text portion.
 };
 
diff --git a/sc/source/filter/inc/worksheethelper.hxx 
b/sc/source/filter/inc/worksheethelper.hxx
index 3aeb576f93de..3a44dc2e105e 100644
--- a/sc/source/filter/inc/worksheethelper.hxx
+++ b/sc/source/filter/inc/worksheethelper.hxx
@@ -262,7 +262,7 @@ public:
     /** Inserts a rich-string cell directly into the Calc sheet. */
     void putRichString(
         const ScAddress& rAddress,
-        const RichString& rString, const oox::xls::Font* pFirstPortionFont );
+        RichString& rString, const oox::xls::Font* pFirstPortionFont );
 
     /** Inserts a formula cell directly into the Calc sheet. */
     void putFormulaTokens(
diff --git a/sc/source/filter/oox/richstring.cxx 
b/sc/source/filter/oox/richstring.cxx
index 294fddfbc86a..bc040cdceeb5 100644
--- a/sc/source/filter/oox/richstring.cxx
+++ b/sc/source/filter/oox/richstring.cxx
@@ -160,8 +160,7 @@ OUString lcl_unEscapeUnicodeChars(const OUString& rSrc)
 
 } // namespace
 
-RichStringPortion::RichStringPortion( const WorkbookHelper& rHelper ) :
-    WorkbookHelper( rHelper ),
+RichStringPortion::RichStringPortion() :
     mnFontId( -1 ),
     mbConverted( false )
 {
@@ -172,9 +171,9 @@ void RichStringPortion::setText( const OUString& rText )
     maText = lcl_unEscapeUnicodeChars(rText);
 }
 
-FontRef const & RichStringPortion::createFont()
+FontRef const & RichStringPortion::createFont(const WorkbookHelper& rHelper)
 {
-    mxFont = std::make_shared<Font>( *this, false );
+    mxFont = std::make_shared<Font>( rHelper, false );
     return mxFont;
 }
 
@@ -183,12 +182,12 @@ void RichStringPortion::setFontId( sal_Int32 nFontId )
     mnFontId = nFontId;
 }
 
-void RichStringPortion::finalizeImport()
+void RichStringPortion::finalizeImport(const WorkbookHelper& rHelper)
 {
     if( mxFont )
         mxFont->finalizeImport();
     else if( mnFontId >= 0 )
-        mxFont = getStyles().getFont( mnFontId );
+        mxFont = rHelper.getStyles().getFont( mnFontId );
 }
 
 void RichStringPortion::convert( const Reference< XText >& rxText, bool 
bReplace )
@@ -411,12 +410,12 @@ RichString::RichString( const WorkbookHelper& rHelper ) :
 {
 }
 
-RichStringPortionRef RichString::importText()
+sal_Int32 RichString::importText()
 {
     return createPortion();
 }
 
-RichStringPortionRef RichString::importRun()
+sal_Int32 RichString::importRun()
 {
     return createPortion();
 }
@@ -446,7 +445,7 @@ void RichString::importString( SequenceInputStream& rStrm, 
bool bRich )
     }
     else
     {
-        createPortion()->setText( aBaseText );
+        getPortion(createPortion()).setText( aBaseText );
     }
 
     if( !rStrm.isEof() && getFlag( nFlags, BIFF12_STRINGFLAG_PHONETICS ) )
@@ -461,7 +460,8 @@ void RichString::importString( SequenceInputStream& rStrm, 
bool bRich )
 
 void RichString::finalizeImport()
 {
-    maTextPortions.forEachMem( &RichStringPortion::finalizeImport );
+    for (RichStringPortion& rPortion : maTextPortions)
+        rPortion.finalizeImport( *this );
 }
 
 bool RichString::extractPlainString( OUString& orString, const oox::xls::Font* 
pFirstPortionFont ) const
@@ -473,50 +473,50 @@ bool RichString::extractPlainString( OUString& orString, 
const oox::xls::Font* p
         orString.clear();
         return true;
     }
-    if( (maTextPortions.size() == 1) && !maTextPortions.front()->hasFont() && 
!lclNeedsRichTextFormat( pFirstPortionFont ) )
+    if( (maTextPortions.size() == 1) && !maTextPortions.front().hasFont() && 
!lclNeedsRichTextFormat( pFirstPortionFont ) )
     {
-        orString = maTextPortions.front()->getText();
+        orString = maTextPortions.front().getText();
         return orString.indexOf( '\x0A' ) < 0;
     }
     return false;
 }
 
-void RichString::convert( const Reference< XText >& rxText ) const
+void RichString::convert( const Reference< XText >& rxText )
 {
     if (maTextPortions.size() == 1)
     {
         // Set text directly to the cell when the string has only one portion.
         // It's much faster this way.
-        RichStringPortion& rPtn = *maTextPortions.front();
+        const RichStringPortion& rPtn = maTextPortions.front();
         rxText->setString(rPtn.getText());
         rPtn.writeFontProperties(rxText);
         return;
     }
 
     bool bReplaceOld = true;
-    for( const auto& rxTextPortion : maTextPortions )
+    for( auto& rTextPortion : maTextPortions )
     {
-        rxTextPortion->convert( rxText, bReplaceOld );
+        rTextPortion.convert( rxText, bReplaceOld );
         bReplaceOld = false;    // do not replace first portion text with 
following portions
     }
 }
 
-std::unique_ptr<EditTextObject> RichString::convert( ScEditEngineDefaulter& 
rEE, const oox::xls::Font* pFirstPortionFont ) const
+std::unique_ptr<EditTextObject> RichString::convert( ScEditEngineDefaulter& 
rEE, const oox::xls::Font* pFirstPortionFont )
 {
     ESelection aSelection;
 
     OUStringBuffer sString;
-    for( const auto& rxTextPortion : maTextPortions )
-        sString.append(rxTextPortion->getText());
+    for( auto& rTextPortion : maTextPortions )
+        sString.append(rTextPortion.getText());
 
     // fdo#84370 - diving into editeng is not thread safe.
     SolarMutexGuard aGuard;
 
     rEE.SetTextCurrentDefaults( sString.makeStringAndClear() );
 
-    for( const auto& rxTextPortion : maTextPortions )
+    for( auto& rTextPortion : maTextPortions )
     {
-        rxTextPortion->convert( rEE, aSelection, pFirstPortionFont );
+        rTextPortion.convert( rEE, aSelection, pFirstPortionFont );
         pFirstPortionFont = nullptr;
     }
 
@@ -525,11 +525,10 @@ std::unique_ptr<EditTextObject> RichString::convert( 
ScEditEngineDefaulter& rEE,
 
 // private --------------------------------------------------------------------
 
-RichStringPortionRef RichString::createPortion()
+sal_Int32 RichString::createPortion()
 {
-    RichStringPortionRef xPortion = std::make_shared<RichStringPortion>( *this 
);
-    maTextPortions.push_back( xPortion );
-    return xPortion;
+    maTextPortions.emplace_back();
+    return maTextPortions.size() - 1;
 }
 
 RichStringPhoneticRef RichString::createPhonetic()
@@ -558,9 +557,9 @@ void RichString::createTextPortions( const OUString& rText, 
FontPortionModelList
         sal_Int32 nPortionLen = (aIt + 1)->mnPos - aIt->mnPos;
         if( (0 < nPortionLen) && (aIt->mnPos + nPortionLen <= nStrLen) )
         {
-            RichStringPortionRef xPortion = createPortion();
-            xPortion->setText( rText.copy( aIt->mnPos, nPortionLen ) );
-            xPortion->setFontId( aIt->mnFontId );
+            RichStringPortion& rPortion = getPortion(createPortion());
+            rPortion.setText( rText.copy( aIt->mnPos, nPortionLen ) );
+            rPortion.setFontId( aIt->mnFontId );
         }
     }
 }
diff --git a/sc/source/filter/oox/richstringcontext.cxx 
b/sc/source/filter/oox/richstringcontext.cxx
index e7c3fd618bed..7f899f23bb27 100644
--- a/sc/source/filter/oox/richstringcontext.cxx
+++ b/sc/source/filter/oox/richstringcontext.cxx
@@ -33,10 +33,10 @@ ContextHandlerRef RichStringContext::onCreateContext( 
sal_Int32 nElement, const
         switch( nElement )
         {
             case XLS_TOKEN( t ):
-                mxPortion = mxString->importText();
+                mnPortionIdx = mxString->importText();
                 return this;    // collect text in onCharacters()
             case XLS_TOKEN( r ):
-                mxPortion = mxString->importRun();
+                mnPortionIdx = mxString->importRun();
                 return this;
             case XLS_TOKEN( rPh ):
                 mxPhonetic = mxString->importPhoneticRun( rAttribs );
@@ -52,8 +52,8 @@ ContextHandlerRef RichStringContext::onCreateContext( 
sal_Int32 nElement, const
             switch( nElement )
             {
                 case XLS_TOKEN( rPr ):
-                    if( mxPortion )
-                        return new FontContext( *this, mxPortion->createFont() 
);
+                    if( mnPortionIdx != -1 )
+                        return new FontContext( *this, 
mxString->getPortion(mnPortionIdx).createFont(*this) );
                 break;
 
                 case XLS_TOKEN( t ):
@@ -81,8 +81,8 @@ void RichStringContext::onCharacters( const OUString& rChars )
                 mxPhonetic->setText( rChars );
         break;
         default:
-            if( mxPortion )
-                mxPortion->setText( rChars );
+            if( mnPortionIdx != -1 )
+                mxString->getPortion(mnPortionIdx).setText( rChars );
     }
 }
 
diff --git a/sc/source/filter/oox/worksheethelper.cxx 
b/sc/source/filter/oox/worksheethelper.cxx
index 5e9ef3726a5f..402703c2206f 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -1588,7 +1588,7 @@ void WorksheetHelper::setCellFormulaValue(
     getFormulaBuffer().setCellFormulaValue(rAddress, rValueStr, nCellType);
 }
 
-void WorksheetHelper::putRichString( const ScAddress& rAddress, const 
RichString& rString, const oox::xls::Font* pFirstPortionFont )
+void WorksheetHelper::putRichString( const ScAddress& rAddress, RichString& 
rString, const oox::xls::Font* pFirstPortionFont )
 {
     ScEditEngineDefaulter& rEE = getEditEngine();
 

Reply via email to