sw/inc/doc.hxx                     |    3 ++
 sw/inc/shellio.hxx                 |    2 -
 sw/source/core/bastyp/init.cxx     |    6 ++--
 sw/source/core/doc/doc.cxx         |   45 +++++++++++++++++++++++++++++++++++++
 sw/source/filter/writer/writer.cxx |   27 ++++++++++++++++------
 sw/source/filter/ww8/wrtw8sty.cxx  |   19 +++++++--------
 sw/source/filter/xml/xmlfonte.cxx  |   23 +++++++++---------
 7 files changed, 93 insertions(+), 32 deletions(-)

New commits:
commit 9ceb4141ec291129dfbf0c1a220c9c498bc50585
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Thu Sep 19 13:03:39 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon Sep 23 14:34:07 2024 +0200

    dont use GetItemSurrogates for gathering SvxFontItem
    
    which is very expensive these days
    
    Change-Id: I43e19c77eee024fd4875aa57d9c28d5c9e0ad465
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173650
    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 7137078c1571..a1bcea1eca4f 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_CHRATR_FONT/RES_CHRATR_CJK_FONT/RES_CHRATR_CTL_FONT SvxFontItem, if the 
function returns false, iteration is stopped
+    SW_DLLPUBLIC void ForEachCharacterFontItem(TypedWhichId<SvxFontItem> 
nWhich, bool bIgnoreAutoStyles, const std::function<bool(const SvxFontItem&)>&  
);
+
     /// 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;
 
diff --git a/sw/inc/shellio.hxx b/sw/inc/shellio.hxx
index 633dbacf9070..a9245c8f3bba 100644
--- a/sw/inc/shellio.hxx
+++ b/sw/inc/shellio.hxx
@@ -392,7 +392,7 @@ class SW_DLLPUBLIC Writer
     OUString       m_sBaseURL;
 
     void AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont );
-    void AddFontItems_( SfxItemPool& rPool, sal_uInt16 nWhichId );
+    void AddFontItems_( SfxItemPool& rPool, TypedWhichId<SvxFontItem> nWhichId 
);
 
     std::unique_ptr<Writer_Impl> m_pImpl;
 
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index 487484512141..9dbf4043d88f 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -283,7 +283,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes()
             { RES_CHRATR_CONTOUR, new SvxContourItem( false, 
RES_CHRATR_CONTOUR ), SID_ATTR_CHAR_CONTOUR, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_CROSSEDOUT, new SvxCrossedOutItem( STRIKEOUT_NONE, 
RES_CHRATR_CROSSEDOUT ), SID_ATTR_CHAR_STRIKEOUT, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_ESCAPEMENT, new SvxEscapementItem( 
RES_CHRATR_ESCAPEMENT ), SID_ATTR_CHAR_ESCAPEMENT, SFX_ITEMINFOFLAG_NONE },
-            { RES_CHRATR_FONT, nullptr, SID_ATTR_CHAR_FONT, 
SFX_ITEMINFOFLAG_SUPPORT_SURROGATE },
+            { RES_CHRATR_FONT, nullptr, SID_ATTR_CHAR_FONT, 
SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_FONTSIZE, new SvxFontHeightItem( 240, 100, 
RES_CHRATR_FONTSIZE ), SID_ATTR_CHAR_FONTHEIGHT, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_KERNING, new SvxKerningItem( 0, RES_CHRATR_KERNING ), 
SID_ATTR_CHAR_KERNING, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_LANGUAGE, new SvxLanguageItem(LANGUAGE_DONTKNOW, 
RES_CHRATR_LANGUAGE ), SID_ATTR_CHAR_LANGUAGE, SFX_ITEMINFOFLAG_NONE },
@@ -300,14 +300,14 @@ ItemInfoPackage& getItemInfoPackageSwAttributes()
             { RES_CHRATR_BACKGROUND, new SvxBrushItem( RES_CHRATR_BACKGROUND 
), SID_ATTR_BRUSH_CHAR, SFX_ITEMINFOFLAG_NONE },
 
             // CJK-Attributes
-            { RES_CHRATR_CJK_FONT, nullptr, SID_ATTR_CHAR_CJK_FONT, 
SFX_ITEMINFOFLAG_SUPPORT_SURROGATE },
+            { RES_CHRATR_CJK_FONT, nullptr, SID_ATTR_CHAR_CJK_FONT, 
SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_CJK_FONTSIZE, new SvxFontHeightItem( 240, 100, 
RES_CHRATR_CJK_FONTSIZE ), SID_ATTR_CHAR_CJK_FONTHEIGHT, SFX_ITEMINFOFLAG_NONE 
},
             { RES_CHRATR_CJK_LANGUAGE, new SvxLanguageItem(LANGUAGE_DONTKNOW, 
RES_CHRATR_CJK_LANGUAGE), SID_ATTR_CHAR_CJK_LANGUAGE, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_CJK_POSTURE, new SvxPostureItem(ITALIC_NONE, 
RES_CHRATR_CJK_POSTURE ), SID_ATTR_CHAR_CJK_POSTURE, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_CJK_WEIGHT, new SvxWeightItem( WEIGHT_NORMAL, 
RES_CHRATR_CJK_WEIGHT ), SID_ATTR_CHAR_CJK_WEIGHT, SFX_ITEMINFOFLAG_NONE },
 
             // CTL-Attributes
-            { RES_CHRATR_CTL_FONT, nullptr, SID_ATTR_CHAR_CTL_FONT, 
SFX_ITEMINFOFLAG_SUPPORT_SURROGATE },
+            { RES_CHRATR_CTL_FONT, nullptr, SID_ATTR_CHAR_CTL_FONT, 
SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_CTL_FONTSIZE, new SvxFontHeightItem(  240, 100,  
RES_CHRATR_CTL_FONTSIZE ), SID_ATTR_CHAR_CTL_FONTHEIGHT, SFX_ITEMINFOFLAG_NONE 
},
             { RES_CHRATR_CTL_LANGUAGE, new SvxLanguageItem(LANGUAGE_DONTKNOW, 
RES_CHRATR_CTL_LANGUAGE), SID_ATTR_CHAR_CTL_LANGUAGE, SFX_ITEMINFOFLAG_NONE },
             { RES_CHRATR_CTL_POSTURE, new SvxPostureItem(ITALIC_NONE, 
RES_CHRATR_CTL_POSTURE ), SID_ATTR_CHAR_CTL_POSTURE, SFX_ITEMINFOFLAG_NONE },
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 15e6a1bf29fe..f9ab83b6522f 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -54,6 +54,7 @@
 #include <editeng/udlnitem.hxx>
 #include <editeng/colritem.hxx>
 #include <editeng/xmlcnitm.hxx>
+#include <editeng/fontitem.hxx>
 #include <unotools/localedatawrapper.hxx>
 
 #include <officecfg/Office/Writer.hxx>
@@ -1521,6 +1522,50 @@ void SwDoc::ForEachTxtAtrContainerItem(const 
std::function<bool(const SvXMLAttrC
     }
 }
 
+/// Iterate over all RES_CHRATR_FONT/RES_CHRATR_CJK_FONT/RES_CHRATR_CTL_FONT 
SvxFontItem, if the function returns false, iteration is stopped
+void SwDoc::ForEachCharacterFontItem(TypedWhichId<SvxFontItem> nWhich, bool 
bIgnoreAutoStyles, const std::function<bool(const SvxFontItem&)>& rFunc )
+{
+    assert(nWhich == RES_CHRATR_FONT || nWhich == RES_CHRATR_CJK_FONT || 
nWhich == RES_CHRATR_CTL_FONT);
+    for(const SwCharFormat* pFormat : *GetCharFormats())
+    {
+        const SwAttrSet& rAttrSet = pFormat->GetAttrSet();
+        if (const SvxFontItem* pItem = rAttrSet.GetItemIfSet(nWhich))
+            if (!rFunc(*pItem))
+                return;
+    }
+    for(const SwTextFormatColl* pFormat : *GetTextFormatColls())
+    {
+        const SwAttrSet& rAttrSet = pFormat->GetAttrSet();
+        if (const SvxFontItem* pItem = rAttrSet.GetItemIfSet(nWhich))
+            if (!rFunc(*pItem))
+                return;
+    }
+    SwNodeOffset nCount = GetNodes().Count();
+    for (SwNodeOffset i(0); i < nCount; ++i)
+    {
+        const SwNode* pNode = GetNodes()[i];
+        if (pNode->IsContentNode())
+        {
+            const SwContentNode* pTextNode = pNode->GetContentNode();
+            if (pTextNode->HasSwAttrSet())
+                if (const SvxFontItem* pItem = 
pTextNode->GetSwAttrSet().GetItemIfSet(nWhich))
+                    if (!rFunc(*pItem))
+                        return;
+        }
+    }
+    // ignore auto styles when called from the code that is constructing the 
auto style pool
+    if (!bIgnoreAutoStyles)
+    {
+        // auto styles
+        std::vector<std::shared_ptr<SfxItemSet>> aStyles;
+        GetIStyleAccess().getAllStyles(aStyles, IStyleAccess::AUTO_STYLE_CHAR);
+        for (const auto & rxItemSet : aStyles)
+            if (const SvxFontItem* pItem = rxItemSet->GetItemIfSet(nWhich))
+                if (!rFunc(*pItem))
+                    return;
+    }
+}
+
 /// 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
 {
diff --git a/sw/source/filter/writer/writer.cxx 
b/sw/source/filter/writer/writer.cxx
index 9febf054e0d7..0576663965c9 100644
--- a/sw/source/filter/writer/writer.cxx
+++ b/sw/source/filter/writer/writer.cxx
@@ -360,19 +360,32 @@ void Writer::PutEditEngFontsInAttrPool()
     }
 }
 
-void Writer::AddFontItems_( SfxItemPool& rPool, sal_uInt16 nW )
+void Writer::AddFontItems_( SfxItemPool& rPool, TypedWhichId<SvxFontItem> 
nWhich )
 {
-    const SvxFontItem* pFont = static_cast<const 
SvxFontItem*>(&rPool.GetUserOrPoolDefaultItem( nW ));
+    const SvxFontItem* pFont = &rPool.GetUserOrPoolDefaultItem( nWhich );
     AddFontItem( rPool, *pFont );
 
-    pFont = static_cast<const SvxFontItem*>(rPool.GetUserDefaultItem( nW ));
+    pFont = rPool.GetUserDefaultItem( nWhich );
     if( nullptr != pFont )
         AddFontItem( rPool, *pFont );
 
-    ItemSurrogates aSurrogates;
-    rPool.GetItemSurrogates(aSurrogates, nW);
-    for (const SfxPoolItem* pItem : aSurrogates)
-        AddFontItem( rPool, *static_cast<const SvxFontItem*>(pItem) );
+    if (nWhich == RES_CHRATR_FONT || nWhich == RES_CHRATR_CJK_FONT || nWhich 
== RES_CHRATR_CTL_FONT)
+    {
+        m_pDoc->ForEachCharacterFontItem(nWhich, /*bIgnoreAutoStyles*/false,
+            [this, &rPool] (const SvxFontItem& rFontItem) -> bool
+            {
+                AddFontItem( rPool, rFontItem );
+                return true;
+            });
+    }
+    else
+    {
+        // nWhich is one of EE_CHAR_FONTINFO /  EE_CHAR_FONTINFO_CJK / rPool, 
EE_CHAR_FONTINFO_CTL
+        ItemSurrogates aSurrogates;
+        rPool.GetItemSurrogates(aSurrogates, nWhich);
+        for (const SfxPoolItem* pItem : aSurrogates)
+            AddFontItem( rPool, *static_cast<const SvxFontItem*>(pItem) );
+    }
 }
 
 void Writer::AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont )
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx 
b/sw/source/filter/ww8/wrtw8sty.cxx
index 39ab72c1fbc3..ff7d30bd84dc 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -944,17 +944,16 @@ void wwFontHelper::InitFontTable(const SwDoc& rDoc)
     if (!m_bLoadAllFonts)
         return;
 
-    const sal_uInt16 aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, 
RES_CHRATR_CTL_FONT, 0 };
-    for (const sal_uInt16* pId = aTypes; *pId; ++pId)
+    const TypedWhichId<SvxFontItem> aTypes[] { RES_CHRATR_FONT, 
RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT };
+    for (const TypedWhichId<SvxFontItem> & pId : aTypes)
     {
-        ItemSurrogates aSurrogates;
-        rPool.GetItemSurrogates(aSurrogates, *pId);
-        for (const SfxPoolItem* pItem : aSurrogates)
-        {
-            pFont = static_cast<const SvxFontItem*>(pItem);
-            GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
-                         pFont->GetFamily(), pFont->GetCharSet()));
-        }
+        const_cast<SwDoc&>(rDoc).ForEachCharacterFontItem(pId, 
/*bIgnoreAutoStyles*/false,
+            [this] (const SvxFontItem& rFontItem) -> bool
+            {
+                GetId(wwFont(rFontItem.GetFamilyName(), rFontItem.GetPitch(),
+                             rFontItem.GetFamily(), rFontItem.GetCharSet()));
+                return true;
+            });
     }
 }
 
diff --git a/sw/source/filter/xml/xmlfonte.cxx 
b/sw/source/filter/xml/xmlfonte.cxx
index 8566a1a69497..d634bbbd5d8b 100644
--- a/sw/source/filter/xml/xmlfonte.cxx
+++ b/sw/source/filter/xml/xmlfonte.cxx
@@ -21,6 +21,9 @@
 #include <xmloff/XMLFontAutoStylePool.hxx>
 #include <editeng/fontitem.hxx>
 #include <doc.hxx>
+#include <docsh.hxx>
+#include <ndtxt.hxx>
+#include <txatbase.hxx>
 #include "xmlexp.hxx"
 #include "xmlimp.hxx"
 #include <IDocumentSettingAccess.hxx>
@@ -56,23 +59,21 @@ sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB)
 SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& 
_rExport, bool bFontEmbedding)
     : XMLFontAutoStylePool(_rExport, bFontEmbedding)
 {
-    sal_uInt16 const aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
+    TypedWhichId<SvxFontItem> const aWhichIds[3] = { RES_CHRATR_FONT, 
RES_CHRATR_CJK_FONT,
                                       RES_CHRATR_CTL_FONT };
 
     const SfxItemPool& rPool = _rExport.getDoc()->GetAttrPool();
     std::vector<const SvxFontItem *> aFonts;
-    for(sal_uInt16 nWhichId : aWhichIds)
+    for(const TypedWhichId<SvxFontItem> & nWhichId : aWhichIds)
     {
-        const SvxFontItem& rFont =
-            static_cast<const SvxFontItem&>(rPool.GetUserOrPoolDefaultItem( 
nWhichId ));
+        const SvxFontItem& rFont = rPool.GetUserOrPoolDefaultItem( nWhichId );
         aFonts.push_back(&rFont);
-        ItemSurrogates aSurrogates;
-        rPool.GetItemSurrogates(aSurrogates, nWhichId);
-        for (const SfxPoolItem* pItem : aSurrogates)
-        {
-            auto pFont = static_cast<const SvxFontItem *>(pItem);
-            aFonts.push_back(pFont);
-        }
+        _rExport.getDoc()->ForEachCharacterFontItem(nWhichId, 
/*bIgnoreAutoStyles*/true,
+            [&aFonts] (const SvxFontItem& rFontItem) -> bool
+            {
+                aFonts.push_back(&rFontItem);
+                return true;
+            });
     }
 
     std::sort(aFonts.begin(), aFonts.end(),

Reply via email to