diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-06-20 08:50:57 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-06-20 10:00:37 +0200 |
commit | 2d0a4ef1d83b8de6cb133970c2c35ae706fb058e (patch) | |
tree | b66ebeca6a975afcf872f104679024d16d3f2982 /sw/qa/core/text/text.cxx | |
parent | abca28b4db956848271b53b4bc59f79b5f2f2529 (diff) |
sw floattable: fix negative vertical offset handling on page boundary
The bugdoc has 3 floating tables, the last one was on page 1 in Word,
but it was on page 2 in Writer.
It seems what happens is that the vertical offset of the last table is
negative, so it is moved above the paragraph before the last floating
table, but once the anchor frame (last paragraph) is moved to a new page
(because it doesn't fit), then its fly frame is also moved to page 2,
which leads to overlapping text in the original bugdoc. Interesting this
works already with 0 vertical offset, and in that case we split the last
paragraph, fill the page 1 part with a fly portion and fill the page 2
part with the anchor text.
Fix the problem by:
- triggering a split of the frame in SwTextFrameBreak::IsBreakNow(): if
the anchor frame doesn't fit (has to be moved to a next page), then
split it, so only the anchor text is moved, the fly is not (so its
position matches Word)
- preventing the manipulation of the frame offset in
SwTextFrame::AdjustFollow_(), so no content is moved from the follow
to the parent, because that would mean later we move the joined frame to
the next page
- finally minimizing the frame height at the end of
SwTextFrame::Format(), so the master still fits the current page
An alternative approach would be to extend
SwAnchoredObject::FindAnchorCharFrame(), which already has code to
handle the case when the text frame master and the anchored object is
not on the same page, but that operates on existing anchor frames, and
here the original problem is that the entire anchor frame is moved to
page 2, so we don't have anything left on page 1. Note that this is all
specific to floating tables, I could not reproduce the same behavior
with an anchored shape in Word.
Change-Id: I007b57b369f5c1e98ccad77111958dfd9335f079
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153309
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'sw/qa/core/text/text.cxx')
-rw-r--r-- | sw/qa/core/text/text.cxx | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index dff758985c37..96ffbf4e74a3 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -1309,6 +1309,29 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testFloattableOverlap) CPPUNIT_ASSERT(!rRect1.Overlaps(rRect2)); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testFloattableAnchorNextPage) +{ + // Given a document with 3 floating tables, the last one has a negative vertical offset, so the + // floating table is on page 1, but its anchor frame is effectively on page 2: + createSwDoc("floattable-anchor-next-page.docx"); + + // When laying out that document: + calcLayout(); + + // Then make sure all 3 floating tables are on page 1: + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + CPPUNIT_ASSERT(pPage1->GetSortedObjs()); + const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 3 + // - Actual : 2 + // i.e. the last floating table was on the wrong page (page 2). + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rPage1Objs.size()); +} + CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf89288) { // Given a document with 2 paragraphs of mixed Complex and Western text, |