summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/text/data/floattable-anchor-next-page.docxbin0 -> 9409 bytes
-rw-r--r--sw/qa/core/text/text.cxx23
-rw-r--r--sw/source/core/inc/txtfrm.hxx4
-rw-r--r--sw/source/core/text/frmform.cxx18
-rw-r--r--sw/source/core/text/itratr.cxx26
-rw-r--r--sw/source/core/text/widorp.cxx28
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
new file mode 100644
index 000000000000..898c5514c587
--- /dev/null
+++ b/sw/qa/core/text/data/floattable-anchor-next-page.docx
Binary files differ
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() ) )
{