diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/core/text/data/floattable-anchor-next-page.docx | bin | 0 -> 9409 bytes | |||
-rw-r--r-- | sw/qa/core/text/text.cxx | 23 | ||||
-rw-r--r-- | sw/source/core/inc/txtfrm.hxx | 4 | ||||
-rw-r--r-- | sw/source/core/text/frmform.cxx | 18 | ||||
-rw-r--r-- | sw/source/core/text/itratr.cxx | 26 | ||||
-rw-r--r-- | sw/source/core/text/widorp.cxx | 28 |
6 files changed, 99 insertions, 0 deletions
diff --git a/sw/qa/core/text/data/floattable-anchor-next-page.docx b/sw/qa/core/text/data/floattable-anchor-next-page.docx Binary files differnew file mode 100644 index 000000000000..898c5514c587 --- /dev/null +++ b/sw/qa/core/text/data/floattable-anchor-next-page.docx 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, diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index c39df900dfb7..090f0bc0c340 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -799,6 +799,10 @@ public: /// a follow, i.e. not the last in a master -> follow 1 -> ... -> last follow chain? bool HasNonLastSplitFlyDrawObj() const; + /// This text frame has a follow and the text frame don't contain text. Additionally one split + /// fly is anchored to the text frame. + bool IsEmptyMasterWithSplitFly() const; + static SwView* GetView(); virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override; diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index ad0412a257ca..9398f28ad0ae 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -652,6 +652,12 @@ void SwTextFrame::AdjustFollow_( SwTextFormatter &rLine, } } + if (IsEmptyMasterWithSplitFly()) + { + // A split fly is anchored to us, don't move content from the follow frame to this one. + return; + } + // The Offset moved if( GetFollow() ) { @@ -2116,6 +2122,18 @@ void SwTextFrame::Format( vcl::RenderContext* pRenderContext, const SwBorderAttr { pPre->InvalidatePos(); } + + if (IsEmptyMasterWithSplitFly()) + { + // A fly is anchored to us, reduce size, so we definitely still fit the current + // page. + SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); + aRectFnSet.SetHeight(aFrm, 0); + + SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); + aRectFnSet.SetTop(aPrt, 0); + aRectFnSet.SetHeight(aPrt, 0); + } } } diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index 61fb23368fbe..176e06c4490e 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -1520,6 +1520,32 @@ bool SwTextFrame::HasNonLastSplitFlyDrawObj() const return false; } +bool SwTextFrame::IsEmptyMasterWithSplitFly() const +{ + if (!IsEmptyMaster()) + { + return false; + } + + if (!m_pDrawObjs || m_pDrawObjs->size() != 1) + { + return false; + } + + SwFlyFrame* pFlyFrame = (*m_pDrawObjs)[0]->DynCastFlyFrame(); + if (!pFlyFrame || !pFlyFrame->IsFlySplitAllowed()) + { + return false; + } + + if (mnOffset != GetFollow()->GetOffset()) + { + return false; + } + + return true; +} + SwTwips SwTextNode::GetWidthOfLeadingTabs() const { SwTwips nRet = 0; diff --git a/sw/source/core/text/widorp.cxx b/sw/source/core/text/widorp.cxx index 553cc2fa2de9..72903502749e 100644 --- a/sw/source/core/text/widorp.cxx +++ b/sw/source/core/text/widorp.cxx @@ -37,6 +37,9 @@ #include <ftnfrm.hxx> #include <pagefrm.hxx> #include <IDocumentSettingAccess.hxx> +#include <sortedobjs.hxx> +#include <anchoredobject.hxx> +#include <flyfrm.hxx> #undef WIDOWTWIPS @@ -237,6 +240,31 @@ bool SwTextFrameBreak::IsBreakNow( SwTextMargin &rLine ) bool bFirstLine = 1 == rLine.GetLineNr() && !rLine.GetPrev(); m_bBreak = true; + + if (bFirstLine) + { + bool bFits = m_pFrame->getFrameArea().Bottom() <= m_pFrame->GetUpper()->getFramePrintArea().Bottom(); + if (!m_pFrame->IsFollow() && !bFits) + { + // This is a master that doesn't fit the current parent. + if (m_pFrame->GetDrawObjs() && m_pFrame->GetDrawObjs()->size() == 1) + { + SwFlyFrame* pFlyFrame = (*m_pFrame->GetDrawObjs())[0]->DynCastFlyFrame(); + if (pFlyFrame && pFlyFrame->IsFlySplitAllowed()) + { + // It has a split fly anchored to it. + if (pFlyFrame->GetFrameFormat().GetVertOrient().GetPos() < 0) + { + // Negative vertical offset means that visually it already has a + // previous line. Consider that, otherwise the split fly would move to + // the next page as well, which is not wanted. + bFirstLine = false; + } + } + } + } + } + if( ( bFirstLine && m_pFrame->GetIndPrev() ) || ( rLine.GetLineNr() <= rLine.GetDropLines() ) ) { |