sw/inc/doc.hxx                  |    6 ++++++
 sw/source/core/bastyp/init.cxx  |    4 ++--
 sw/source/core/doc/doc.cxx      |   39 +++++++++++++++++++++++++++++++++++++++
 sw/source/core/doc/docfmt.cxx   |    9 +++------
 sw/source/filter/xml/xmlexp.cxx |   19 ++++++++++++++++---
 5 files changed, 66 insertions(+), 11 deletions(-)

New commits:
commit 01ab23b13297c9d7b091dfbe2850cd343fcd3e0e
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Thu Sep 19 19:53:53 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Fri Sep 20 07:52:02 2024 +0200

    dont use GetItemSurrogates for gathering SvxTabStopItem
    
    which is very expensive these days
    
    Change-Id: Iae80c9d677fd1db8606a6a3f9462fe16b110a540
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173682
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index c11f23dcf6f6..0e16a9607e34 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1458,6 +1458,9 @@ public:
     /// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, 
if the function returns false, iteration is stopped
     SW_DLLPUBLIC void ForEachTxtAtrContainerItem(const 
std::function<bool(const SvXMLAttrContainerItem&)>&  ) const;
 
+    /// Iterate over all RES_PARATR_TABSTOP SvxTabStopItem, if the function 
returns false, iteration is stopped
+    SW_DLLPUBLIC void ForEachParaAtrTabStopItem(const std::function<bool(const 
SvxTabStopItem&)>&  ) const;
+
     // Call into intransparent Basic; expect possible Return String.
     void ExecMacro( const SvxMacro& rMacro, OUString* pRet, SbxArray* pArgs );
 
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index b5b409705f1a..9c1fb0bb62c5 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -358,7 +358,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes()
             { RES_PARATR_SPLIT, new SvxFormatSplitItem( true, RES_PARATR_SPLIT 
), SID_ATTR_PARA_SPLIT, SFX_ITEMINFOFLAG_NONE  },
             { RES_PARATR_ORPHANS, new SvxOrphansItem( 0, RES_PARATR_ORPHANS ), 
SID_ATTR_PARA_ORPHANS, SFX_ITEMINFOFLAG_NONE  },
             { RES_PARATR_WIDOWS, new SvxWidowsItem( 0, RES_PARATR_WIDOWS ), 
SID_ATTR_PARA_WIDOWS, SFX_ITEMINFOFLAG_NONE  },
-            { RES_PARATR_TABSTOP, new SvxTabStopItem( 1, SVX_TAB_DEFDIST, 
SvxTabAdjust::Default, RES_PARATR_TABSTOP ), SID_ATTR_TABSTOP, 
SFX_ITEMINFOFLAG_SUPPORT_SURROGATE  },
+            { RES_PARATR_TABSTOP, new SvxTabStopItem( 1, SVX_TAB_DEFDIST, 
SvxTabAdjust::Default, RES_PARATR_TABSTOP ), SID_ATTR_TABSTOP, 
SFX_ITEMINFOFLAG_NONE  },
 
             // for this at the Item GetMaxHyphens() = 0 was called, do this 
now on-demand at construction time
             // it will get added in constructor below once for LO runtime as 
static default
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 2be295986df3..1f2db1ab6668 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -1521,6 +1521,18 @@ void SwDoc::ForEachTxtAtrContainerItem(const 
std::function<bool(const SvXMLAttrC
     }
 }
 
+/// Iterate over all RES_PARATR_TABSTOP SvXMLAttrContainerItem, if the 
function returns false, iteration is stopped
+void SwDoc::ForEachParaAtrTabStopItem(const std::function<bool(const 
SvxTabStopItem&)>& rFunc ) const
+{
+    for(SwCharFormat* pFormat : *GetCharFormats())
+    {
+        const SwAttrSet& rAttrSet = pFormat->GetAttrSet();
+        if (const SvxTabStopItem* pItem = 
rAttrSet.GetItemIfSet(RES_PARATR_TABSTOP))
+            if (!rFunc(*pItem))
+                return;
+    }
+}
+
 void SwDoc::Summary(SwDoc& rExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, bool 
bImpress)
 {
     const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds();
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 75ccf557810e..b7f8d4ba7791 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -636,18 +636,15 @@ void SwDoc::SetDefault( const SfxItemSet& rSet )
                     nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos();
 
             bool bChg = false;
-            ItemSurrogates aSurrogates;
-            GetAttrPool().GetItemSurrogates(aSurrogates, RES_PARATR_TABSTOP);
-            for (const SfxPoolItem* pItem2 : aSurrogates)
-            {
+            ForEachParaAtrTabStopItem([&bChg, &nOldWidth, &nNewWidth](const 
SvxTabStopItem& rTabStopItem) -> bool {
                 // pItem2 and thus pTabStopItem is a evtl. shared & RefCounted
                 // Item and *should* not be changed that way. 
lcl_SetNewDefTabStops
                 // seems to change pTabStopItem (!). This may need to be 
changed
                 // to use iterateItemSurrogates and a defined write cycle.
-                const auto & rTabStopItem = static_cast<const 
SvxTabStopItem&>(*pItem2);
                 bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth,
                                                
const_cast<SvxTabStopItem&>(rTabStopItem) );
-            }
+                return true;
+            });
 
             aNew.ClearItem( RES_PARATR_TABSTOP );
             aOld.ClearItem( RES_PARATR_TABSTOP );
commit 1442dc4ee12251eed04e51eb324a34dc4b7973c3
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Thu Sep 19 19:11:52 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Fri Sep 20 07:51:54 2024 +0200

    dont use GetItemSurrogates for gathering SvXMLAttrContainerItem
    
    which is very expensive these days
    
    Change-Id: Idf133fc0532f12d297c0f44a3aad48b6eaa2206a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173680
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 83c64f06409b..c11f23dcf6f6 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1455,6 +1455,9 @@ public:
     /// Iterate over all RES_CHRATR_BACKGROUND SvxBrushItem, if the function 
returns false, iteration is stopped
     SW_DLLPUBLIC void ForEachCharacterBrushItem(const std::function<bool(const 
SvxBrushItem&)>&  ) const;
 
+    /// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, 
if the function returns false, iteration is stopped
+    SW_DLLPUBLIC void ForEachTxtAtrContainerItem(const 
std::function<bool(const SvXMLAttrContainerItem&)>&  ) const;
+
     // Call into intransparent Basic; expect possible Return String.
     void ExecMacro( const SvxMacro& rMacro, OUString* pRet, SbxArray* pArgs );
 
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index 0920842909e4..b5b409705f1a 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -344,7 +344,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes()
 
             { RES_TXTATR_CHARFMT, new SwFormatCharFormat( nullptr ),  0, 
SFX_ITEMINFOFLAG_NONE },
             { RES_TXTATR_CJK_RUBY, new SwFormatRuby( OUString() ),  
SID_ATTR_CHAR_CJK_RUBY, SFX_ITEMINFOFLAG_NONE },
-            { RES_TXTATR_UNKNOWN_CONTAINER, new SvXMLAttrContainerItem( 
RES_TXTATR_UNKNOWN_CONTAINER ),  0, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE },
+            { RES_TXTATR_UNKNOWN_CONTAINER, new SvXMLAttrContainerItem( 
RES_TXTATR_UNKNOWN_CONTAINER ),  0, SFX_ITEMINFOFLAG_NONE },
             { RES_TXTATR_INPUTFIELD, createSwFormatFieldForItemInfoPackage( 
RES_TXTATR_INPUTFIELD ),  0, SFX_ITEMINFOFLAG_NONE },
             { RES_TXTATR_CONTENTCONTROL, new SwFormatContentControl( 
RES_TXTATR_CONTENTCONTROL ),  0, SFX_ITEMINFOFLAG_NONE },
             { RES_TXTATR_FIELD, createSwFormatFieldForItemInfoPackage( 
RES_TXTATR_FIELD ),  0, SFX_ITEMINFOFLAG_NONE },
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 58bb026e1c7e..2be295986df3 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -53,6 +53,7 @@
 #include <editeng/pbinitem.hxx>
 #include <editeng/udlnitem.hxx>
 #include <editeng/colritem.hxx>
+#include <editeng/xmlcnitm.hxx>
 #include <unotools/localedatawrapper.hxx>
 
 #include <officecfg/Office/Writer.hxx>
@@ -1494,6 +1495,32 @@ void SwDoc::ForEachCharacterBrushItem( const 
std::function<bool(const SvxBrushIt
     }
 }
 
+/// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, if 
the function returns false, iteration is stopped
+void SwDoc::ForEachTxtAtrContainerItem(const std::function<bool(const 
SvXMLAttrContainerItem&)>& rFunc ) const
+{
+    SwNodeOffset nCount = GetNodes().Count();
+    for (SwNodeOffset i(0); i < nCount; ++i)
+    {
+        SwNode* pNode = GetNodes()[i];
+        if (!pNode->IsTextNode())
+            continue;
+        SwTextNode* pTextNode = pNode->GetTextNode();
+        if (!pTextNode->HasHints())
+            continue;
+        SwpHints& rHints = pTextNode->GetSwpHints();
+        for (size_t j = 0; j < rHints.Count(); ++j)
+        {
+            const SwTextAttr* pTextAttr = rHints.Get(j);
+            if (pTextAttr->Which() != RES_TXTATR_AUTOFMT)
+                continue;
+            const SwFormatAutoFormat& rFmt = pTextAttr->GetAutoFormat();
+            if (const SvXMLAttrContainerItem* pItem = 
rFmt.GetStyleHandle()->GetItemIfSet(RES_TXTATR_UNKNOWN_CONTAINER))
+                if (!rFunc(*pItem))
+                    return;
+        }
+    }
+}
+
 void SwDoc::Summary(SwDoc& rExtDoc, sal_uInt8 nLevel, sal_uInt8 nPara, bool 
bImpress)
 {
     const SwOutlineNodes& rOutNds = GetNodes().GetOutLineNds();
diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx
index 07bc30f98939..0d9e89979bdf 100644
--- a/sw/source/filter/xml/xmlexp.cxx
+++ b/sw/source/filter/xml/xmlexp.cxx
@@ -135,14 +135,27 @@ ErrCode SwXMLExport::exportDoc( enum XMLTokenEnum eClass )
 
         GetTextParagraphExport()->SetBlockMode( m_bBlock );
 
+        pDoc->ForEachTxtAtrContainerItem([this](const SvXMLAttrContainerItem& 
rUnknown) -> bool {
+            if( rUnknown.GetAttrCount() > 0 )
+            {
+                sal_uInt16 nIdx = rUnknown.GetFirstNamespaceIndex();
+                while( USHRT_MAX != nIdx )
+                {
+                    GetNamespaceMap_().Add( rUnknown.GetPrefix( nIdx ),
+                                        rUnknown.GetNamespace( nIdx ) );
+                    nIdx = rUnknown.GetNextNamespaceIndex( nIdx );
+                }
+            }
+            return true;
+        });
+
         const SfxItemPool& rPool = pDoc->GetAttrPool();
-        sal_uInt16 aWhichIds[5] = { RES_UNKNOWNATR_CONTAINER,
-                                    RES_TXTATR_UNKNOWN_CONTAINER,
+        sal_uInt16 aWhichIds[4] = { RES_UNKNOWNATR_CONTAINER,
                                     SDRATTR_XMLATTRIBUTES,
                                     EE_PARA_XMLATTRIBS,
                                     EE_CHAR_XMLATTRIBS };
 
-        const int nWhichIds = rPool.GetSecondaryPool() ? 5 : 2;
+        const int nWhichIds = rPool.GetSecondaryPool() ? 4 : 1;
         for( int j=0; j < nWhichIds; ++j )
         {
             const sal_uInt16 nWhichId = aWhichIds[j];

Reply via email to