summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-10-03 12:08:36 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-10-03 17:29:14 +0200
commit695390b08799af34b393c81c834d615bea330d89 (patch)
treefa6efc4d63e70a72910ede5526b3ac81f0328fcd
parent140dc375adfffa59dff2652eb8b9625c23d81c8b (diff)
tdf#126449 sw floattable: fix too small height of non-last anchors
The bugdoc had an outer inline table, a middle inline table and an inner floating table. The floating table is expected to be on pages 2, 3 and 4; actually it was only on page 2 and 3. This happened because the fly frame that should be on page 4 was on page 3, leading to overlapping text. And that bad fly position seems to happen because the anchor frames just have a 1 line height (~269 twips instead of the fly height). Fix this similar to how "first paragraph only" wrapping works: increase the (anchor) text frame height, even if the contained lines would not require that amount of height. With this, finally the DOCX version of the bugdoc lays out reasonable (all 5 pages). Change-Id: Ib08bf34be61eb2b4d8656887f83ac7fd17e3b252 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157507 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sw/qa/core/text/data/floattable-anchor-height.docxbin0 -> 19441 bytes
-rw-r--r--sw/qa/core/text/porrst.cxx37
-rw-r--r--sw/source/core/text/porrst.cxx26
3 files changed, 61 insertions, 2 deletions
diff --git a/sw/qa/core/text/data/floattable-anchor-height.docx b/sw/qa/core/text/data/floattable-anchor-height.docx
new file mode 100644
index 000000000000..3052f0daef73
--- /dev/null
+++ b/sw/qa/core/text/data/floattable-anchor-height.docx
Binary files differ
diff --git a/sw/qa/core/text/porrst.cxx b/sw/qa/core/text/porrst.cxx
index 1c343dc0d9f2..f2e14e7f7f31 100644
--- a/sw/qa/core/text/porrst.cxx
+++ b/sw/qa/core/text/porrst.cxx
@@ -18,6 +18,7 @@
#include <pagefrm.hxx>
#include <rootfrm.hxx>
#include <txtfrm.hxx>
+#include <sortedobjs.hxx>
namespace
{
@@ -52,6 +53,42 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableLeftoverParaPortion)
// also had some (duplicated) anchor text.
CPPUNIT_ASSERT(!pPara2->GetPara());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testFloattableAnchorHeight)
+{
+#if !defined(MACOSX) // FIXME fails on macOS
+ // Given 3 tables, innermost table on pages 2-3-4:
+ createSwDoc("floattable-anchor-height.docx");
+
+ // When laying out the document:
+ calcLayout();
+
+ // Then make sure the flys are on the expected pages:
+ SwDoc* pDoc = getSwDoc();
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage1 = pLayout->Lower()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage1);
+ CPPUNIT_ASSERT(!pPage1->GetSortedObjs());
+ auto pPage2 = pPage1->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage2);
+ SwSortedObjs* pPage2Objs = pPage2->GetSortedObjs();
+ CPPUNIT_ASSERT(pPage2Objs);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage2Objs->size());
+ auto pPage3 = pPage2->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage3);
+ SwSortedObjs* pPage3Objs = pPage3->GetSortedObjs();
+ CPPUNIT_ASSERT(pPage3Objs);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 2
+ // i.e. page 3 also had the fly frame of page 4 as well.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage3Objs->size());
+ auto pPage4 = pPage3->GetNext()->DynCastPageFrame();
+ SwSortedObjs* pPage4Objs = pPage4->GetSortedObjs();
+ CPPUNIT_ASSERT(pPage4Objs);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage4Objs->size());
+#endif
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index 5c6ea428c1db..bd3589b25676 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -51,6 +51,8 @@
#include <crsrsh.hxx>
#include <swtypes.hxx>
#include <strings.hrc>
+#include <flyfrms.hxx>
+#include <bodyfrm.hxx>
SwTmpEndPortion::SwTmpEndPortion( const SwLinePortion &rPortion,
const FontLineStyle eUL,
@@ -412,7 +414,8 @@ bool SwTextFrame::FormatEmpty()
// sw_redlinehide: just disable FormatEmpty optimisation for now
// Split fly frames: non-last parts of the anchor want this optimization to clear the old
// content.
- bool bHasNonLastSplitFlyDrawObj = HasNonLastSplitFlyDrawObj();
+ SwFlyAtContentFrame* pNonLastSplitFlyDrawObj = HasNonLastSplitFlyDrawObj();
+ bool bHasNonLastSplitFlyDrawObj = pNonLastSplitFlyDrawObj != nullptr;
if ((HasFollow() && !bHasNonLastSplitFlyDrawObj) || GetMergedPara() || (GetTextNodeFirst()->GetpSwpHints() && !bHasNonLastSplitFlyDrawObj) ||
nullptr != GetTextNodeForParaProps()->GetNumRule() ||
GetTextNodeFirst()->HasHiddenCharAttribute(true) ||
@@ -468,7 +471,26 @@ bool SwTextFrame::FormatEmpty()
}
SwRectFnSet aRectFnSet(this);
- const SwTwips nChg = nHeight - aRectFnSet.GetHeight(getFramePrintArea());
+ SwTwips nChg = nHeight - aRectFnSet.GetHeight(getFramePrintArea());
+ const SwBodyFrame* pBody = FindBodyFrame();
+ if (pNonLastSplitFlyDrawObj && pBody)
+ {
+ // See if we need to increase the text frame height due to split flys. This is necessary for
+ // anchors of inner floating tables, where moving to a next page moves indirectly, so we
+ // want a correct text frame height.
+ SwTwips nFrameBottom = aRectFnSet.GetBottom(getFrameArea()) + nChg;
+ SwTwips nFlyBottom = aRectFnSet.GetBottom(pNonLastSplitFlyDrawObj->getFrameArea());
+ SwTwips nBodyBottom = aRectFnSet.GetBottom(pBody->getFrameArea());
+ if (nFlyBottom > nBodyBottom)
+ {
+ // This is the legacy case where flys may overlap with footer frames.
+ nFlyBottom = nBodyBottom;
+ }
+ if (pNonLastSplitFlyDrawObj->isFrameAreaPositionValid() && nFlyBottom > nFrameBottom)
+ {
+ nChg += (nFlyBottom - nFrameBottom);
+ }
+ }
if( !nChg )
SetUndersized( false );