diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2024-02-13 08:09:23 +0100 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2024-02-14 13:50:27 +0100 |
commit | f1307f09e60e715877769e9fa12c0a6313fa0c1a (patch) | |
tree | aff39f33aae2e643db2746cda65945d94c5eb73d | |
parent | 9589438d53f32ba7b59512d56a6dbd1d28de70a6 (diff) |
tdf#159453 sw floattable: fix unexpected overlap of in-header fly and body text
Regression from commit e2076cf7a92694bc94bdc9f3173c2bddbe881a89
(tdf#155682 sw floattable: fix DOCX with big pictures causes endless
loop, 2023-10-25), the bugdoc's body text was wrapping around the
floating table from the header, while the expectation was that the top
of the body frame is below the bottom of the header frame.
It seems IsFollowingTextFlow is only needed when the relation of the
floating table is not "page", and this bugdoc has has an examplicit
vertical relation of page.
Solve the problem by limiting the IsFollowingTextFlow=true request for
the floating table to the VertOrientRelation=page case, which fixes the
bugdoc and keeps the old use-case working.
The doc model for the new bugdoc now matches the WW8 import result.
Change-Id: Ia3da65cd52d70b357e448a26a50ffb92a39795e6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163290
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
(cherry picked from commit f74a6ef94ac957e4c146fc9923d30ce6bd31b5ce)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163286
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163298
-rw-r--r-- | writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx | 36 | ||||
-rw-r--r-- | writerfilter/qa/cppunittests/dmapper/data/floattable-header-overlap.docx | bin | 0 -> 23584 bytes | |||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 20 |
3 files changed, 52 insertions, 4 deletions
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx index 7be7da99f219..4843a3e76bb0 100644 --- a/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/qa/cppunittests/dmapper/DomainMapperTableHandler.cxx @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include <test/unoapi_test.hxx> +#include <test/unoapixml_test.hxx> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/table/BorderLine2.hpp> @@ -19,17 +19,18 @@ #include <com/sun/star/style/BreakType.hpp> #include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <com/sun/star/text/XPageCursor.hpp> +#include <com/sun/star/qa/XDumper.hpp> using namespace ::com::sun::star; namespace { /// Tests for writerfilter/source/dmapper/DomainMapperTableHandler.cxx. -class Test : public UnoApiTest +class Test : public UnoApiXmlTest { public: Test() - : UnoApiTest("/writerfilter/qa/cppunittests/dmapper/data/") + : UnoApiXmlTest("/writerfilter/qa/cppunittests/dmapper/data/") { } }; @@ -197,6 +198,35 @@ CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableFootnoteRedline) uno::Reference<drawing::XDrawPage> xDrawPage = xModel->getDrawPage(); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount()); } + +CPPUNIT_TEST_FIXTURE(Test, testDOCXFloatingTableHeaderBodyOverlap) +{ + // Given a document with a floating table in a header, the floating table extends the header + // frame: + // When importing that document: + loadFromFile(u"floattable-header-overlap.docx"); + + // Then make sure the fly bottom is less than the top of the body text: + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + css::uno::Reference<qa::XDumper> xDumper(xModel->getCurrentController(), uno::UNO_QUERY); + OString aDump = xDumper->dump("layout").toUtf8(); + auto pCharBuffer = reinterpret_cast<const xmlChar*>(aDump.getStr()); + xmlDocUniquePtr pXmlDoc(xmlParseDoc(pCharBuffer)); + sal_Int32 nFlyBottom = getXPath(pXmlDoc, "//fly/infos/bounds", "bottom").toInt32(); + // Body text top is body top + height of the first line, that's just a fly portion (kind of a + // top margin). + sal_Int32 nBodyTop = getXPath(pXmlDoc, "//page[1]/body/txt[1]/infos/bounds", "top").toInt32(); + // Without the accompanying fix in place, this test would have failed, the first line was not a + // fly portion but it was actual text, above the floating table. + assertXPath(pXmlDoc, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]/child::*", "type", + "PortionType::Fly"); + sal_Int32 nBodyFlyPortionHeight + = getXPath(pXmlDoc, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "height") + .toInt32(); + sal_Int32 nBodyTextTop = nBodyTop + nBodyFlyPortionHeight; + // Fly bottom was 3063, body text top was 7148. + CPPUNIT_ASSERT_LESS(nBodyTextTop, nFlyBottom); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/qa/cppunittests/dmapper/data/floattable-header-overlap.docx b/writerfilter/qa/cppunittests/dmapper/data/floattable-header-overlap.docx Binary files differnew file mode 100644 index 000000000000..1230b9f4e07c --- /dev/null +++ b/writerfilter/qa/cppunittests/dmapper/data/floattable-header-overlap.docx diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index eda2946a3b9f..1bddab4552a9 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -39,6 +39,7 @@ #include <com/sun/star/text/WritingMode2.hpp> #include <com/sun/star/text/XTextField.hpp> #include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/text/RelOrientation.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertyState.hpp> #include <com/sun/star/container/XEnumeration.hpp> @@ -1589,8 +1590,25 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel) // 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. + bool bIsFollowingTextFlow = true; + + sal_Int16 nVertOrientRelation{}; + auto it = std::find_if(aFrameProperties.begin(), aFrameProperties.end(), + [](const beans::PropertyValue& rPropertyValue) -> bool + { return rPropertyValue.Name == "VertOrientRelation"; }); + if (it != aFrameProperties.end()) + { + it->Value >>= nVertOrientRelation; + if (nVertOrientRelation == text::RelOrientation::PAGE_FRAME) + { + // If vertical relation is page, follow-text-flow is not useful and causes + // unwanted wrap of body text around in-header floating table, so avoid it. + bIsFollowingTextFlow = false; + } + } + aFrameProperties.push_back( - comphelper::makePropertyValue("IsFollowingTextFlow", true)); + comphelper::makePropertyValue("IsFollowingTextFlow", bIsFollowingTextFlow)); } // A text frame created for floating tables is always allowed to split. |