editeng/source/items/frmitems.cxx     |   84 +++++++--------
 include/svl/itemset.hxx               |    1 
 include/svl/style.hxx                 |    3 
 include/tools/XmlWriter.hxx           |    4 
 sc/inc/patattr.hxx                    |   20 +--
 sc/source/core/data/patattr.cxx       |  179 +++++++++++++++++-----------------
 sc/source/filter/inc/stylesbuffer.hxx |    2 
 sc/source/filter/oox/stylesbuffer.cxx |   20 ++-
 svl/source/items/cenumitm.cxx         |    8 -
 svl/source/items/intitem.cxx          |   31 +++--
 svl/source/items/itemset.cxx          |   29 ++++-
 svl/source/items/poolitem.cxx         |   20 ++-
 svl/source/items/stritem.cxx          |   10 +
 svl/source/items/style.cxx            |   29 ++---
 svl/source/items/voiditem.cxx         |    9 -
 svl/source/undo/undo.cxx              |   45 ++++----
 svx/source/xoutdev/xattr.cxx          |   67 ++++++------
 svx/source/xoutdev/xattr2.cxx         |   55 +++++-----
 svx/source/xoutdev/xattrbmp.cxx       |   10 -
 sw/source/uibase/shells/grfsh.cxx     |   31 +++++
 tools/qa/cppunit/test_xmlwriter.cxx   |   18 ++-
 tools/source/xml/XmlWriter.cxx        |   32 ++++--
 vcl/inc/svdata.hxx                    |    3 
 23 files changed, 400 insertions(+), 310 deletions(-)

New commits:
commit 9b6e69b2da02b5f802332ff55aaf82ba729d0581
Author:     Noel Grandin <[email protected]>
AuthorDate: Mon Dec 22 10:31:46 2025 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:34 2026 +0100

    tdf#166684 used unordered_set for maCacheOwners
    
    maCacheOwners is pretty much a write-only data-structure, we very seldom 
read it,
    which makes unordered_set a better fit.
    Shaves about 1% off the time here.
    
    Change-Id: Ife37d56c64ecfa0e658ee42d40f425d2bc3ac670
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196065
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit a2d8fe60153364d9f94de344e47a57907a98354c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196361
    Reviewed-by: Noel Grandin <[email protected]>
    Tested-by: Jenkins

diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index df49ad1e7d56..3b3773e4cdac 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -55,6 +55,7 @@
 #include <optional>
 #include <vector>
 #include <unordered_map>
+#include <unordered_set>
 #include "schedulerimpl.hxx"
 #include <basegfx/DrawCommands.hxx>
 
@@ -402,7 +403,7 @@ struct ImplSVData
 
     css::uno::Reference< css::lang::XComponent > mxAccessBridge;
     std::unordered_map< int, OUString > maPaperNames;
-    o3tl::sorted_vector<CacheOwner*> maCacheOwners;
+    std::unordered_set<CacheOwner*> maCacheOwners;
 
     css::uno::Reference<css::i18n::XCharacterClassification> m_xCharClass;
 
commit af8d3eae333db0cd7c1d970a7c96d9ce68f0d96a
Author:     Noel Grandin <[email protected]>
AuthorDate: Mon Dec 22 11:53:08 2025 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:34 2026 +0100

    tdf#166684 avoid re-creating ExtConditional stylesheets
    
    there are a lot of them, and renaming them is expensive.
    
    Shaves 10% off load time.
    
    Change-Id: Ic5c3347367babd9156ceec94f78ef6f1017c6e4d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196088
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/source/filter/inc/stylesbuffer.hxx 
b/sc/source/filter/inc/stylesbuffer.hxx
index 6905b07c762a..b908c8f83d37 100644
--- a/sc/source/filter/inc/stylesbuffer.hxx
+++ b/sc/source/filter/inc/stylesbuffer.hxx
@@ -35,6 +35,7 @@
 #include <docmodel/color/ComplexColor.hxx>
 #include <attarray.hxx>
 #include <vector>
+#include <unordered_set>
 
 class ScPatternCache;
 enum class ScTableStyleElement;
@@ -981,6 +982,7 @@ private:
     DxfVector           maExtDxfs;          /// List of differential extlst 
cell styles.
     mutable DxfStyleMap maDxfStyles;        /// Maps DXF identifiers to Calc 
style sheet names.
     TableStyleVector    maTableStyles;
+    mutable std::unordered_set<sal_Int32> maExtConditionalStyles;  /// DXF 
identifiers for ExtCondition which have been mapped to styles.
 };
 
 } // namespace oox::xls
diff --git a/sc/source/filter/oox/stylesbuffer.cxx 
b/sc/source/filter/oox/stylesbuffer.cxx
index d38bd13ece3e..1860612b2c01 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -3308,16 +3308,20 @@ OUString StylesBuffer::createExtDxfStyle( sal_Int32 
nDxfId ) const
     {
         rStyleName = "ExtConditionalStyle_" + OUString::number(nDxfId + 1);
 
-        // Create a cell style. This may overwrite an existing style if
-        // one with the same name exists.
-        ScStyleSheet& rStyleSheet = ScfTools::MakeCellStyleSheet(
-                *getScDocument().GetStyleSheetPool(), rStyleName, true);
+        // use a map to avoid creating the same style more than once.
+        if (maExtConditionalStyles.insert(nDxfId).second)
+        {
+            // Create a cell style. This may overwrite an existing style if
+            // one with the same name exists.
+            ScStyleSheet& rStyleSheet = ScfTools::MakeCellStyleSheet(
+                    *getScDocument().GetStyleSheetPool(), rStyleName, true);
 
-        rStyleSheet.ResetParent();
-        SfxItemSet& rStyleItemSet =
-            rStyleSheet.GetItemSet();
+            rStyleSheet.ResetParent();
+            SfxItemSet& rStyleItemSet =
+                rStyleSheet.GetItemSet();
 
-        pDxf->fillToItemSet(rStyleItemSet);
+            pDxf->fillToItemSet(rStyleItemSet);
+        }
     }
 
     // on error: fallback to default style
commit a0f17e97358d02baf5b503427383a32f6dda1c92
Author:     Noel Grandin <[email protected]>
AuthorDate: Mon Dec 22 10:30:56 2025 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:34 2026 +0100

    tdf#166684 inline SfxStyleSheetIterator::GetSearchFamily
    
    which is a little hot here, and this is just a getter method.
    Shaves about 1% off.
    
    Change-Id: I94fcdbb35e1be9cbc446f7f7709eaa67d21d0d48
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196064
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    (cherry picked from commit a6812f5dab4b4eab0dca92a0556a70317aeca80d)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196359
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/include/svl/style.hxx b/include/svl/style.hxx
index 94f71375251d..8cd3a038e6e4 100644
--- a/include/svl/style.hxx
+++ b/include/svl/style.hxx
@@ -205,7 +205,8 @@ public:
     SfxStyleSheetIterator(const SfxStyleSheetBasePool *pBase,
                           SfxStyleFamily eFam, SfxStyleSearchBits 
n=SfxStyleSearchBits::All );
     SfxStyleSearchBits GetSearchMask() const;
-    SfxStyleFamily GetSearchFamily() const;
+    SfxStyleFamily GetSearchFamily() const { return nSearchFamily; }
+
     virtual sal_Int32 Count();
     virtual SfxStyleSheetBase *operator[](sal_Int32 nIdx);
     virtual SfxStyleSheetBase* First();
diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx
index fefcd02c78dd..bccbe71f7614 100644
--- a/svl/source/items/style.cxx
+++ b/svl/source/items/style.cxx
@@ -364,11 +364,6 @@ OUString SfxStyleSheetBase::GetDescription( MapUnit 
eMetric )
     return aDesc.makeStringAndClear();
 }
 
-SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
-{
-    return nSearchFamily;
-}
-
 inline bool SfxStyleSheetIterator::IsTrivialSearch() const
 {
     return (( nMask & SfxStyleSearchBits::AllVisible ) == 
SfxStyleSearchBits::AllVisible) &&
commit bc97c05624dab81fabaf4de218b0dff3fe16694e
Author:     Noel Grandin <[email protected]>
AuthorDate: Mon Dec 22 09:19:59 2025 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:34 2026 +0100

    tdf#166684 use unordered_map/sorted_vector in registerAndCheck()
    
    which is little more memory expensive, but about 10% more efficient in load
    time here.
    
    Change-Id: If1cfb7dfe3b6a70f5acf8766db4b83eb386030bf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196063
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit b0920fbf83957a245292ea23840d79e0c6385429)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196358
    Reviewed-by: Noel Grandin <[email protected]>
    Tested-by: Jenkins

diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx
index 533714d1e119..0bf555bdaa93 100644
--- a/sc/inc/patattr.hxx
+++ b/sc/inc/patattr.hxx
@@ -25,11 +25,12 @@
 #include <svl/languageoptions.hxx>
 #include <tools/degree.hxx>
 #include <editeng/svxenum.hxx>
+#include <o3tl/sorted_vector.hxx>
 #include "scdllapi.h"
 #include "fonthelper.hxx"
 #include "scitems.hxx"
 #include "attrib.hxx"
-#include <set>
+#include <unordered_map>
 
 namespace vcl { class Font; }
 namespace model { class ComplexColor; }
@@ -62,20 +63,16 @@ class SC_DLLPUBLIC CellAttributeHelper final
     // Data structure chosen so that
     // (a) we can find by name
     // (b) we can erase quickly, by using name and pointer.
-    // so we sort the set first by name, and then by pointer.
-    struct RegisteredAttrSetLess
+    // (c) scanning through all the entries with the same name is cheap
+    struct RegisteredAttrMapHash
     {
-        bool operator()(const ScPatternAttr* lhs, const ScPatternAttr* rhs) 
const;
-        // so we can search in std::set without a ScPatternAttr
-        using is_transparent = void;
-        bool operator()(const ScPatternAttr* lhs, const OUString* rhs) const;
-        bool operator()(const OUString* lhs, const ScPatternAttr* rhs) const;
+        size_t operator()(const std::optional<OUString>&) const;
     };
-    typedef std::set<const ScPatternAttr*, RegisteredAttrSetLess> 
RegisteredAttrSet;
+    typedef std::unordered_map<std::optional<OUString>, 
o3tl::sorted_vector<const ScPatternAttr*>, RegisteredAttrMapHash> 
RegisteredAttrMap;
 
     SfxItemPool&                                        mrSfxItemPool;
     mutable ScPatternAttr*                              mpDefaultCellAttribute;
-    mutable RegisteredAttrSet                           
maRegisteredCellAttributes;
+    mutable RegisteredAttrMap                           
maRegisteredCellAttributes;
     mutable const ScPatternAttr*                        mpLastHit;
     mutable sal_uInt64                                  mnCurrentMaxKey;
 
diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index b6c738227b47..d3532ebb7ff8 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -80,17 +80,6 @@ CellAttributeHelper::~CellAttributeHelper()
     delete mpDefaultCellAttribute;
 }
 
-static int CompareStringPtr(const OUString* lhs, const OUString* rhs)
-{
-    if (lhs == rhs)
-        return 0;
-    if (lhs && rhs)
-        return (*lhs).compareTo(*rhs);
-    if (!lhs && rhs)
-        return -1;
-    return 1;
-}
-
 const ScPatternAttr* CellAttributeHelper::registerAndCheck(const 
ScPatternAttr& rCandidate, bool bPassingOwnership) const
 {
     if (&rCandidate == &getDefaultCellAttribute())
@@ -114,28 +103,29 @@ const ScPatternAttr* 
CellAttributeHelper::registerAndCheck(const ScPatternAttr&
         return mpLastHit;
     }
     const OUString* pCandidateStyleName = rCandidate.GetStyleName();
-    auto it = maRegisteredCellAttributes.lower_bound(pCandidateStyleName);
-    const size_t nCandidateHashCode = rCandidate.GetHashCode();
-    for (; it != maRegisteredCellAttributes.end(); ++it)
+    auto it = maRegisteredCellAttributes.find(pCandidateStyleName ? 
std::optional<OUString>(*pCandidateStyleName) : std::nullopt);
+    if (it != maRegisteredCellAttributes.end())
     {
-        const ScPatternAttr* pCheck = *it;
-        if (CompareStringPtr(pCheck->GetStyleName(), pCandidateStyleName) != 0)
-            break;
-        if (nCandidateHashCode == pCheck->GetHashCode()
-            && ScPatternAttr::areSame(pCheck, &rCandidate))
+        const size_t nCandidateHashCode = rCandidate.GetHashCode();
+        for (const ScPatternAttr* pCheck : it->second)
         {
-            pCheck->mnRefCount++;
-            if (bPassingOwnership)
-                delete &rCandidate;
-            mpLastHit = pCheck;
-            return pCheck;
+            if (nCandidateHashCode == pCheck->GetHashCode()
+                && ScPatternAttr::areSame(pCheck, &rCandidate))
+            {
+                pCheck->mnRefCount++;
+                if (bPassingOwnership)
+                    delete &rCandidate;
+                mpLastHit = pCheck;
+                return pCheck;
+            }
         }
     }
 
     const ScPatternAttr* pCandidate(bPassingOwnership ? &rCandidate : new 
ScPatternAttr(rCandidate));
     pCandidate->mnRefCount++;
     const_cast<ScPatternAttr*>(pCandidate)->SetPAKey(mnCurrentMaxKey++);
-    maRegisteredCellAttributes.insert(pCandidate);
+    const OUString* pStyleName = pCandidate->GetStyleName();
+    maRegisteredCellAttributes[pStyleName ? 
std::optional<OUString>(*pStyleName) : std::nullopt].insert(pCandidate);
     mpLastHit = pCandidate;
     return pCandidate;
 }
@@ -154,8 +144,12 @@ void CellAttributeHelper::doUnregister(const 
ScPatternAttr& rCandidate)
     if (mpLastHit == &rCandidate)
         mpLastHit = nullptr;
 
-    assert(maRegisteredCellAttributes.find(&rCandidate) != 
maRegisteredCellAttributes.end());
-    maRegisteredCellAttributes.erase(&rCandidate);
+    const OUString* pStyleName = rCandidate.GetStyleName();
+    auto it = maRegisteredCellAttributes.find(pStyleName ? 
std::optional<OUString>(*pStyleName) : std::nullopt);
+    assert(it != maRegisteredCellAttributes.end());
+    it->second.erase(&rCandidate);
+    if (it->second.empty())
+        maRegisteredCellAttributes.erase(it);
     delete &rCandidate;
 }
 
@@ -188,15 +182,13 @@ const ScPatternAttr& 
CellAttributeHelper::getDefaultCellAttribute() const
 void CellAttributeHelper::CellStyleDeleted(const ScStyleSheet& rStyle)
 {
     const OUString& rCandidateStyleName = rStyle.GetName();
-    auto it = maRegisteredCellAttributes.lower_bound(&rCandidateStyleName);
-    for (; it != maRegisteredCellAttributes.end(); ++it)
-    {
-        const ScPatternAttr* pCheck = *it;
-        if (CompareStringPtr(pCheck->GetStyleName(), &rCandidateStyleName) != 
0)
-            break;
-        if (&rStyle == pCheck->GetStyleSheet())
-            const_cast<ScPatternAttr*>(pCheck)->StyleToName();
-    }
+    auto it = maRegisteredCellAttributes.find(rCandidateStyleName);
+    if (it != maRegisteredCellAttributes.end())
+        for (const ScPatternAttr* pCheck : it->second)
+        {
+            if (&rStyle == pCheck->GetStyleSheet())
+                const_cast<ScPatternAttr*>(pCheck)->StyleToName();
+        }
 }
 
 void CellAttributeHelper::RenameCellStyle(ScStyleSheet& rStyle, const 
OUString& rNewName)
@@ -204,26 +196,32 @@ void CellAttributeHelper::RenameCellStyle(ScStyleSheet& 
rStyle, const OUString&
     std::vector<const ScPatternAttr*> aChanged;
 
     const OUString& rCandidateStyleName = rStyle.GetName();
-    auto it = maRegisteredCellAttributes.lower_bound(&rCandidateStyleName);
-    while(it != maRegisteredCellAttributes.end())
+    auto it = maRegisteredCellAttributes.find(rCandidateStyleName);
+    if (it != maRegisteredCellAttributes.end())
     {
-        const ScPatternAttr* pCheck = *it;
-        if (CompareStringPtr(pCheck->GetStyleName(), &rCandidateStyleName) != 
0)
-            break;
-        if (&rStyle == pCheck->GetStyleSheet())
+        for (auto it2 = it->second.begin(); it2 != it->second.end();)
         {
-            aChanged.push_back(pCheck);
-            // The name will change, we have to re-insert it
-            it = maRegisteredCellAttributes.erase(it);
+            const ScPatternAttr* pCheck = *it2;
+            if (&rStyle == pCheck->GetStyleSheet())
+            {
+                aChanged.push_back(pCheck);
+                // The name will change, we have to re-insert it
+                it2 = it->second.erase(it2);
+            }
+            else
+                ++it2;
         }
-        else
-            ++it;
+        if (it->second.empty())
+            maRegisteredCellAttributes.erase(it);
     }
 
     rStyle.SetName(rNewName);
 
     for (const ScPatternAttr* p : aChanged)
-        maRegisteredCellAttributes.insert(p);
+    {
+        const OUString* pStyleName = p->GetStyleName();
+        maRegisteredCellAttributes[pStyleName ? 
std::optional<OUString>(*pStyleName) : std::nullopt].insert(p);
+    }
 }
 
 void CellAttributeHelper::CellStyleCreated(const ScDocument& rDoc, const 
OUString& rName)
@@ -233,12 +231,13 @@ void CellAttributeHelper::CellStyleCreated(const 
ScDocument& rDoc, const OUStrin
     // Calling StyleSheetChanged isn't enough because the pool may still 
contain items
     // for undo or clipboard content.
     std::vector<const ScPatternAttr*> aChanged;
-    auto it = maRegisteredCellAttributes.lower_bound(&rName);
-    while(it != maRegisteredCellAttributes.end())
+    auto it = maRegisteredCellAttributes.find(rName);
+    if (it == maRegisteredCellAttributes.end())
+        return;
+
+    for (auto it2 = it->second.begin(); it2 != it->second.end();)
     {
-        const ScPatternAttr* pCheck = *it;
-        if (CompareStringPtr(pCheck->GetStyleName(), &rName) != 0)
-            break;
+        const ScPatternAttr* pCheck = *it2;
         // tdf#163831 Invalidate cache if the style is modified/created
         const_cast<ScPatternAttr*>(pCheck)->InvalidateCaches();
         if (nullptr == pCheck->GetStyleSheet())
@@ -246,22 +245,29 @@ void CellAttributeHelper::CellStyleCreated(const 
ScDocument& rDoc, const OUStrin
             {
                 aChanged.push_back(pCheck);
                 // if the name changed, we have to re-insert it
-                it = maRegisteredCellAttributes.erase(it);
+                it2 = it->second.erase(it2);
             }
             else
-                ++it;
+                ++it2;
         else
-            ++it;
+            ++it2;
     }
+    if (it->second.empty())
+        maRegisteredCellAttributes.erase(it);
+
     for (const ScPatternAttr* p : aChanged)
-        maRegisteredCellAttributes.insert(p);
+    {
+        const OUString* pStyleName = p->GetStyleName();
+        maRegisteredCellAttributes[pStyleName ? 
std::optional<OUString>(*pStyleName) : std::nullopt].insert(p);
+    }
 }
 
 void CellAttributeHelper::UpdateAllStyleSheets(const ScDocument& rDoc)
 {
     bool bNameChanged = false;
-    for (const ScPatternAttr* pCheck : maRegisteredCellAttributes)
-        bNameChanged |= 
const_cast<ScPatternAttr*>(pCheck)->UpdateStyleSheet(rDoc);
+    for (const auto & rPair : maRegisteredCellAttributes)
+        for (const ScPatternAttr* pCheck : rPair.second)
+            bNameChanged |= 
const_cast<ScPatternAttr*>(pCheck)->UpdateStyleSheet(rDoc);
     if (bNameChanged)
         ReIndexRegistered();
 
@@ -272,8 +278,9 @@ void CellAttributeHelper::UpdateAllStyleSheets(const 
ScDocument& rDoc)
 
 void CellAttributeHelper::AllStylesToNames()
 {
-    for (const ScPatternAttr* pCheck : maRegisteredCellAttributes)
-        const_cast<ScPatternAttr*>(pCheck)->StyleToName();
+    for (const auto & rPair : maRegisteredCellAttributes)
+        for (const ScPatternAttr* pCheck : rPair.second)
+            const_cast<ScPatternAttr*>(pCheck)->StyleToName();
 
     // force existence, then access
     getDefaultCellAttribute();
@@ -283,38 +290,22 @@ void CellAttributeHelper::AllStylesToNames()
 /// If the style name changed, we need to reindex.
 void CellAttributeHelper::ReIndexRegistered()
 {
-    RegisteredAttrSet aNewSet;
-    for (auto const & p : maRegisteredCellAttributes)
-        aNewSet.insert(p);
-    maRegisteredCellAttributes = std::move(aNewSet);
-}
+    RegisteredAttrMap aNewMap;
+    for (const auto & rPair : maRegisteredCellAttributes)
+        for (const ScPatternAttr* p : rPair.second)
+        {
+            const OUString* pStyleName = p->GetStyleName();
+            aNewMap[pStyleName ? std::optional<OUString>(*pStyleName) : 
std::nullopt].insert(p);
+        }
 
-bool CellAttributeHelper::RegisteredAttrSetLess::operator()(const 
ScPatternAttr* lhs, const ScPatternAttr* rhs) const
-{
-    int cmp = CompareStringPtr(lhs->GetStyleName(), rhs->GetStyleName());
-    if (cmp < 0)
-        return true;
-    if (cmp > 0)
-        return false;
-    return lhs < rhs;
-}
-bool CellAttributeHelper::RegisteredAttrSetLess::operator()(const 
ScPatternAttr* lhs, const OUString* rhs) const
-{
-    int cmp = CompareStringPtr(lhs->GetStyleName(), rhs);
-    if (cmp < 0)
-        return true;
-    if (cmp > 0)
-        return false;
-    return false;
+    maRegisteredCellAttributes = std::move(aNewMap);
 }
-bool CellAttributeHelper::RegisteredAttrSetLess::operator()(const OUString* 
lhs, const ScPatternAttr* rhs) const
+
+size_t CellAttributeHelper::RegisteredAttrMapHash::operator()(const 
std::optional<OUString>& p) const
 {
-    int cmp = CompareStringPtr(lhs, rhs->GetStyleName());
-    if (cmp < 0)
-        return true;
-    if (cmp > 0)
-        return false;
-    return true;
+    if (!p)
+        return 0;
+    return p->hashCode();
 }
 
 
commit 35111f56983b68523d53298d29a7051309aa469c
Author:     Noel Grandin <[email protected]>
AuthorDate: Sun Dec 21 19:55:04 2025 +0200
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:34 2026 +0100

    tdf#166684 use hashing in CellAttributeHelper::registerAndCheck
    
    reduces load time from 1m11s to 33s.
    
    Change-Id: I911c101eb8692bf678e6f7147e64e503e9f2bf0a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196062
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    (cherry picked from commit 044885e896a441c96a6934b10cbb723fabcf262d)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196357
    Reviewed-by: Noel Grandin <[email protected]>
    Tested-by: Jenkins

diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 118e3da7f036..7dd32ff77791 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -246,6 +246,7 @@ public:
     const SfxItemSet*           GetParent() const { return m_pParent; }
 
     bool                        operator==(const SfxItemSet &) const;
+    size_t                      GetHashCode() const;
 
     /** Compare possibly ignoring SfxItemPool pointer.
 
diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx
index 3d47591a13b0..533714d1e119 100644
--- a/sc/inc/patattr.hxx
+++ b/sc/inc/patattr.hxx
@@ -130,6 +130,7 @@ class SAL_DLLPUBLIC_RTTI ScPatternAttr final
     friend class CellAttributeHelper;
 
     SfxItemSet                  maLocalSfxItemSet;
+    mutable std::optional<size_t> moHashCode;
     std::optional<OUString>     moName;
     mutable std::optional<bool> mxVisible;
     mutable std::optional<sal_uInt32> mxNumberFormatKey;
@@ -149,6 +150,7 @@ public:
     SC_DLLPUBLIC ~ScPatternAttr();
 
     bool operator==(const ScPatternAttr& rCmp) const;
+    size_t GetHashCode() const { if (!moHashCode) CalcHashCode(); return 
*moHashCode; }
 
     // version that allows nullptrs
     SC_DLLPUBLIC static bool areSame(const ScPatternAttr* pItem1, const 
ScPatternAttr* pItem2);
@@ -291,6 +293,7 @@ private:
     LanguageType            GetLanguageType() const;
     void                    InvalidateCaches();
     void                    InvalidateCacheFor(sal_uInt16 nWhich);
+    void                    CalcHashCode() const;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index 9870c56db403..b6c738227b47 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -115,12 +115,14 @@ const ScPatternAttr* 
CellAttributeHelper::registerAndCheck(const ScPatternAttr&
     }
     const OUString* pCandidateStyleName = rCandidate.GetStyleName();
     auto it = maRegisteredCellAttributes.lower_bound(pCandidateStyleName);
+    const size_t nCandidateHashCode = rCandidate.GetHashCode();
     for (; it != maRegisteredCellAttributes.end(); ++it)
     {
         const ScPatternAttr* pCheck = *it;
         if (CompareStringPtr(pCheck->GetStyleName(), pCandidateStyleName) != 0)
             break;
-        if (ScPatternAttr::areSame(pCheck, &rCandidate))
+        if (nCandidateHashCode == pCheck->GetHashCode()
+            && ScPatternAttr::areSame(pCheck, &rCandidate))
         {
             pCheck->mnRefCount++;
             if (bPassingOwnership)
@@ -472,6 +474,15 @@ bool ScPatternAttr::operator==(const ScPatternAttr& rCmp) 
const
     return maLocalSfxItemSet == rCmp.maLocalSfxItemSet;
 }
 
+void ScPatternAttr::CalcHashCode() const
+{
+    size_t nHash = 0;
+    if (const OUString* pName = GetStyleName())
+        nHash = pName->hashCode();
+    o3tl::hash_combine(nHash, maLocalSfxItemSet.GetHashCode());
+    moHashCode = nHash;
+}
+
 bool ScPatternAttr::areSame(const ScPatternAttr* pItem1, const ScPatternAttr* 
pItem2)
 {
     if (pItem1 == pItem2)
@@ -1839,6 +1850,7 @@ void ScPatternAttr::InvalidateCaches()
     mxVisible.reset();
     mxNumberFormatKey.reset();
     mxLanguageType.reset();
+    moHashCode.reset();
 }
 
 SfxItemSet& ScPatternAttr::GetItemSetWritable()
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 5a7efdac8708..ae60b661a8ff 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -27,6 +27,7 @@
 
 #include <libxml/xmlwriter.h>
 #include <tools/XmlWriter.hxx>
+#include <o3tl/hash_combine.hxx>
 
 #include <sal/log.hxx>
 #include <svl/itemset.hxx>
@@ -1289,6 +1290,24 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool 
bComparePool) const
     return true;
 }
 
+size_t SfxItemSet::GetHashCode() const
+{
+    size_t seed = 0;
+
+    for (PoolItemMap::const_iterator it(m_aPoolItemMap.begin()); it != 
m_aPoolItemMap.end(); it++)
+    {
+        const sal_uInt16 nWhich = it->first;
+        const SfxPoolItem *pItem = it->second;
+
+        o3tl::hash_combine(seed, nWhich);
+        if (!IsInvalidItem(pItem) && !IsDisabledItem(pItem)
+            && pItem && pItem->supportsHashCode())
+            o3tl::hash_combine(seed, pItem->hashCode());
+    }
+
+    return seed;
+}
+
 std::unique_ptr<SfxItemSet> SfxItemSet::Clone(bool bItems, SfxItemPool 
*pToPool ) const
 {
     if (pToPool && pToPool != GetPool())
commit 83f640ffd325b875bae30aa987fc3958e2071f62
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Sun Dec 7 00:06:17 2025 +0900
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:34 2026 +0100

    switch some dumpAsXml functions to use tools::XmlWriter
    
    Change-Id: I6bcda888f578ec52c05a575df56c4c267ad82ccc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195169
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/editeng/source/items/frmitems.cxx 
b/editeng/source/items/frmitems.cxx
index b3742fc9b06c..b397d4e4dff7 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -50,6 +50,7 @@
 #include <tools/debug.hxx>
 #include <tools/mapunit.hxx>
 #include <tools/UnitConversion.hxx>
+#include <tools/XmlWriter.hxx>
 #include <vcl/graphicfilter.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/svapp.hxx>
@@ -1022,11 +1023,12 @@ bool SvxLeftMarginItem::HasMetrics() const
 
 void SvxLeftMarginItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxLeftMarginItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nLeftMargin"), 
BAD_CAST(OString::number(m_nLeftMargin).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nPropLeftMargin"), 
BAD_CAST(OString::number(m_nPropLeftMargin).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SvxLeftMarginItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("m_nLeftMargin", m_nLeftMargin);
+    aWriter.attribute("m_nPropLeftMargin", m_nPropLeftMargin);
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree SvxLeftMarginItem::dumpAsJSON() const
@@ -2806,13 +2808,14 @@ bool SvxShadowItem::HasMetrics() const
 
 void SvxShadowItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxShadowItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aShadowColor"), 
BAD_CAST(aShadowColor.AsRGBHexString().toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), 
BAD_CAST(OString::number(nWidth).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLocation"), 
BAD_CAST(OString::number(static_cast<int>(eLocation)).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), 
BAD_CAST(EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]).toUtf8().getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SvxShadowItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("aShadowColor", aShadowColor.AsRGBHexString());
+    aWriter.attribute("nWidth", nWidth);
+    aWriter.attribute("eLocation", sal_Int32(eLocation));
+    aWriter.attribute("presentation", 
EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]));
+    aWriter.endElement();
 }
 
 // class SvxBoxItem ------------------------------------------------------
@@ -2845,17 +2848,14 @@ SvxBoxItem::~SvxBoxItem()
 
 void SvxBoxItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBoxItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("top-dist"),
-                                      
BAD_CAST(OString::number(mnTopDistance).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bottom-dist"),
-                                      
BAD_CAST(OString::number(mnBottomDistance).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("left-dist"),
-                                      
BAD_CAST(OString::number(mnLeftDistance).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("right-dist"),
-                                      
BAD_CAST(OString::number(mnRightDistance).getStr()));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SvxBoxItem");
+    aWriter.attribute("top-dist", mnTopDistance);
+    aWriter.attribute("bottom-dist", mnBottomDistance);
+    aWriter.attribute("left-dist", mnLeftDistance);
+    aWriter.attribute("right-dist", mnRightDistance);
     SfxPoolItem::dumpAsXml(pWriter);
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree SvxBoxItem::dumpAsJSON() const
@@ -4373,11 +4373,10 @@ bool SvxFormatKeepItem::GetPresentation
 
 void SvxFormatKeepItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFormatKeepItem"));
-
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SvxFormatKeepItem");
     SfxBoolItem::dumpAsXml(pWriter);
-
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 SvxLineItem::SvxLineItem( const sal_uInt16 nId ) :
@@ -5138,16 +5137,17 @@ void SvxBrushItem::ApplyGraphicTransparency_Impl()
 
 void SvxBrushItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBrushItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"), 
BAD_CAST(aColor.AsRGBHexString().toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filtercolor"), 
BAD_CAST(aFilterColor.AsRGBHexString().toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("shadingValue"), 
BAD_CAST(OString::number(nShadingValue).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("link"), 
BAD_CAST(maStrLink.toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filter"), 
BAD_CAST(maStrFilter.toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("graphicPos"), 
BAD_CAST(OString::number(eGraphicPos).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("loadAgain"), 
BAD_CAST(OString::boolean(bLoadAgain).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SvxBrushItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("color", aColor.AsRGBHexString());
+    aWriter.attribute("filtercolor", aFilterColor.AsRGBHexString());
+    aWriter.attribute("shadingValue", nShadingValue);
+    aWriter.attribute("link", maStrLink);
+    aWriter.attribute("filter", maStrFilter);
+    aWriter.attribute("graphicPos", eGraphicPos);
+    aWriter.attribute("loadAgain", bLoadAgain);
+    aWriter.endElement();
 }
 
 ItemInstanceManager* SvxFrameDirectionItem::getItemInstanceManager() const
@@ -5290,13 +5290,11 @@ bool SvxFrameDirectionItem::QueryValue( css::uno::Any& 
rVal,
 
 void SvxFrameDirectionItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, 
BAD_CAST("SvxFrameDirectionItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nWhich"),
-                                BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(
-        pWriter, BAD_CAST("m_nValue"),
-        
BAD_CAST(OString::number(static_cast<sal_Int16>(GetValue())).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SvxFrameDirectionItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("m_nValue", sal_Int16(GetValue()));
+    aWriter.endElement();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/cenumitm.cxx b/svl/source/items/cenumitm.cxx
index 8da04d98df67..849ce0307635 100644
--- a/svl/source/items/cenumitm.cxx
+++ b/svl/source/items/cenumitm.cxx
@@ -23,6 +23,7 @@
 #include <unordered_map>
 #include <comphelper/extract.hxx>
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <sal/log.hxx>
 
 
@@ -196,10 +197,11 @@ bool SfxBoolItem::GetPresentation(SfxItemPresentation,
 
 void SfxBoolItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxBoolItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(GetValueTextByVal(m_bValue).toUtf8().getStr()));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxBoolItem");
+    aWriter.attribute("value", GetValueTextByVal(m_bValue));
     SfxPoolItem::dumpAsXml(pWriter);
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 // virtual
diff --git a/svl/source/items/intitem.cxx b/svl/source/items/intitem.cxx
index 0ced3eb20146..02acd395d137 100644
--- a/svl/source/items/intitem.cxx
+++ b/svl/source/items/intitem.cxx
@@ -17,18 +17,16 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-
 #include <svl/intitem.hxx>
 #include <com/sun/star/uno/Any.hxx>
 #include <osl/diagnose.h>
 #include <tools/bigint.hxx>
 #include <svl/metitem.hxx>
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <boost/property_tree/ptree.hpp>
 
 
-
-
 SfxPoolItem* SfxByteItem::CreateDefault()
 {
     return new SfxByteItem();
@@ -100,10 +98,11 @@ SfxPoolItem* SfxUInt16Item::CreateDefault()
 
 void SfxUInt16Item::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxUInt16Item"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxUInt16Item");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree SfxUInt16Item::dumpAsJSON() const
@@ -123,10 +122,11 @@ SfxPoolItem* SfxInt32Item::CreateDefault()
 
 void SfxInt32Item::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxInt32Item"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxInt32Item");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree SfxInt32Item::dumpAsJSON() const
@@ -146,10 +146,11 @@ SfxPoolItem* SfxUInt32Item::CreateDefault()
 
 void SfxUInt32Item::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxUInt32Item"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxUInt32Item");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree SfxUInt32Item::dumpAsJSON() const
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 3c0d1cbd4783..5a7efdac8708 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -26,6 +26,7 @@
 #include <unordered_map>
 
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 
 #include <sal/log.hxx>
 #include <svl/itemset.hxx>
@@ -1344,21 +1345,22 @@ SfxItemSet SfxItemSet::CloneAsValue(bool bItems, 
SfxItemPool *pToPool ) const
 
 void SfxItemSet::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxItemSet"));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxItemSet");
     SfxItemIter aIter(*this);
     for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = 
aIter.NextItem())
     {
         if (IsInvalidItem(pItem))
         {
-            (void)xmlTextWriterStartElement(pWriter, BAD_CAST("invalid"));
-            (void)xmlTextWriterEndElement(pWriter);
+            aWriter.startElement("invalid");
+            aWriter.endElement();
         }
         else
         {
             pItem->dumpAsXml(pWriter);
         }
     }
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 
diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx
index 3bb040372f29..393554df1ac8 100644
--- a/svl/source/items/poolitem.cxx
+++ b/svl/source/items/poolitem.cxx
@@ -23,6 +23,7 @@
 #include <osl/diagnose.h>
 #include <sal/log.hxx>
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <typeinfo>
 #include <boost/property_tree/ptree.hpp>
 
@@ -187,19 +188,20 @@ bool SfxPoolItem::GetPresentation(
 
 void SfxPoolItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxPoolItem"));
-    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", 
this);
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"),
-                                      
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("typeName"),
-                                      BAD_CAST(typeid(*this).name()));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxPoolItem");
+    aWriter.attribute("ptr", reinterpret_cast<sal_IntPtr>(this));
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("typeName", typeid(*this).name());
+
     OUString rText;
     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
     if (GetPresentation(SfxItemPresentation::Complete, MapUnit::Map100thMM, 
MapUnit::Map100thMM,
                         rText, aIntlWrapper))
-        (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"),
-                                          BAD_CAST(rText.toUtf8().getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    {
+        aWriter.attribute("presentation", rText);
+    }
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree SfxPoolItem::dumpAsJSON() const
diff --git a/svl/source/items/stritem.cxx b/svl/source/items/stritem.cxx
index 0c6b8be1763d..fef4d404a486 100644
--- a/svl/source/items/stritem.cxx
+++ b/svl/source/items/stritem.cxx
@@ -19,6 +19,7 @@
 
 #include <svl/stritem.hxx>
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <com/sun/star/uno/Any.hxx>
 #include <osl/diagnose.h>
 #include <unotools/intlwrapper.hxx>
@@ -70,10 +71,11 @@ SfxStringItem* SfxStringItem::Clone(SfxItemPool *) const
 
 void SfxStringItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxStringItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(GetValue().toUtf8().getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxStringItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 SfxPoolItem* SfxStringItem::CreateDefault()
diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx
index 97a183bb05a8..fefcd02c78dd 100644
--- a/svl/source/items/style.cxx
+++ b/svl/source/items/style.cxx
@@ -20,6 +20,7 @@
 #include <memory>
 
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 
 #include <svl/style.hxx>
 
@@ -273,14 +274,13 @@ std::optional<SfxItemSet> 
SfxStyleSheetBase::GetItemSetForPreview()
 
 void SfxStyleSheetBase::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxStyleSheetBase"));
-    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", 
this);
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), 
BAD_CAST(aName.toUtf8().getStr()));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxStyleSheetBase");
+    aWriter.attribute("ptr", reinterpret_cast<sal_IntPtr>(this));
+    aWriter.attribute("name", aName);
     if (pSet)
-    {
         pSet->dumpAsXml(pWriter);
-    }
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 /**
@@ -694,17 +694,15 @@ void SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& 
rSheet )
 
 void SfxStyleSheetBasePool::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, 
BAD_CAST("SfxStyleSheetBasePool"));
-    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", 
this);
-
-    std::shared_ptr<SfxStyleSheetIterator> aSSSI
-        = std::make_shared<SfxStyleSheetIterator>(this, SfxStyleFamily::All);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxStyleSheetBasePool");
+    aWriter.attribute("ptr", reinterpret_cast<sal_IntPtr>(this));
+    auto aSSSI = std::make_shared<SfxStyleSheetIterator>(this, 
SfxStyleFamily::All);
     for (SfxStyleSheetBase* pStyle = aSSSI->First(); pStyle; pStyle = 
aSSSI->Next())
     {
         pStyle->dumpAsXml(pWriter);
     }
-
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const 
SfxStyleSheetBasePool& r )
diff --git a/svl/source/items/voiditem.cxx b/svl/source/items/voiditem.cxx
index 6bda725d0fcd..df1503dc7473 100644
--- a/svl/source/items/voiditem.cxx
+++ b/svl/source/items/voiditem.cxx
@@ -19,6 +19,7 @@
 
 #include <svl/voiditem.hxx>
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <sal/log.hxx>
 
 SfxPoolItem* SfxVoidItem::CreateDefault() { return new SfxVoidItem(0); }
@@ -59,10 +60,10 @@ bool SfxVoidItem::GetPresentation(SfxItemPresentation 
/*ePresentation*/, MapUnit
 
 void SfxVoidItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxVoidItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"),
-                                      
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxVoidItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.endElement();
 }
 
 SfxVoidItem* SfxVoidItem::Clone(SfxItemPool*) const { return new 
SfxVoidItem(*this); }
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index 8986ff76d7ac..4972a119491f 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -25,6 +25,7 @@
 #include <comphelper/diagnose_ex.hxx>
 #include <tools/long.hxx>
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <boost/property_tree/json_parser.hpp>
 #include <unotools/datetime.hxx>
 
@@ -146,13 +147,14 @@ bool SfxUndoAction::CanRepeat(SfxRepeatTarget&) const
 
 void SfxUndoAction::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxUndoAction"));
-    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", 
this);
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("symbol"), 
BAD_CAST(typeid(*this).name()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("comment"), 
BAD_CAST(GetComment().toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("viewShellId"), 
BAD_CAST(OString::number(static_cast<sal_Int32>(GetViewShellId())).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("dateTime"), 
BAD_CAST(utl::toISO8601(m_aDateTime.GetUNODateTime()).toUtf8().getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxUndoAction");
+    aWriter.attribute("ptr", reinterpret_cast<sal_IntPtr>(this));
+    aWriter.attribute("symbol", typeid(*this).name());
+    aWriter.attribute("comment", GetComment());
+    aWriter.attribute("viewShellId", sal_Int32(GetViewShellId()));
+    aWriter.attribute("dateTime", 
utl::toISO8601(m_aDateTime.GetUNODateTime()));
+    aWriter.endElement();
 }
 
 std::unique_ptr<SfxUndoAction> SfxUndoArray::Remove(int idx)
@@ -1205,27 +1207,27 @@ void SfxUndoManager::dumpAsXml(xmlTextWriterPtr 
pWriter) const
         bOwns = true;
     }
 
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxUndoManager"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUndoActionCount"), 
BAD_CAST(OString::number(GetUndoActionCount()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRedoActionCount"), 
BAD_CAST(OString::number(GetRedoActionCount()).getStr()));
-
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("undoActions"));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxUndoManager");
+    aWriter.attribute("nUndoActionCount", GetUndoActionCount());
+    aWriter.attribute("nRedoActionCount", GetRedoActionCount());
+    aWriter.startElement("undoActions");
     for (size_t i = 0; i < GetUndoActionCount(); ++i)
     {
         const SfxUndoArray* pUndoArray = m_xData->pActUndoArray;
         pUndoArray->maUndoActions[pUndoArray->nCurUndoAction - 1 - 
i].pAction->dumpAsXml(pWriter);
     }
-    (void)xmlTextWriterEndElement(pWriter);
-
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("redoActions"));
+    aWriter.endElement();
+    aWriter.startElement("redoActions");
     for (size_t i = 0; i < GetRedoActionCount(); ++i)
     {
         const SfxUndoArray* pUndoArray = m_xData->pActUndoArray;
         pUndoArray->maUndoActions[pUndoArray->nCurUndoAction + 
i].pAction->dumpAsXml(pWriter);
     }
-    (void)xmlTextWriterEndElement(pWriter);
 
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
+    aWriter.endElement();
+
     if (bOwns)
     {
         (void)xmlTextWriterEndDocument(pWriter);
@@ -1417,14 +1419,13 @@ bool SfxListUndoAction::Merge( SfxUndoAction 
*pNextAction )
 
 void SfxListUndoAction::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxListUndoAction"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), 
BAD_CAST(OString::number(maUndoActions.size()).getStr()));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("SfxListUndoAction");
+    aWriter.attribute("size", maUndoActions.size());
     SfxUndoAction::dumpAsXml(pWriter);
-
     for (size_t i = 0; i < maUndoActions.size(); ++i)
         maUndoActions[i].pAction->dumpAsXml(pWriter);
-
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 SfxUndoArray::~SfxUndoArray()
diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx
index 39dc2e26370c..9abb2ad79755 100644
--- a/svx/source/xoutdev/xattr.cxx
+++ b/svx/source/xoutdev/xattr.cxx
@@ -89,6 +89,7 @@
 #include <unotools/intlwrapper.hxx>
 #include <unotools/syslocale.hxx>
 #include <string>
+#include <tools/XmlWriter.hxx>
 
 #include <boost/property_tree/ptree.hpp>
 #include <libxml/xmlwriter.h>
@@ -260,12 +261,13 @@ OUString NameOrIndex::CheckNamedItem(const sal_uInt16 
nWhich, const SfxItemPool*
 
 void NameOrIndex::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("NameOrIndex"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("isIndex"), 
BAD_CAST(OString::boolean(IsIndex()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), 
BAD_CAST(GetName().toUtf8().getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("index"), 
BAD_CAST(OString::number(m_nPalIndex).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("NameOrIndex");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("isIndex", IsIndex());
+    aWriter.attribute("name", GetName());
+    aWriter.attribute("index", GetPalIndex());
+    aWriter.endElement();
 }
 
 SfxPoolItem* XColorItem::CreateDefault() { return new XColorItem(); }
@@ -383,38 +385,32 @@ bool XColorItem::PutValue( const css::uno::Any& rVal, 
sal_uInt8 nMemberId)
 
 void XColorItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XColorItem"));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XColorItem");
     if (Which() == SDRATTR_SHADOWCOLOR)
     {
-        (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST("SDRATTR_SHADOWCOLOR"));
+        aWriter.attribute("whichId", "SDRATTR_SHADOWCOLOR");
     }
     else if (Which() == XATTR_FILLCOLOR)
     {
-        (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST("XATTR_FILLCOLOR"));
+        aWriter.attribute("whichId", "XATTR_FILLCOLOR");
     }
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aColor"),
-                                
BAD_CAST(m_aColor.AsRGBHexString().toUtf8().getStr()));
+    aWriter.attribute("color", m_aColor.AsRGBHexString());
 
     NameOrIndex::dumpAsXml(pWriter);
 
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("complex-color"));
-
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("scheme-index"),
-                                      
BAD_CAST(OString::number(sal_Int16(maComplexColor.getThemeColorType())).getStr()));
-
+    aWriter.startElement("ComplexColor");
+    aWriter.attribute("scheme_index", 
sal_Int16(maComplexColor.getThemeColorType()));
     for (auto const& rTransform : maComplexColor.getTransformations())
     {
-        (void)xmlTextWriterStartElement(pWriter, BAD_CAST("transformation"));
-        (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("type"),
-                                      
BAD_CAST(OString::number(sal_Int16(rTransform.meType)).getStr()));
-        (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
-                                      
BAD_CAST(OString::number(rTransform.mnValue).getStr()));
-        (void)xmlTextWriterEndElement(pWriter);
+        aWriter.startElement("transformation");
+        aWriter.attribute("type", sal_Int16(rTransform.meType));
+        aWriter.attribute("value", rTransform.mnValue);
+        aWriter.endElement();
     }
 
-    (void)xmlTextWriterEndElement(pWriter);
-
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement(); // complex-color
+    aWriter.endElement(); // XColorItem
 }
 
 // --- line attributes ---
@@ -1765,16 +1761,17 @@ bool XFillStyleItem::PutValue( const css::uno::Any& 
rVal, sal_uInt8 /*nMemberId*
 
 void XFillStyleItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillStyleItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(static_cast<sal_Int16>(GetValue())).getStr()));
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillStyleItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", sal_Int16(GetValue()));
 
     OUString aPresentation;
     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
     GetPresentation(SfxItemPresentation::Nameless, MapUnit::Map100thMM, 
MapUnit::Map100thMM, aPresentation, aIntlWrapper);
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), 
BAD_CAST(aPresentation.toUtf8().getStr()));
+    aWriter.attribute("presentation", aPresentation);
 
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree XFillStyleItem::dumpAsJSON() const
@@ -1964,12 +1961,12 @@ bool XFillColorItem::PutValue( const css::uno::Any& 
rVal, sal_uInt8 nMemberId )
 
 void XFillColorItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillColorItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillColorItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
     XColorItem::dumpAsXml(pWriter);
-
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree XFillColorItem::dumpAsJSON() const
diff --git a/svx/source/xoutdev/xattr2.cxx b/svx/source/xoutdev/xattr2.cxx
index 1131408e4bf5..744441c32fb4 100644
--- a/svx/source/xoutdev/xattr2.cxx
+++ b/svx/source/xoutdev/xattr2.cxx
@@ -51,6 +51,7 @@
 #include <comphelper/lok.hxx>
 
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 #include <boost/property_tree/ptree.hpp>
 
 XLineTransparenceItem::XLineTransparenceItem(sal_uInt16 nLineTransparence) :
@@ -356,10 +357,11 @@ bool XFillTransparenceItem::GetPresentation
 
 void XFillTransparenceItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, 
BAD_CAST("XFillTransparenceItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillTransparenceItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 boost::property_tree::ptree XFillTransparenceItem::dumpAsJSON() const
@@ -482,10 +484,11 @@ bool XFillBmpTileItem::GetPresentation
 
 void XFillBmpTileItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillBmpTileItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::boolean(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillBmpTileItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 
@@ -514,10 +517,11 @@ bool XFillBmpPosItem::GetPresentation
 
 void XFillBmpPosItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillBmpPosItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::number(static_cast<int>(GetValue())).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillBmpPosItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", sal_Int32(GetValue()));
+    aWriter.endElement();
 }
 
 
@@ -671,10 +675,11 @@ bool XFillBmpStretchItem::GetPresentation
 
 void XFillBmpStretchItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillBmpStretchItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::boolean(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillBmpStretchItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 XFillBmpPosOffsetXItem::XFillBmpPosOffsetXItem(sal_Int32 nOffPosX)
@@ -740,10 +745,11 @@ bool XFillBackgroundItem::GetPresentation( 
SfxItemPresentation /*ePres*/, MapUni
 
 void XFillBackgroundItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillBackgroundItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::boolean(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillBackgroundItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 XFillUseSlideBackgroundItem::XFillUseSlideBackgroundItem( bool bFill ) :
@@ -765,10 +771,11 @@ bool XFillUseSlideBackgroundItem::GetPresentation( 
SfxItemPresentation /*ePres*/
 
 void XFillUseSlideBackgroundItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, 
BAD_CAST("XFillUseSlideBackgroundItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), 
BAD_CAST(OString::boolean(GetValue()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillUseSlideBackgroundItem");
+    aWriter.attribute("whichId", Which());
+    aWriter.attribute("value", GetValue());
+    aWriter.endElement();
 }
 
 
diff --git a/svx/source/xoutdev/xattrbmp.cxx b/svx/source/xoutdev/xattrbmp.cxx
index 50c754beb936..c34bdb353e23 100644
--- a/svx/source/xoutdev/xattrbmp.cxx
+++ b/svx/source/xoutdev/xattrbmp.cxx
@@ -39,6 +39,7 @@
 #include <vcl/GraphicLoader.hxx>
 
 #include <libxml/xmlwriter.h>
+#include <tools/XmlWriter.hxx>
 
 using namespace ::com::sun::star;
 
@@ -328,12 +329,11 @@ std::unique_ptr<XFillBitmapItem> 
XFillBitmapItem::checkForUniqueItem( SdrModel&
 
 void XFillBitmapItem::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("XFillBitmapItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), 
BAD_CAST(OString::number(Which()).getStr()));
-
+    tools::XmlWriter aWriter(pWriter);
+    aWriter.startElement("XFillBitmapItem");
+    aWriter.attribute("whichId", Which());
     NameOrIndex::dumpAsXml(pWriter);
-
-    (void)xmlTextWriterEndElement(pWriter);
+    aWriter.endElement();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 964055dc807ab04f884a62c930ae98da5d8b7681
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Sat Dec 6 22:55:58 2025 +0900
Commit:     Andras Timar <[email protected]>
CommitDate: Sun Jan 11 00:38:33 2026 +0100

    tools: support XmlWriter construction from xmlTextWriterPtr
    
    So we can use it in dumpAsXml functions and eventually use it as
    a replacement to directly using libxml.
    
    Change-Id: I204d487b52343f69224fec2fd480657785bc0a69
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195167
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <[email protected]>

diff --git a/include/tools/XmlWriter.hxx b/include/tools/XmlWriter.hxx
index 8947c16ed1ff..1ad34bcdac0e 100644
--- a/include/tools/XmlWriter.hxx
+++ b/include/tools/XmlWriter.hxx
@@ -20,6 +20,8 @@
 #include <o3tl/concepts.hxx>
 
 class SvStream;
+struct _xmlTextWriter;
+typedef struct _xmlTextWriter* xmlTextWriterPtr;
 
 namespace tools
 {
@@ -41,7 +43,7 @@ private:
 
 public:
     XmlWriter(SvStream* pStream);
-
+    XmlWriter(xmlTextWriterPtr pWriter);
     ~XmlWriter();
 
     bool startDocument(sal_Int32 nIndent = 2, bool bWriteXmlHeader = true);
diff --git a/tools/qa/cppunit/test_xmlwriter.cxx 
b/tools/qa/cppunit/test_xmlwriter.cxx
index 6ab22950bf4d..61ce47533f13 100644
--- a/tools/qa/cppunit/test_xmlwriter.cxx
+++ b/tools/qa/cppunit/test_xmlwriter.cxx
@@ -22,25 +22,35 @@ public:
     {
     }
 
-    virtual void setUp() override {}
+    void setUp() override {}
 
     void testSimpleRoot();
     void testSpecialChars();
     void testAttributes();
+    void testStartAndEndDocument();
 
     CPPUNIT_TEST_SUITE(XmlWriterTest);
     CPPUNIT_TEST(testSimpleRoot);
     CPPUNIT_TEST(testSpecialChars);
     CPPUNIT_TEST(testAttributes);
+    CPPUNIT_TEST(testStartAndEndDocument);
     CPPUNIT_TEST_SUITE_END();
 };
 
+void XmlWriterTest::testStartAndEndDocument()
+{
+    SvMemoryStream aMemoryStream;
+    tools::XmlWriter aWriter(&aMemoryStream);
+    CPPUNIT_ASSERT(aWriter.startDocument());
+    CPPUNIT_ASSERT(!aWriter.startDocument());
+}
+
 void XmlWriterTest::testSimpleRoot()
 {
     SvMemoryStream aMemoryStream;
 
     tools::XmlWriter aWriter(&aMemoryStream);
-    aWriter.startDocument(0, false);
+    CPPUNIT_ASSERT(aWriter.startDocument(0, false));
     aWriter.startElement("test");
     aWriter.endElement();
     aWriter.endDocument();
@@ -55,7 +65,7 @@ void XmlWriterTest::testSpecialChars()
     SvMemoryStream aMemoryStream;
 
     tools::XmlWriter aWriter(&aMemoryStream);
-    aWriter.startDocument(0, false);
+    CPPUNIT_ASSERT(aWriter.startDocument(0, false));
     aWriter.startElement("test");
     aWriter.content("<>");
     aWriter.endElement();
@@ -71,7 +81,7 @@ void XmlWriterTest::testAttributes()
     SvMemoryStream aMemoryStream;
 
     tools::XmlWriter aWriter(&aMemoryStream);
-    aWriter.startDocument(0, false);
+    CPPUNIT_ASSERT(aWriter.startDocument(0, false));
     aWriter.startElement("test");
     aWriter.attribute("c", std::string_view("c"));
     aWriter.attribute("d", std::u16string_view(u"d"));
diff --git a/tools/source/xml/XmlWriter.cxx b/tools/source/xml/XmlWriter.cxx
index 5200c3dcd044..0df0b4e2c19d 100644
--- a/tools/source/xml/XmlWriter.cxx
+++ b/tools/source/xml/XmlWriter.cxx
@@ -42,16 +42,22 @@ requires(sizeof(T) == sizeof(char)) void 
attributeBase64_impl(xmlTextWriterPtr w
 
 struct XmlWriterImpl
 {
+    SvStream* mpStream = nullptr;
+    xmlTextWriterPtr mpWriter = nullptr;
+    bool mbWriteXmlHeader = true;
+    bool mbExternalXmlWriter = false;
+
     XmlWriterImpl(SvStream* pStream)
         : mpStream(pStream)
-        , mpWriter(nullptr)
-        , mbWriteXmlHeader(true)
     {
     }
 
-    SvStream* mpStream;
-    xmlTextWriterPtr mpWriter;
-    bool mbWriteXmlHeader;
+    XmlWriterImpl(xmlTextWriterPtr pWriter)
+        : mpWriter(pWriter)
+        , mbWriteXmlHeader(false)
+        , mbExternalXmlWriter(true)
+    {
+    }
 };
 
 XmlWriter::XmlWriter(SvStream* pStream)
@@ -59,29 +65,41 @@ XmlWriter::XmlWriter(SvStream* pStream)
 {
 }
 
+XmlWriter::XmlWriter(xmlTextWriterPtr pWriter)
+    : mpImpl(std::make_unique<XmlWriterImpl>(pWriter))
+{
+}
+
 XmlWriter::~XmlWriter()
 {
-    if (mpImpl && mpImpl->mpWriter != nullptr)
+    if (mpImpl)
         endDocument();
 }
 
 bool XmlWriter::startDocument(sal_Int32 nIndent, bool bWriteXmlHeader)
 {
+    if (mpImpl->mpWriter)
+        return false;
+
     mpImpl->mbWriteXmlHeader = bWriteXmlHeader;
     xmlCharEncodingHandlerPtr pEncodingHandler = 
xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8);
     xmlOutputBufferPtr xmlOutBuffer = 
xmlOutputBufferCreateIO(funcWriteCallback, funcCloseCallback,
                                                               
mpImpl->mpStream, pEncodingHandler);
     mpImpl->mpWriter = xmlNewTextWriter(xmlOutBuffer);
-    if (mpImpl->mpWriter == nullptr)
+    if (!mpImpl->mpWriter)
         return false;
     xmlTextWriterSetIndent(mpImpl->mpWriter, nIndent);
     if (mpImpl->mbWriteXmlHeader)
         (void)xmlTextWriterStartDocument(mpImpl->mpWriter, nullptr, "UTF-8", 
nullptr);
+
     return true;
 }
 
 void XmlWriter::endDocument()
 {
+    if (!mpImpl->mpWriter || mpImpl->mbExternalXmlWriter)
+        return;
+
     if (mpImpl->mbWriteXmlHeader)
         (void)xmlTextWriterEndDocument(mpImpl->mpWriter);
     xmlFreeTextWriter(mpImpl->mpWriter);
commit 6aaa97b00042b2c1c3bbacb95bf1a102607e2d06
Author:     Mohit Marathe <[email protected]>
AuthorDate: Tue Jul 22 16:30:11 2025 +0530
Commit:     Andras Timar <[email protected]>
CommitDate: Sat Jan 10 23:48:57 2026 +0100

    sw: handle param of graphic related uno commands
    
    Handles param of GrafLuminance, GrafContrast, GrafMode, and
    GrafTransparence
    
    Signed-off-by: Mohit Marathe <[email protected]>
    Change-Id: I824ddab9ad3efbd5f0739126a1d25ceca3908a83
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188156
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Pranam Lashkari <[email protected]>

diff --git a/sw/source/uibase/shells/grfsh.cxx 
b/sw/source/uibase/shells/grfsh.cxx
index 75a1c9b0ffca..f01261c974c4 100644
--- a/sw/source/uibase/shells/grfsh.cxx
+++ b/sw/source/uibase/shells/grfsh.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <svl/intitem.hxx>
+#include <vcl/GraphicAttributes.hxx>
 #include <cmdid.h>
 #include <hintids.hxx>
 #include <tools/urlobj.hxx>
@@ -613,16 +615,26 @@ void SwGrfShell::ExecAttr( SfxRequest const &rReq )
             break;
 
         case SID_ATTR_GRAF_LUMINANCE:
-            if( pItem )
+        {
+            const SfxInt16Item* pBrightness = 
rReq.GetArg<SfxInt16Item>(FN_PARAM_1);
+            if (pBrightness)
+                aGrfSet.Put( SwLuminanceGrf( pBrightness->GetValue() ) );
+            else if( pItem )
                 aGrfSet.Put( SwLuminanceGrf(
                             static_cast<const 
SfxInt16Item*>(pItem)->GetValue() ));
             break;
+        }
 
         case SID_ATTR_GRAF_CONTRAST:
-            if( pItem )
+        {
+            const SfxInt16Item* pContrast = 
rReq.GetArg<SfxInt16Item>(FN_PARAM_1);
+            if (pContrast)
+                aGrfSet.Put( SwContrastGrf( pContrast->GetValue() ) );
+            else if( pItem )
                 aGrfSet.Put( SwContrastGrf(
                             static_cast<const 
SfxInt16Item*>(pItem)->GetValue() ));
             break;
+        }
 
         case SID_ATTR_GRAF_RED:
             if( pItem )
@@ -651,10 +663,15 @@ void SwGrfShell::ExecAttr( SfxRequest const &rReq )
             break;
 
         case SID_ATTR_GRAF_TRANSPARENCE:
-            if( pItem )
+        {
+            const SfxInt16Item* pTransparence = 
rReq.GetArg<SfxInt16Item>(FN_PARAM_1);
+            if (pTransparence)
+                aGrfSet.Put( SwTransparencyGrf( pTransparence->GetValue() ) );
+            else if( pItem )
                 aGrfSet.Put( SwTransparencyGrf(
                     static_cast< sal_Int8 >( static_cast<const 
SfxUInt16Item*>(pItem )->GetValue() ) ) );
             break;
+        }
 
         case SID_ATTR_GRAF_INVERT:
             if( pItem )
@@ -663,10 +680,16 @@ void SwGrfShell::ExecAttr( SfxRequest const &rReq )
             break;
 
         case SID_ATTR_GRAF_MODE:
-            if( pItem )
+        {
+            const SfxInt16Item* pMode = rReq.GetArg<SfxInt16Item>(FN_PARAM_1);
+            if (pMode)
+                aGrfSet.Put( SwDrawModeGrf(
+                            static_cast<GraphicDrawMode>( pMode->GetValue() ) 
));
+            else if( pItem )
                 aGrfSet.Put( SwDrawModeGrf(
                             static_cast<GraphicDrawMode>(static_cast<const 
SfxUInt16Item*>(pItem)->GetValue()) ));
             break;
+        }
 
         case SID_COLOR_SETTINGS:
         {

Reply via email to