summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/text/frmform.cxx101
1 files changed, 88 insertions, 13 deletions
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index e19b834a5618..97eff3e607ec 100644
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -1081,6 +1081,54 @@ void SwTextFrame::ChangeOffset( SwTextFrame* pFrame, TextFrameIndex nNew )
MoveFlyInCnt( pFrame, nNew, TextFrameIndex(COMPLETE_STRING) );
}
+static bool isFirstVisibleFrameInBody(const SwTextFrame* pFrame)
+{
+ const SwFrame* pBodyFrame = pFrame->FindBodyFrame();
+ if (!pBodyFrame)
+ return false;
+ for (const SwFrame* pCur = pFrame;;)
+ {
+ for (const SwFrame* pPrev = pCur->GetPrev(); pPrev; pPrev = pPrev->GetPrev())
+ if (!pPrev->IsHiddenNow())
+ return false;
+ pCur = pCur->GetUpper();
+ assert(pCur); // We found pBodyFrame, right?
+ if (pCur->IsBodyFrame())
+ return true;
+ }
+}
+
+static bool hasFly(const SwTextFrame* pFrame)
+{
+ if (auto pDrawObjs = pFrame->GetDrawObjs(); pDrawObjs && pDrawObjs->size())
+ {
+ auto anchorId = (*pDrawObjs)[0]->GetFrameFormat()->GetAnchor().GetAnchorId();
+ if (anchorId == RndStdIds::FLY_AT_PARA || anchorId == RndStdIds::FLY_AT_CHAR)
+ return true;
+ }
+ return false;
+}
+
+static bool hasAtPageFly(const SwFrame* pFrame)
+{
+ auto pPageFrame = pFrame->FindPageFrame();
+ if (!pPageFrame)
+ return false;
+ auto pPageDrawObjs = pPageFrame->GetDrawObjs();
+ if (pPageDrawObjs)
+ {
+ for (const auto pObject : *pPageDrawObjs)
+ if (pObject->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ return true;
+ }
+ return false;
+}
+
+static bool isReallyEmptyMaster(const SwTextFrame* pFrame)
+{
+ return pFrame->IsEmptyMaster() && (!pFrame->GetDrawObjs() || !pFrame->GetDrawObjs()->size());
+}
+
void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
WidowsAndOrphans &rFrameBreak,
TextFrameIndex const nStrLen,
@@ -1108,27 +1156,55 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
? 1 : 0;
SwTextFormatInfo& rInf = rLine.GetInfo();
+ bool bEmptyWithSplitFly = false;
if (nNew == 0 && !nStrLen && !rInf.GetTextFly().IsOn() && IsEmptyWithSplitFly())
{
// Empty paragraph, so IsBreakNow() is not called, but we should split the fly portion and
// the paragraph marker.
nNew = 1;
+ bEmptyWithSplitFly = true;
}
+ const SwFrame *pBodyFrame = FindBodyFrame();
+
// i#84870
// no split of text frame, which only contains an as-character anchored object
- bool bOnlyContainsAsCharAnchoredObj =
+ bool bLoneAsCharAnchoredObj =
+ pBodyFrame &&
!IsFollow() && nStrLen == TextFrameIndex(1) &&
GetDrawObjs() && GetDrawObjs()->size() == 1 &&
(*GetDrawObjs())[0]->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR;
- // Still try split text frame if we have columns.
- if (FindColFrame())
- bOnlyContainsAsCharAnchoredObj = false;
-
- if ( nNew && bOnlyContainsAsCharAnchoredObj )
+ if (bLoneAsCharAnchoredObj)
{
- nNew = 0;
+ // Still try split text frame if we have columns.
+ if (FindColFrame())
+ bLoneAsCharAnchoredObj = false;
+ // tdf#160526: only no split if there is no preceding frames on same page
+ else if (!isFirstVisibleFrameInBody(this))
+ bLoneAsCharAnchoredObj = false;
+ else
+ nNew = 0;
+ }
+ else if (nNew)
+ {
+ if (IsFollow())
+ {
+ // tdf#160549: do not split the frame at the very beginning again, if its master was empty
+ auto precede = static_cast<SwTextFrame*>(GetPrecede());
+ assert(precede);
+ auto precedeText = precede->DynCastTextFrame();
+ assert(precedeText);
+ if (isReallyEmptyMaster(precedeText))
+ nNew = 0;
+ }
+ else if (!bEmptyWithSplitFly)
+ {
+ // Do not split immediately in the beginning of page (unless there is an at-para or
+ // at-char or at-page fly, which pushes the rest down)
+ if (isFirstVisibleFrameInBody(this) && !hasFly(this) && !hasAtPageFly(pBodyFrame))
+ nNew = 0;
+ }
}
if ( nNew )
@@ -1136,8 +1212,6 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
SplitFrame( nEnd );
}
- const SwFrame *pBodyFrame = FindBodyFrame();
-
const tools::Long nBodyHeight = pBodyFrame ? ( IsVertical() ?
pBodyFrame->getFrameArea().Width() :
pBodyFrame->getFrameArea().Height() ) : 0;
@@ -1239,9 +1313,10 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
// content or contains no content, but has a numbering.
// i#84870 - No split, if text frame only contains one
// as-character anchored object.
- if ( !bOnlyContainsAsCharAnchoredObj &&
- (nStrLen > TextFrameIndex(0) ||
- bHasVisibleNumRule )
+ if (!bLoneAsCharAnchoredObj
+ && (bHasVisibleNumRule
+ || (nStrLen > TextFrameIndex(0)
+ && (nEnd != rLine.GetStart() || rInf.GetRest())))
)
{
SplitFrame( nEnd );
@@ -1265,7 +1340,7 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine,
SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
//#i84870# - no shrink of text frame, if it only contains one as-character anchored object.
- if ( nChg < 0 && !bDelta && bOnlyContainsAsCharAnchoredObj )
+ if (nChg < 0 && !bDelta && bLoneAsCharAnchoredObj)
{
nChg = 0;
}