sw/qa/writerfilter/ooxml/data/table-wafter-row-height.docx |binary
 sw/qa/writerfilter/ooxml/ooxml.cxx                         |   24 ++++++++++
 sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx   |   30 +++++++++++++
 3 files changed, 54 insertions(+)

New commits:
commit 0e9f3c631e97bc148ee5f26a7f3eab5468f15f72
Author:     Miklos Vajna <[email protected]>
AuthorDate: Fri Oct 31 09:50:41 2025 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Fri Nov 7 21:20:06 2025 +0100

    tdf#168916 DOCX import, <w:wAfter>: make dummy paragraph less visible
    
    Load the bugdoc, Writer layout thinks there are floating tables here
    that need splitting, then layout fails to do that and it hangs:
    warn:legacy.osl:17593:17593:sw/source/core/layout/tabfrm.cxx:3365: debug 
assertion: <SwTabFrame::MakeAll()> - format of table lowers suppressed by fix 
i44910
    
    Checking what would be the expected output here, it turns out no actual
    splitting is happening in Word, but Writer thinks the table won't fit
    the page. This happens because the table row has a "wAfter" (spacing
    after last cell), and Writer uses an empty paragraph in that cell, using
    the default paragraph style (non-zero paragraph spacing, larger font
    size); while Word simply has no content in such a "fake cell".
    
    Fix the problem similar to what we already do for floating table anchor
    paragraphs in commit 86b0957cf18ea6705c8afa09bf4aae1fbb7db22e
    (tdf#167379 sw floattable: make dummy paragraph from DOCX import less
    visible, 2025-07-10), where we have the same problem that we want the
    empty paragraph to take ~no layout space.
    
    Once the table row has the correct height, Writer doesn't attempt to
    split the floating table, so it can't go wrong.
    
    Change-Id: I7fb2b859e72e5ec1b4b54d46c191ebfc5e8fcaa0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193257
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <[email protected]>
    (cherry picked from commit 3a0b56e4b2b94fd9001ea7a95488142cd9d6186d)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193271
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/sw/qa/writerfilter/ooxml/data/table-wafter-row-height.docx 
b/sw/qa/writerfilter/ooxml/data/table-wafter-row-height.docx
new file mode 100644
index 000000000000..98f7b218d6bd
Binary files /dev/null and 
b/sw/qa/writerfilter/ooxml/data/table-wafter-row-height.docx differ
diff --git a/sw/qa/writerfilter/ooxml/ooxml.cxx 
b/sw/qa/writerfilter/ooxml/ooxml.cxx
index 9a9d2745ba7c..7ef1d48cbab1 100644
--- a/sw/qa/writerfilter/ooxml/ooxml.cxx
+++ b/sw/qa/writerfilter/ooxml/ooxml.cxx
@@ -25,6 +25,7 @@
 #include <sortedobjs.hxx>
 #include <anchoredobject.hxx>
 #include <flyfrm.hxx>
+#include <tabfrm.hxx>
 
 using namespace ::com::sun::star;
 
@@ -146,6 +147,29 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableAnchorPos)
     // i.e. the vertical position of D was too big.
     CPPUNIT_ASSERT_LESSEQUAL(static_cast<SwTwips>(1), nDiff);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTableWafterRowHeight)
+{
+    // Given a document with a table, 2 rows, 2nd row's height is 12pt:
+    // When laying out that document:
+    createSwDoc("table-wafter-row-height.docx");
+
+    // Then make sure that <w:gridAfter> / <w:wAfter> doesn't increase the row 
height:
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    SwRootFrame* pLayout = pWrtShell->GetLayout();
+    SwPageFrame* pPage = pLayout->GetLower()->DynCastPageFrame();
+    auto pBeforeTableFrame = pPage->FindFirstBodyContent()->DynCastTextFrame();
+    auto pTabFrame = pBeforeTableFrame->GetNext()->DynCastTabFrame();
+    const SwFrame* pRow1Frame = pTabFrame->Lower();
+    const SwFrame* pRow2Frame = pRow1Frame->GetNext();
+    SwTwips nRow2Height = pRow2Frame->getFrameArea().Height();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 240
+    // - Actual  : 580
+    // i.e. the row height was too large, should be exactly 12 points (11 
points from line spacing,
+    // 1 point for the border).
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwTwips>(240), nRow2Height);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx 
b/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx
index 83c6b55e700c..3d0a29b60428 100644
--- a/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx
+++ b/sw/source/writerfilter/ooxml/OOXMLFastContextHandler.cxx
@@ -1554,6 +1554,36 @@ void 
OOXMLFastContextHandlerTextTableRow::handleGridBefore( const OOXMLValue& va
          i < count;
          ++i )
     {
+        if (isForwardEvents())
+        {
+            // Forwarding events: not just looking through e.g. all footnotes, 
searching for a
+            // specific footnote. In this case wBefore/wAfter creates a cell 
to ensure correct width
+            // of the other cells in the row. Set the layout size of the empty 
paragraph to a
+            // minimum, to make sure this dummy paragraph doesn't increase the 
row height.
+            startParagraphGroup();
+            {
+                // <w:spacing w:before="0" w:after="0" w:lineRule="atLeast" 
w:line="0">
+                OOXMLPropertySet::Pointer_t pAttributes(new OOXMLPropertySet);
+                OOXMLValue pSBVal = OOXMLValue::createInteger(0);
+                pAttributes->add(NS_ooxml::LN_CT_Spacing_before, pSBVal, 
OOXMLProperty::ATTRIBUTE);
+                OOXMLValue pSAVal = OOXMLValue::createInteger(0);
+                pAttributes->add(NS_ooxml::LN_CT_Spacing_after, pSAVal, 
OOXMLProperty::ATTRIBUTE);
+                OOXMLValue pSLRVal = 
OOXMLValue::createInteger(NS_ooxml::LN_Value_doc_ST_LineSpacingRule_atLeast);
+                pAttributes->add(NS_ooxml::LN_CT_Spacing_lineRule, pSLRVal, 
OOXMLProperty::ATTRIBUTE);
+                OOXMLValue pSLVal = OOXMLValue::createInteger(0);
+                pAttributes->add(NS_ooxml::LN_CT_Spacing_line, pSLVal, 
OOXMLProperty::ATTRIBUTE);
+                OOXMLValue pSprm = OOXMLValue::createPropertySet(pAttributes);
+                OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
+                pProps->add(NS_ooxml::LN_CT_PPrBase_spacing, pSprm, 
OOXMLProperty::SPRM);
+                mpStream->props(pProps.get());
+            }
+            // Also set the font size to 1pt, unit is half-points.
+            OOXMLPropertySet::Pointer_t pProps(new OOXMLPropertySet);
+            OOXMLValue pSprm = OOXMLValue::createInteger(2);
+            pProps->add(NS_ooxml::LN_EG_RPrBase_sz, pSprm, 
OOXMLProperty::SPRM);
+            mpStream->props(pProps.get());
+        }
+
         endOfParagraph();
 
         if (isForwardEvents())

Reply via email to