sw/qa/extras/ooxmlexport/ooxmlexport25.cxx | 8 ++++++++ sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 2 +- sw/qa/extras/ooxmlexport/ooxmlexport6.cxx | 2 +- sw/source/filter/ww8/wrtw8nds.cxx | 23 ++++++++++------------- 4 files changed, 20 insertions(+), 15 deletions(-)
New commits: commit b88fae70d30846273f44508462ac71cc69632248 Author: Justin Luth <[email protected]> AuthorDate: Wed Feb 25 08:15:14 2026 -0500 Commit: Justin Luth <[email protected]> CommitDate: Fri Feb 27 14:50:09 2026 +0100 tdf#170516 also always write ending flies in separate w:r This is a followup patch. Earlier patches for this bug report always put earlier flies in a separate w:r before processing text in a run. Now do the same for flies that come afterwards, at the end of the paragraph. One benefit of this is to prevent corrupt content controls, since plainText controls cannot contain flies, and flies-at-paragraph-end were creaping into the sdtContent. This was also problematic for redline content. A last-run delete-redline should not necessarily include anchored flies that are at the end of the paragraph. make CppunitTest_sw_ooxmlexport25 \ CPPUNIT_TEST_NAME=testTdf170908_delText The code block I pulled out was related to mk's make CppunitTest_sw_ooxmlexport18 CPPUNIT_TEST_NAME=testTdf152200 Change-Id: Ida92a1ec9d897ed21b0bf091bd6c36809af88c8a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200096 Reviewed-by: Justin Luth <[email protected]> Tested-by: Jenkins diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx index 8e8a98d791c1..fab4ac2aef79 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx @@ -361,6 +361,14 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf170908_delText) // delText must be inside a w:del or MS Word considers the document to be corrupt assertXPath(pXmlDoc, "//w:delText", 1); // there is a delTree element CPPUNIT_ASSERT_EQUAL(1, countXPathNodes(pXmlDoc, "//w:del/w:r/w:delText")); // must be in w:del + + // tdf#170516 drawing after plainText control + assertXPath(pXmlDoc, "//mc:AlternateContent", 1); // only one drawing + const int nRunsBeforeDelText = countXPathNodes(pXmlDoc, "//w:delText/preceding::w:r"); + const int nRunsBeforeAnchor = countXPathNodes(pXmlDoc, "//mc:AlternateContent/preceding::w:r"); + + // The text should be in a separate (preceding) run from the floating stuff + CPPUNIT_ASSERT_GREATER(nRunsBeforeDelText, nRunsBeforeAnchor); } CPPUNIT_TEST_FIXTURE(Test, testTdf170952_delText) diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx index 58e93f2d5ff0..f7eb9fae4744 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx @@ -522,7 +522,7 @@ CPPUNIT_TEST_FIXTURE(Test, testPageBreakInFirstPara) */ xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); - assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[2]/w:br","type",u"page"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[3]/w:br","type",u"page"); } CPPUNIT_TEST_FIXTURE(Test, testFDO78284) diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx index 5a156d05f1ae..d7449e6b4352 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx @@ -800,7 +800,7 @@ CPPUNIT_TEST_FIXTURE(Test, testDrawinglayerPicPos) // The problem was that the position of the picture was incorrect, it was shifted towards the bottom right corner. xmlDocUniquePtr pXmlDocument = parseExport(u"word/document.xml"_ustr); - const char* const aXPath("/w:document/w:body/w:p[1]/w:r[1]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:xfrm/a:off"); + const char* const aXPath("/w:document/w:body/w:p[1]/w:r[2]/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/pic:pic/pic:spPr/a:xfrm/a:off"); // This was 720. assertXPath(pXmlDocument, aXPath, "x", u"0"); // This was 1828800. diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index ebdd21614841..4881729736f9 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -2745,14 +2745,6 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) nCurrentPos + ofs + nLen); AttrOutput().RunText( aSnippet, eChrSet, aSymbolFont ); - - if (ofs == 1 && nNextAttr == nEnd) - { - // tdf#152200: There could be flys anchored after the last position; make sure - // to provide a separate run after field character to write them - AttrOutput().EndRun(&rNode, nCurrentPos, -1, nNextAttr == nEnd); - AttrOutput().StartRun(pRedlineData, nCurrentPos, bSingleEmptyRun); - } } if ( aAttrIter.IsDropCap( nNextAttr ) ) @@ -2778,12 +2770,10 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) else { // insert final graphic anchors if any before CR - if (pSdt && *pSdt->GetEnd() == nEnd && aAttrIter.HasFlysAt(nEnd)) + if (nEnd && aAttrIter.HasFlysAt(nEnd)) { - // Close the content control run before exporting final flies, - // otherwise the flies will be moved into the Sdt run, - // which (for a non-richText Sdt) will be considered corrupt in MS Word. - AttrOutput().EndRun(&rNode, nCurrentPos, nLen, /*bLastRun=*/false); + // Don't mix ending flies with the content of the last run + AttrOutput().EndRun(&rNode, nCurrentPos, nLen); nLen = 0; nCurrentPos = nEnd; AttrOutput().StartRun(pRedlineData, nCurrentPos, bSingleEmptyRun); @@ -2841,6 +2831,13 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) AttrOutput().WritePostitFieldReference(); // insert final graphic anchors if any before CR + if (nEnd && aAttrIter.HasFlysAt(nEnd)) + { + AttrOutput().EndRun(&rNode, nCurrentPos, nLen); + nLen = 0; + nCurrentPos = nEnd; + AttrOutput().StartRun(pRedlineData, nCurrentPos, bSingleEmptyRun); + } aAttrIter.OutFlys(nEnd); // insert final bookmarks if any before CR and after flys AppendBookmarks( rNode, nEnd, 1 );
