summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-02-13 08:09:23 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2024-02-14 13:50:27 +0100
commitf1307f09e60e715877769e9fa12c0a6313fa0c1a (patch)
treeaff39f33aae2e643db2746cda65945d94c5eb73d
parent9589438d53f32ba7b59512d56a6dbd1d28de70a6 (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.cxx36
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/floattable-header-overlap.docxbin0 -> 23584 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.cxx20
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
new file mode 100644
index 000000000000..1230b9f4e07c
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/floattable-header-overlap.docx
Binary files differ
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.