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 3fc834982400d29f99ecbae5013d9437c49c07e4 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Oct 25 08:33:18 2023 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Thu Oct 26 11:44:59 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. (cherry picked from commit 9704f61982360ce35983a61cca3fd00bbdf51ab6) Change-Id: Id9e80140af3123d52b0fea2f96fc19c150c8e736 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158482 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx index fa1567c5a577..6d732ec5edc1 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 e8e075dba31a..d2214567ffed 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -1583,9 +1583,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)); }