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)); }