sw/qa/extras/ooxmlexport/ooxmlexport12.cxx   |    5 ++---
 sw/source/filter/ww8/docxattributeoutput.cxx |    6 +++++-
 sw/source/filter/ww8/writerhelper.cxx        |   12 ++++++++++++
 sw/source/filter/ww8/writerhelper.hxx        |    2 ++
 sw/source/filter/ww8/wrtw8nds.cxx            |    1 +
 5 files changed, 22 insertions(+), 4 deletions(-)

New commits:
commit 515df96a85878f10dae3c9d1274ef4575d2e3215
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Dec 6 12:03:07 2022 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Thu Dec 8 16:30:45 2022 +0000

    sw: DOCX export: avoid writing duplicate w:b to w:pPr
    
    This prevents validation of documents in unit tests, only one w:b is
    allowed.
    
    The problem is that Writer has 3 different bold attributes, but Word
    apparently has only 2 of them, so Western and CJK are now both mapped to
    w:b.
    
    But RTF export oddly maps CJK and CTL to \ab, in contrast to DOC/DOCX.
    
    Change-Id: Icb9ece988de29e54dc320c483c74a4d4b8b70141
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143814
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
index eaddd1d6f48c..444fbf51a39c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
@@ -1859,9 +1859,8 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf135187)
     loadAndSave("tdf135187.docx");
     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:p/w:pPr/w:rPr/w:b", 0);
-    // FIXME: remove duplicate
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[3]/w:tc[1]/w:p/w:pPr/w:rPr/w:b", 2);
-    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc[1]/w:p/w:pPr/w:rPr/w:b", 2);
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[3]/w:tc[1]/w:p/w:pPr/w:rPr/w:b", 1);
+    assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[4]/w:tc[1]/w:p/w:pPr/w:rPr/w:b", 1);
 
     assertXPath(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:p/w:r[1]/w:rPr/w:b", 1);
     assertXPathNoAttribute(pXmlDoc, 
"/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:p/w:r[1]/w:rPr/w:b",
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 9084b9b6171a..92b13f34823c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1362,6 +1362,7 @@ void 
lcl_writeParagraphMarkerProperties(DocxAttributeOutput& rAttributeOutput, c
     const SfxPoolItem* pItem = nullptr;
     // Did we already produce a <w:sz> element?
     bool bFontSizeWritten = false;
+    bool bBoldWritten = false;
     while (nWhichId)
     {
         if (aIter.GetItemState(true, &pItem) == SfxItemState::SET && nWhichId 
!= RES_CHRATR_GRABBAG)
@@ -1370,10 +1371,13 @@ void 
lcl_writeParagraphMarkerProperties(DocxAttributeOutput& rAttributeOutput, c
             {
                 // Will this item produce a <w:sz> element?
                 bool bFontSizeItem = nWhichId == RES_CHRATR_FONTSIZE || 
nWhichId == RES_CHRATR_CJK_FONTSIZE;
-                if (!bFontSizeWritten || !bFontSizeItem)
+                bool bBoldItem = nWhichId == RES_CHRATR_WEIGHT || nWhichId == 
RES_CHRATR_CJK_WEIGHT;
+                if (!(bFontSizeWritten && bFontSizeItem) && !(bBoldWritten && 
bBoldItem))
                     rAttributeOutput.OutputItem(*pItem);
                 if (bFontSizeItem)
                     bFontSizeWritten = true;
+                if (bBoldItem)
+                    bBoldWritten = true;
             }
             else if (nWhichId == RES_TXTATR_AUTOFMT)
             {
diff --git a/sw/source/filter/ww8/writerhelper.cxx 
b/sw/source/filter/ww8/writerhelper.cxx
index 61be965848e6..5a45a6dbb04b 100644
--- a/sw/source/filter/ww8/writerhelper.cxx
+++ b/sw/source/filter/ww8/writerhelper.cxx
@@ -401,6 +401,18 @@ namespace sw
                     while ((pItem = aIter.NextItem()));
                 }
             }
+//            DeduplicateItems(rItems);
+        }
+
+        void DeduplicateItems(ww8::PoolItems & rItems)
+        {
+            if (rItems.find(RES_CHRATR_WEIGHT) != rItems.end()
+                && rItems.find(RES_CHRATR_CJK_WEIGHT) != rItems.end())
+            {
+                // avoid duplicate w:b element (DOC and DOCX map Western and
+                // CJK the same - inconsistently RTF maps CJK and CTL the 
same?)
+                rItems.erase(rItems.find(RES_CHRATR_CJK_WEIGHT));
+            }
         }
 
         const SfxPoolItem *SearchPoolItems(const ww8::PoolItems &rItems,
diff --git a/sw/source/filter/ww8/writerhelper.hxx 
b/sw/source/filter/ww8/writerhelper.hxx
index 632d1cb3a639..27442fceb0b9 100644
--- a/sw/source/filter/ww8/writerhelper.hxx
+++ b/sw/source/filter/ww8/writerhelper.hxx
@@ -317,6 +317,8 @@ namespace sw
         */
         void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool 
bExportParentItemSet );
 
+        void DeduplicateItems(ww8::PoolItems &rItems);
+
         const SfxPoolItem *SearchPoolItems(const ww8::PoolItems &rItems,
             sal_uInt16 eType);
 
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index 115a009bde79..2e94e5986cc7 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -465,6 +465,7 @@ void SwWW8AttrIter::OutAttr(sal_Int32 nSwPos, bool 
bWriteCombChars)
                 break;
         }
     }
+//    DeduplicateItems(aRangeItems);
 
     /*
      For #i24291# we need to explicitly remove any properties from the

Reply via email to