writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx |   23 
++++++++++
 writerfilter/qa/cppunittests/dmapper/data/floattable-header.docx  |binary
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx          |    4 +
 3 files changed, 26 insertions(+), 1 deletion(-)

New commits:
commit 9704f61982360ce35983a61cca3fd00bbdf51ab6
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 25 08:33:18 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Oct 25 09:34:28 2023 +0200

    tdf#155682 sw floattable: fix DOCX with big pictures causes endless loop
    
    The bugdoc had a floating table in the header that overlapped with
    full-page, as-char anchored images in the body text, leading to a layout
    loop.
    
    The trouble is that the body text was broken into 2 lines: the first
    line just had fly portions for the area where the in-header floating
    table was rendered and then the second line hosted the actual image. But
    then this image didn't fit the remaining space, so it moves to the next
    page. And this happened again and again.
    
    Fix the problem by keeping in-header anchored floating tables inside the
    boundary of the header, this way the body text still doesn't overlap
    with the floating table, but the space available to the body text
    doesn't have to contain fly portions. Which means we don't try to move
    the image to a next page, so there is no loop.
    
    Note that the IsFollowingTextFlow flag is already ignored in some cases
    (e.g. sw/qa/extras/ww8export/data/tdf128700_relativeTableWidth.doc), so
    this doesn't break the use-case when a footer provides an anchor
    position for some text on the left/right margin. In that case the footer
    height is still unchanged as it should be.
    
    Change-Id: Id9e80140af3123d52b0fea2f96fc19c150c8e736
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158413
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
index 34fee71efff3..5046be81e98e 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx
@@ -17,6 +17,8 @@
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/style/BreakType.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
 
 using namespace ::com::sun::star;
 
@@ -160,6 +162,27 @@ CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableNested)
     // split.
     CPPUNIT_ASSERT(bIsSplitAllowed);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableHeader)
+{
+    // Given a document with a header that has a floating table and some large 
images in the body
+    // text:
+    loadFromURL(u"floattable-header.docx");
+
+    // When breaking that document into pages:
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+        xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<text::XPageCursor> 
xCursor(xTextViewCursorSupplier->getViewCursor(),
+                                              uno::UNO_QUERY);
+    xCursor->jumpToLastPage();
+
+    // Then make sure we get 2 pages:
+    sal_Int32 nLastPage = xCursor->getPage();
+    // Without the accompanying fix in place, this test would have failed, the 
page count went to
+    // 2233 pages and then there was a layout loop.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), nLastPage);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/qa/cppunittests/dmapper/data/floattable-header.docx 
b/writerfilter/qa/cppunittests/dmapper/data/floattable-header.docx
new file mode 100644
index 000000000000..1042dfc0616d
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/floattable-header.docx differ
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 2d1c4f3b44ba..2092ba4096ae 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -1580,9 +1580,11 @@ void DomainMapperTableHandler::endTable(unsigned int 
nestedTableLevel)
                 xTableProperties->setPropertyValue("BreakType", 
uno::Any(style::BreakType_NONE));
             }
 
-            if (nestedTableLevel >= 2)
+            if (nestedTableLevel >= 2 || m_rDMapper_Impl.IsInHeaderFooter())
             {
                 // Floating tables inside a table always stay inside the cell.
+                // Also extend the header/footer area if needed, so an 
in-header floating table
+                // typically doesn't overlap with body test.
                 aFrameProperties.push_back(
                     comphelper::makePropertyValue("IsFollowingTextFlow", 
true));
             }

Reply via email to