LibreOffice Module sw (master)  1
calcmove.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <rootfrm.hxx>
22 #include <pagefrm.hxx>
23 #include <viewopt.hxx>
24 #include <frmatr.hxx>
25 #include <frmtool.hxx>
26 #include <txtftn.hxx>
27 #include <fmtftn.hxx>
28 #include <ndtxt.hxx>
29 #include <editeng/ulspitem.hxx>
30 #include <editeng/keepitem.hxx>
31 #include <osl/diagnose.h>
32 #include <svx/sdtaitm.hxx>
33 
34 #include <fmtfsize.hxx>
35 #include <fmtanchr.hxx>
36 #include <fmtclbl.hxx>
37 
38 #include <tabfrm.hxx>
39 #include <ftnfrm.hxx>
40 #include <txtfrm.hxx>
41 #include <sectfrm.hxx>
42 #include <dbg_lay.hxx>
43 
44 #include <sortedobjs.hxx>
45 #include <layouter.hxx>
46 #include <flyfrms.hxx>
47 
50 
51 // Move methods
52 
55 {
57  {
58  // Floating back a frm uses a bit of time unfortunately.
59  // The most common case is the following: The Frame wants to float to
60  // somewhere where the FixSize is the same that the Frame itself has already.
61  // In that case it's pretty easy to check if the Frame has enough space
62  // for its VarSize. If this is NOT the case, we already know that
63  // we don't need to move.
64  // The Frame checks itself whether it has enough space - respecting the fact
65  // that it could possibly split itself if needed.
66  // If, however, the FixSize differs from the Frame or Flys are involved
67  // (either in the old or the new position), checking is pointless,
68  // and we have to move the Frame just to see what happens - if there's
69  // some space available to do it, that is.
70 
71  // The FixSize of the containers of Contents is always the width.
72 
73  // If we moved more than one sheet back (for example jumping over empty
74  // pages), we have to move either way. Otherwise, if the Frame doesn't fit
75  // into the page, empty pages wouldn't be respected anymore.
76  sal_uInt8 nMoveAnyway = 0;
77  SwPageFrame * const pNewPage = pNewUpper->FindPageFrame();
78  SwPageFrame *pOldPage = FindPageFrame();
79 
81  return true;
82 
83  if( IsInFootnote() && IsInSct() )
84  {
85  SwFootnoteFrame* pFootnote = FindFootnoteFrame();
86  SwSectionFrame* pMySect = pFootnote->FindSctFrame();
87  if( pMySect && pMySect->IsFootnoteLock() )
88  {
89  SwSectionFrame *pSect = pNewUpper->FindSctFrame();
90  while( pSect && pSect->IsInFootnote() )
91  pSect = pSect->GetUpper()->FindSctFrame();
92  OSL_ENSURE( pSect, "Escaping footnote" );
93  if( pSect != pMySect )
94  return false;
95  }
96  }
97  SwRectFnSet aRectFnSet(this);
98  SwRectFnSet fnRectX(pNewUpper);
99  if( std::abs( fnRectX.GetWidth(pNewUpper->getFramePrintArea()) -
100  aRectFnSet.GetWidth(GetUpper()->getFramePrintArea()) ) > 1 ) {
101  // In this case, only a WouldFit_ with test move is possible
102  nMoveAnyway = 2;
103  }
104 
105  // Do *not* move backward, if <nMoveAnyway> equals 3 and no space is left in new upper.
106  nMoveAnyway |= BwdMoveNecessary( pOldPage, getFrameArea() );
107  {
108  const IDocumentSettingAccess& rIDSA = pNewPage->GetFormat()->getIDocumentSettingAccess();
109  SwTwips nSpace = 0;
110  SwRect aRect( pNewUpper->getFramePrintArea() );
111  aRect.Pos() += pNewUpper->getFrameArea().Pos();
112  const SwFrame *pPrevFrame = pNewUpper->Lower();
113  while ( pPrevFrame )
114  {
115  SwTwips nNewTop = fnRectX.GetBottom(pPrevFrame->getFrameArea());
116  // Consider lower spacing of last frame in a table cell
117  {
118  // Check if last frame is inside table and if it includes its lower spacing.
119  if ( !pPrevFrame->GetNext() && pPrevFrame->IsInTab() &&
121  {
122  const SwFrame* pLastFrame = pPrevFrame;
123  // if last frame is a section, take its last content
124  if ( pPrevFrame->IsSctFrame() )
125  {
126  pLastFrame = static_cast<const SwSectionFrame*>(pPrevFrame)->FindLastContent();
127  if ( pLastFrame &&
128  pLastFrame->FindTabFrame() != pPrevFrame->FindTabFrame() )
129  {
130  pLastFrame = pLastFrame->FindTabFrame();
131  }
132  }
133 
134  if ( pLastFrame )
135  {
136  SwBorderAttrAccess aAccess( SwFrame::GetCache(), pLastFrame );
137  const SwBorderAttrs& rAttrs = *aAccess.Get();
138  nNewTop -= rAttrs.GetULSpace().GetLower();
140  {
141  nNewTop -= rAttrs.CalcLineSpacing();
142  }
143  }
144  }
145  }
146  fnRectX.SetTop( aRect, nNewTop );
147 
148  pPrevFrame = pPrevFrame->GetNext();
149  }
150 
151  nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect);
152 
153  //determine space left in new upper frame
154  nSpace = fnRectX.GetHeight(aRect);
155  const SwViewShell *pSh = pNewUpper->getRootFrame()->GetCurrShell();
156  if ( IsInFootnote() ||
157  (pSh && pSh->GetViewOptions()->getBrowseMode()) ||
158  pNewUpper->IsCellFrame() ||
159  ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrame() ||
160  ( pNewUpper->IsColBodyFrame() &&
161  !pNewUpper->GetUpper()->GetPrev() &&
162  !pNewUpper->GetUpper()->GetNext() ) ) ) )
163  nSpace += pNewUpper->Grow( LONG_MAX, true );
164 
165  if ( nMoveAnyway < 3 )
166  {
167  if ( nSpace )
168  {
169  // Do not notify footnotes which are stuck to the paragraph:
170  // This would require extremely confusing code, taking into
171  // account the widths
172  // and Flys, that in turn influence the footnotes, ...
173 
174  // WouldFit_ can only be used if the width is the same and
175  // ONLY self-anchored Flys are present.
176 
177  // WouldFit_ can also be used if ONLY Flys anchored
178  // somewhere else are present.
179  // In this case, the width doesn't even matter,
180  // because we're running a TestFormat in the new upper.
181  const sal_uInt8 nBwdMoveNecessaryResult =
182  BwdMoveNecessary( pNewPage, aRect);
183  const bool bObjsInNewUpper( nBwdMoveNecessaryResult == 2 ||
184  nBwdMoveNecessaryResult == 3 );
185 
186  return WouldFit_( nSpace, pNewUpper, nMoveAnyway == 2,
187  bObjsInNewUpper );
188  }
189  // It's impossible for WouldFit_ to return a usable result if
190  // we have a fresh multi-column section - so we really have to
191  // float back unless there is no space.
192  return pNewUpper->IsInSct() && pNewUpper->IsColBodyFrame() &&
193  !fnRectX.GetWidth(pNewUpper->getFramePrintArea()) &&
194  ( pNewUpper->GetUpper()->GetPrev() ||
195  pNewUpper->GetUpper()->GetNext() );
196  }
197 
198  // Check for space left in new upper
199  return nSpace != 0;
200  }
201  }
202  return false;
203 }
204 
205 // Calc methods
206 
207 // Two little friendships form a secret society
208 inline void PrepareLock( SwFlowFrame *pTab )
209 {
210  pTab->LockJoin();
211 }
212 inline void PrepareUnlock( SwFlowFrame *pTab )
213 {
214  pTab->UnlockJoin();
215 
216 }
217 
218 // hopefully, one day this function simply will return 'false'
219 static bool lcl_IsCalcUpperAllowed( const SwFrame& rFrame )
220 {
221  return !rFrame.GetUpper()->IsSctFrame() &&
222  !rFrame.GetUpper()->IsFooterFrame() &&
223  // No format of upper Writer fly frame
224  !rFrame.GetUpper()->IsFlyFrame() &&
225  !( rFrame.GetUpper()->IsTabFrame() && rFrame.GetUpper()->GetUpper()->IsInTab() ) &&
226  !( rFrame.IsTabFrame() && rFrame.GetUpper()->IsInTab() );
227 }
228 
247 {
248  StackHack aHack;
249  if ( GetUpper() )
250  {
251  SwFrameDeleteGuard aDeleteGuard(this);
252  if ( lcl_IsCalcUpperAllowed( *this ) )
253  GetUpper()->Calc(pRenderContext);
254  OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
255  if ( !GetUpper() )
256  return;
257 
258  const bool bCnt = IsContentFrame();
259  const bool bTab = IsTabFrame();
260  bool bNoSect = IsInSct();
261  bool bOldTabLock = false, bFoll = false;
262  SwFlowFrame* pThis = bCnt ? static_cast<SwContentFrame*>(this) : nullptr;
263 
264  if ( bTab )
265  {
266  pThis = static_cast<SwTabFrame*>(this);
267  bOldTabLock = static_cast<SwTabFrame*>(this)->IsJoinLocked();
268  ::PrepareLock( static_cast<SwTabFrame*>(this) );
269  bFoll = pThis->IsFollow();
270  }
271  else if( IsSctFrame() )
272  {
273  pThis = static_cast<SwSectionFrame*>(this);
274  bFoll = pThis->IsFollow();
275  bNoSect = false;
276  }
277  else if ( bCnt )
278  {
279  bFoll = pThis->IsFollow();
280  if ( bFoll && GetPrev() )
281  {
282  // Do not follow the chain when we need only one instance
283  const SwTextFrame* pMaster = static_cast<SwContentFrame*>(this)->FindMaster();
284  if ( pMaster && pMaster->IsLocked() )
285  {
286  MakeAll(pRenderContext);
287  return;
288  }
289  }
290  }
291 
292  // There is no format of previous frame, if current frame is a table
293  // frame and its previous frame wants to keep with it.
294  const bool bFormatPrev = !bTab ||
295  !GetPrev() ||
296  !GetPrev()->GetAttrSet()->GetKeep().GetValue();
297  if ( bFormatPrev )
298  {
299  SwFrame *pFrame = GetUpper()->Lower();
300  while ( pFrame != this )
301  {
302  OSL_ENSURE( pFrame, ":-( Layout unstable (this not found)." );
303  if ( !pFrame )
304  return; //Oioioioi ...
305 
306  if ( !pFrame->isFrameAreaDefinitionValid() )
307  {
308  // A small interference that hopefully improves on the stability:
309  // If I'm Follow AND neighbor of a Frame before me, it would delete
310  // me when formatting. This as you can see could easily become a
311  // confusing situation that we want to avoid.
312  if ( bFoll && pFrame->IsFlowFrame() &&
313  SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( pThis ) )
314  break;
315 
316  bool const isLast(pFrame->GetNext() == this);
317  // note: this seems obvious but does *not* hold, a MakeAll()
318  // could move more than 1 frame backwards!
319  // that's why FindNext() is used below
320  // assert(pFrame->GetUpper() == GetUpper());
321  pFrame->MakeAll(pRenderContext);
322  if( IsSctFrame() && !static_cast<SwSectionFrame*>(this)->GetSection() )
323  break;
324  if (isLast && pFrame->GetUpper() != GetUpper())
325  {
326  assert(GetUpper()->Lower() == this
327  // empty section frames are created all the time...
328  || GetUpper()->Lower()->IsSctFrame()
329  // tab frame/section frame may split multiple times
330  || ( SwFlowFrame::CastFlowFrame(pFrame)
332  && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow(
334  && (GetUpper()->Lower()->GetNext() == this
335  // if it's more than 10 pages long...
336  || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow()
338  && GetUpper()->Lower()->GetNext()->GetNext() == this)
339  // pre-existing empty section frames may end up between them...
340  || GetUpper()->Lower()->GetNext()->IsSctFrame())));
341  break; // tdf#119109 frame was moved backward, prevent
342  // FindNext() returning a frame inside this if
343  } // this is a table!
344  }
345  // With ContentFrames, the chain may be broken while walking through
346  // it. Therefore we have to figure out the next frame in a bit more
347  // complicated way. However, I'll HAVE to get back to myself
348  // sometime again.
349  pFrame = pFrame->FindNext();
350 
351  // If we started out in a SectionFrame, it might have happened that
352  // we landed in a Section Follow via the MakeAll calls.
353  // FindNext only gives us the SectionFrame, not it's content - we
354  // won't find ourselves anymore!
355  if( bNoSect && pFrame && pFrame->IsSctFrame() )
356  {
357  SwFrame* pCnt = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
358  if( pCnt )
359  pFrame = pCnt;
360  }
361  }
362  OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." );
363  if ( !GetUpper() )
364  return;
365 
366  if ( lcl_IsCalcUpperAllowed( *this ) )
367  GetUpper()->Calc(pRenderContext);
368 
369  OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." );
370  }
371 
372  if ( bTab && !bOldTabLock )
373  ::PrepareUnlock( static_cast<SwTabFrame*>(this) );
374  }
375  MakeAll(pRenderContext);
376 }
377 
379 {
380  // #i23129#, #i36347# - no format of upper Writer fly frame
381  if ( GetUpper() && !GetUpper()->IsFooterFrame() &&
382  !GetUpper()->IsFlyFrame() )
383  {
384  {
385  SwFrameDeleteGuard aDeleteGuard(this);
386  GetUpper()->Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr);
387  }
388  OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
389  if ( !GetUpper() )
390  return;
391  }
392  if ( GetPrev() && !GetPrev()->isFrameAreaDefinitionValid() )
393  {
394  PrepareMake(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr);
395  }
396  else
397  {
398  StackHack aHack;
399  MakeAll(IsRootFrame() ? nullptr : getRootFrame()->GetCurrShell()->GetOut());
400  }
401 }
402 
404 {
405  StackHack aHack;
406  if( GetUpper() && !GetUpper()->IsSctFrame() )
407  {
408  const bool bCnt = IsContentFrame();
409  const bool bTab = IsTabFrame();
410  bool bNoSect = IsInSct();
411 
412  std::optional<FlowFrameJoinLockGuard> tabGuard;
413  std::optional<SwFrameDeleteGuard> rowGuard;
414  SwFlowFrame* pThis = bCnt ? static_cast<SwContentFrame*>(this) : nullptr;
415 
416  if ( bTab )
417  {
418  tabGuard.emplace(static_cast<SwTabFrame*>(this)); // tdf#125741
419  pThis = static_cast<SwTabFrame*>(this);
420  }
421  else if (IsRowFrame())
422  {
423  rowGuard.emplace(this); // tdf#125741 keep this alive
424  }
425  else if( IsSctFrame() )
426  {
427  pThis = static_cast<SwSectionFrame*>(this);
428  bNoSect = false;
429  }
430 
431  GetUpper()->PrepareCursor();
432  GetUpper()->Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr);
433 
434  OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
435  if ( !GetUpper() )
436  return;
437 
438  bool const bFoll = pThis && pThis->IsFollow();
439 
440  SwFrame *pFrame = GetUpper()->Lower();
441  while ( pFrame != this )
442  {
443  OSL_ENSURE( pFrame, ":-( Layout unstable (this not found)." );
444  if ( !pFrame )
445  return; //Oioioioi ...
446 
447  if ( !pFrame->isFrameAreaDefinitionValid() )
448  {
449  // A small interference that hopefully improves on the stability:
450  // If I'm Follow AND neighbor of a Frame before me, it would delete
451  // me when formatting. This as you can see could easily become a
452  // confusing situation that we want to avoid.
453  if ( bFoll && pFrame->IsFlowFrame() &&
454  SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( pThis ) )
455  break;
456 
457  bool const isLast(pFrame->GetNext() == this);
458  pFrame->MakeAll(getRootFrame()->GetCurrShell()->GetOut());
459  if (isLast && pFrame->GetUpper() != GetUpper())
460  {
461  assert(GetUpper()->Lower() == this
462  // empty section frames are created all the time...
463  || GetUpper()->Lower()->IsSctFrame()
464  // tab frame/section frame may split multiple times
465  || ( SwFlowFrame::CastFlowFrame(pFrame)
467  && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow(
469  && (GetUpper()->Lower()->GetNext() == this
470  // if it's more than 10 pages long...
471  || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow()
473  && GetUpper()->Lower()->GetNext()->GetNext() == this)
474  // pre-existing empty section frames may end up between them...
475  || GetUpper()->Lower()->GetNext()->IsSctFrame())));
476  break; // tdf#119109 frame was moved backward, prevent
477  // FindNext() returning a frame inside this if
478  } // this is a table!
479  }
480  // With ContentFrames, the chain may be broken while walking through
481  // it. Therefore we have to figure out the next frame in a bit more
482  // complicated way. However, I'll HAVE to get back to myself
483  // sometime again.
484  pFrame = pFrame->FindNext();
485  if( bNoSect && pFrame && pFrame->IsSctFrame() )
486  {
487  SwFrame* pCnt = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
488  if( pCnt )
489  pFrame = pCnt;
490  }
491  }
492  OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." );
493  if ( !GetUpper() )
494  return;
495 
496  GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut());
497 
498  OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." );
499  }
500  Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr);
501 }
502 
503 // Here we return GetPrev(); however we will ignore empty SectionFrames
504 static SwFrame* lcl_Prev( SwFrame* pFrame, bool bSectPrv = true )
505 {
506  SwFrame* pRet = pFrame->GetPrev();
507  if( !pRet && pFrame->GetUpper() && pFrame->GetUpper()->IsSctFrame() &&
508  bSectPrv && !pFrame->IsColumnFrame() )
509  pRet = pFrame->GetUpper()->GetPrev();
510  while( pRet && pRet->IsSctFrame() &&
511  !static_cast<SwSectionFrame*>(pRet)->GetSection() )
512  pRet = pRet->GetPrev();
513  return pRet;
514 }
515 
517 {
518  SwFrame *pRet = pFrame;
519  do
520  {
521  pRet = lcl_Prev( pRet );
522  } while ( pRet && pRet->IsTextFrame() && static_cast<SwTextFrame*>(pRet)->IsHiddenNow() );
523  return pRet;
524 }
525 
527 {
528  if ( isFrameAreaPositionValid() )
529  return;
530 
532  bool bUseUpper = false;
533  SwFrame* pPrv = lcl_Prev( this );
534  if ( pPrv &&
535  ( !pPrv->IsContentFrame() ||
536  ( static_cast<SwContentFrame*>(pPrv)->GetFollow() != this ) )
537  )
538  {
539  if ( !StackHack::IsLocked() &&
540  ( !IsInSct() || IsSctFrame() ) &&
541  !pPrv->IsSctFrame() &&
542  !pPrv->GetAttrSet()->GetKeep().GetValue()
543  )
544  {
545  pPrv->Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); // This may cause Prev to vanish!
546  }
547  else if ( pPrv->getFrameArea().Top() == 0 )
548  {
549  bUseUpper = true;
550  }
551  }
552 
553  pPrv = lcl_Prev( this, false );
554  const SwFrameType nMyType = GetType();
555  SwRectFnSet aRectFnSet((IsCellFrame() && GetUpper() ? GetUpper() : this));
556  if ( !bUseUpper && pPrv )
557  {
559  aFrm.Pos( pPrv->getFrameArea().Pos() );
560 
561  if( FRM_NEIGHBOUR & nMyType )
562  {
563  const bool bR2L = IsRightToLeft();
564 
565  if( bR2L )
566  {
567  aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) - aRectFnSet.GetWidth(aFrm) );
568  }
569  else
570  {
571  aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) + aRectFnSet.GetWidth(pPrv->getFrameArea()) );
572  }
573 
574  // cells may now leave their uppers
575  if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType )
576  {
577  aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + pPrv->getFrameArea().Width());
578  }
579  }
580  else if( aRectFnSet.IsVert() && FRM_NOTE_VERT & nMyType )
581  {
582  if ( aRectFnSet.IsVertL2R() )
583  {
584  aFrm.Pos().setX(aFrm.Pos().getX() + pPrv->getFrameArea().Width());
585  }
586  else
587  {
588  aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width());
589  }
590  }
591  else
592  {
593  aFrm.Pos().setY(aFrm.Pos().getY() + pPrv->getFrameArea().Height());
594  }
595  }
596  else if ( GetUpper() )
597  {
598  // If parent frame is a footer frame and its <ColLocked()>, then
599  // do *not* calculate it.
600  // NOTE: Footer frame is <ColLocked()> during its
601  // <FormatSize(..)>, which is called from <Format(..)>, which
602  // is called from <MakeAll()>, which is called from <Calc()>.
603  // #i56850#
604  // - no format of upper Writer fly frame, which is anchored
605  // at-paragraph or at-character.
606  if ( !GetUpper()->IsTabFrame() &&
607  !( IsTabFrame() && GetUpper()->IsInTab() ) &&
608  !GetUpper()->IsSctFrame() &&
609  !dynamic_cast<SwFlyAtContentFrame*>(GetUpper()) &&
610  !( GetUpper()->IsFooterFrame() &&
611  GetUpper()->IsColLocked() )
612  )
613  {
614  GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut());
615  }
616  pPrv = lcl_Prev( this, false );
617  if ( !bUseUpper && pPrv )
618  {
620  aFrm.Pos( pPrv->getFrameArea().Pos() );
621 
622  if( FRM_NEIGHBOUR & nMyType )
623  {
624  const bool bR2L = IsRightToLeft();
625 
626  if( bR2L )
627  {
628  aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) - aRectFnSet.GetWidth(aFrm) );
629  }
630  else
631  {
632  aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) + aRectFnSet.GetWidth(pPrv->getFrameArea()) );
633  }
634 
635  // cells may now leave their uppers
636  if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType )
637  {
638  aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + pPrv->getFrameArea().Width());
639  }
640  }
641  else if( aRectFnSet.IsVert() && FRM_NOTE_VERT & nMyType )
642  {
643  aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width());
644  }
645  else
646  {
647  aFrm.Pos().setY(aFrm.Pos().getY() + pPrv->getFrameArea().Height());
648  }
649  }
650  else
651  {
653  aFrm.Pos( GetUpper()->getFrameArea().Pos() );
654 
655  if( GetUpper()->IsFlyFrame() )
656  {
657  aFrm.Pos() += static_cast<SwFlyFrame*>(GetUpper())->ContentPos();
658  }
659  else
660  {
661  aFrm.Pos() += GetUpper()->getFramePrintArea().Pos();
662  }
663 
664  if( FRM_NEIGHBOUR & nMyType && IsRightToLeft() )
665  {
666  if( aRectFnSet.IsVert() )
667  {
668  aFrm.Pos().setY(aFrm.Pos().getY() + GetUpper()->getFramePrintArea().Height() - aFrm.Height());
669  }
670  else
671  {
672  aFrm.Pos().setX(aFrm.Pos().getX() + GetUpper()->getFramePrintArea().Width() - aFrm.Width());
673  }
674  }
675  else if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && FRM_NOTE_VERT & nMyType )
676  {
677  aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + GetUpper()->getFramePrintArea().Width());
678  }
679  }
680  }
681  else
682  {
684  aFrm.Pos().setX(0);
685  aFrm.Pos().setY(0);
686  }
687 
688  if( IsBodyFrame() && aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && GetUpper() )
689  {
691  aFrm.Pos().setX(aFrm.Pos().getX() + GetUpper()->getFramePrintArea().Width() - aFrm.Width());
692  }
693 
695 }
696 
697 // #i28701# - new type <SwSortedObjs>
698 static void lcl_CheckObjects(SwSortedObjs& rSortedObjs, const SwFrame* pFrame, tools::Long& rBot)
699 {
700  // And then there can be paragraph anchored frames that sit below their paragraph.
701  tools::Long nMax = 0;
702  for (SwAnchoredObject* pObj : rSortedObjs)
703  {
704  // #i28701# - consider changed type of <SwSortedObjs>
705  // entries.
706  tools::Long nTmp = 0;
707  if ( auto pFly = pObj->DynCastFlyFrame() )
708  {
709  if( pFly->getFrameArea().Top() != FAR_AWAY &&
710  ( pFrame->IsPageFrame() ? pFly->IsFlyLayFrame() :
711  ( pFly->IsFlyAtContentFrame() &&
712  ( pFrame->IsBodyFrame() ? pFly->GetAnchorFrame()->IsInDocBody() :
713  pFly->GetAnchorFrame()->IsInFootnote() ) ) ) )
714  {
715  nTmp = pFly->getFrameArea().Bottom();
716  }
717  }
718  else
719  nTmp = pObj->GetObjRect().Bottom();
720  nMax = std::max( nTmp, nMax );
721  }
722  ++nMax; // Lower edge vs. height!
723  rBot = std::max( rBot, nMax );
724 }
725 
726 size_t SwPageFrame::GetContentHeight(const tools::Long nTop, const tools::Long nBottom) const
727 {
728  OSL_ENSURE(!(FindBodyCont() && FindBodyCont()->Lower() && FindBodyCont()->Lower()->IsColumnFrame()),
729  "SwPageFrame::GetContentHeight(): No support for columns.");
730 
731  // In pages without columns, the content defines the size.
732  tools::Long nBot = getFrameArea().Top() + nTop;
733  const SwFrame *pFrame = Lower();
734  while (pFrame)
735  {
736  tools::Long nTmp = 0;
737  const SwFrame *pCnt = static_cast<const SwLayoutFrame*>(pFrame)->ContainsAny();
738  while (pCnt && (pCnt->GetUpper() == pFrame ||
739  static_cast<const SwLayoutFrame*>(pFrame)->IsAnLower(pCnt)))
740  {
741  nTmp += pCnt->getFrameArea().Height();
742  if (pCnt->IsTextFrame() &&
743  static_cast<const SwTextFrame*>(pCnt)->IsUndersized())
744  {
745  // This TextFrame would like to be a bit bigger.
746  nTmp += static_cast<const SwTextFrame*>(pCnt)->GetParHeight()
747  - pCnt->getFramePrintArea().Height();
748  }
749  else if (pCnt->IsSctFrame())
750  {
751  // Grow if undersized, but don't shrink if oversized.
752  const auto delta = static_cast<const SwSectionFrame*>(pCnt)->CalcUndersize();
753  if (delta > 0)
754  nTmp += delta;
755  }
756 
757  pCnt = pCnt->FindNext();
758  }
759  // Consider invalid body frame properties
760  if (pFrame->IsBodyFrame() &&
761  (!pFrame->isFrameAreaSizeValid() ||
762  !pFrame->isFramePrintAreaValid()) &&
763  (pFrame->getFrameArea().Height() < pFrame->getFramePrintArea().Height())
764  )
765  {
766  nTmp = std::min(nTmp, pFrame->getFrameArea().Height());
767  }
768  else
769  {
770  // Assert invalid lower property
771  OSL_ENSURE(!(pFrame->getFrameArea().Height() < pFrame->getFramePrintArea().Height()),
772  "SwPageFrame::GetContentHeight(): Lower with frame height < printing height");
773  nTmp += pFrame->getFrameArea().Height() - pFrame->getFramePrintArea().Height();
774  }
775  if (!pFrame->IsBodyFrame())
776  nTmp = std::min(nTmp, pFrame->getFrameArea().Height());
777  nBot += nTmp;
778  // Here we check whether paragraph anchored objects
779  // protrude outside the Body/FootnoteCont.
780  if (m_pSortedObjs && !pFrame->IsHeaderFrame() &&
781  !pFrame->IsFooterFrame())
782  lcl_CheckObjects(*m_pSortedObjs, pFrame, nBot);
783  pFrame = pFrame->GetNext();
784  }
785  nBot += nBottom;
786  // And the page anchored ones
787  if (m_pSortedObjs)
788  lcl_CheckObjects(*m_pSortedObjs, this, nBot);
789  nBot -= getFrameArea().Top();
790 
791  return nBot;
792 }
793 
795 {
796  PROTOCOL_ENTER( this, PROT::MakeAll, DbgAction::NONE, nullptr )
797 
798  const SwRect aOldRect( getFrameArea() ); // Adjust root size
799  const SwLayNotify aNotify( this ); // takes care of the notification in the dtor
800  std::optional<SwBorderAttrAccess> oAccess;
801  const SwBorderAttrs*pAttrs = nullptr;
802 
804  {
805  if ( !isFrameAreaPositionValid() )
806  {
807  setFrameAreaPositionValid(true); // positioning of the pages is taken care of by the root frame
808  }
809 
811  {
812  if ( IsEmptyPage() )
813  {
815  aFrm.Width( 0 );
816  aFrm.Height( 0 );
817 
819  aPrt.Width( 0 );
820  aPrt.Height( 0 );
821  aPrt.Left( 0 );
822  aPrt.Top( 0 );
823 
824  setFrameAreaSizeValid(true);
826  }
827  else
828  {
829  if (!oAccess)
830  {
831  oAccess.emplace(SwFrame::GetCache(), this);
832  pAttrs = oAccess->Get();
833  }
834  assert(pAttrs);
835 
836  SwRootFrame* pRootFrame = getRootFrame();
837  SwViewShell* pSh = pRootFrame->GetCurrShell();
838  if (pSh && pSh->GetViewOptions()->getBrowseMode())
839  {
840  // In BrowseView, we use fixed settings
841  const Size aBorder = pRenderContext->PixelToLogic( pSh->GetBrowseBorder() );
842  const tools::Long nTop = pAttrs->CalcTopLine() + aBorder.Height();
843  const tools::Long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height();
844 
845  tools::Long nWidth = GetUpper() ? static_cast<SwRootFrame*>(GetUpper())->GetBrowseWidth() : 0;
846  const auto nDefWidth = pSh->GetBrowseWidth();
847  if (nWidth < nDefWidth)
848  nWidth = nDefWidth;
849  nWidth += + 2 * aBorder.Width();
850 
851  constexpr tools::Long constTwips_2cm = o3tl::toTwips(2, o3tl::Length::cm);
852  nWidth = std::max(nWidth, 2L * aBorder.Width() + constTwips_2cm);
853 
854  {
856  aFrm.Width( nWidth );
857 
858  SwLayoutFrame *pBody = FindBodyCont();
859  if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
860  {
861  // Columns have a fixed height
862  aFrm.Height( pAttrs->GetSize().Height() );
863  }
864  else
865  {
866  // In pages without columns, the content defines the size.
867  tools::Long nBot = GetContentHeight(nTop, nBottom);
868 
869  // #i35143# - If second page frame
870  // exists, the first page doesn't have to fulfill the
871  // visible area.
872  if ( !GetPrev() && !GetNext() )
873  {
874  nBot = std::max( nBot, pSh->VisArea().Height() );
875  }
876  // #i35143# - Assure, that the page
877  // doesn't exceed the defined browse height.
878  aFrm.Height( std::min( nBot, BROWSE_HEIGHT ) );
879  }
880  }
881 
882  {
884  aPrt.Left ( pAttrs->CalcLeftLine() + aBorder.Width() );
885  aPrt.Top ( nTop );
886  aPrt.Width( getFrameArea().Width() - ( aPrt.Left() + pAttrs->CalcRightLine() + aBorder.Width() ) );
887  aPrt.Height( getFrameArea().Height() - (nTop + nBottom) );
888  }
889 
890  setFrameAreaSizeValid(true);
892  continue;
893  }
894  else if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden() && pRootFrame->GetLastPage() != this)
895  {
896  tools::Long height = 0;
897  SwLayoutFrame *pBody = FindBodyCont();
898  if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() )
899  {
900  // Columns have a fixed height
901  height = pAttrs->GetSize().Height();
902  }
903  else
904  {
905  // No need for borders.
906  height = GetContentHeight(0, 0);
907  }
908 
909  if (height > 0)
910  {
911  ChgSize(Size(getFrameArea().Width(), height));
913  aPrt.Top(0);
914  aPrt.Height(height);
915  setFrameAreaSizeValid(true);
917  continue;
918  }
919 
920  // Fallback to default formatting. Especially relevant
921  // when loading a doc when Hide Whitespace is enabled.
922  // Heights are zero initially.
923  }
924 
925  // Set FixSize. For pages, this is not done from Upper, but from
926  // the attribute.
927  //FIXME: This resets the size when (isFrameAreaSizeValid() && !isFramePrintAreaValid()).
928  {
930  aFrm.SSize( pAttrs->GetSize() );
931  }
932  Format( pRenderContext, pAttrs );
933  }
934  }
935  } //while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() )
936 
937  if ( getFrameArea() != aOldRect && GetUpper() )
938  static_cast<SwRootFrame*>(GetUpper())->CheckViewLayout( nullptr, nullptr );
939 
940  OSL_ENSURE( !GetUpper() || GetUpper()->getFramePrintArea().Width() >= getFrameArea().Width(),
941  "Upper (Root) must be wide enough to contain the widest page");
942 }
943 
945 {
946  PROTOCOL_ENTER( this, PROT::MakeAll, DbgAction::NONE, nullptr )
947 
948  // takes care of the notification in the dtor
949  const SwLayNotify aNotify( this );
950  bool bVert = IsVertical();
951 
953 
954  std::optional<SwBorderAttrAccess> oAccess;
955  const SwBorderAttrs*pAttrs = nullptr;
956 
958  {
959  if ( !isFrameAreaPositionValid() )
960  MakePos();
961 
962  if ( GetUpper() )
963  {
964  // NEW TABLES
965  if ( IsLeaveUpperAllowed() )
966  {
967  if ( !isFrameAreaSizeValid() )
968  {
969  setFramePrintAreaValid(false);
970  }
971  }
972  else
973  {
974  if ( !isFrameAreaSizeValid() )
975  {
976  // Set FixSize; VarSize is set by Format() after calculating the PrtArea
977  setFramePrintAreaValid(false);
978 
979  SwTwips nPrtWidth = (GetUpper()->getFramePrintArea().*fnRect->fnGetWidth)();
980  if( bVert && ( IsBodyFrame() || IsFootnoteContFrame() ) )
981  {
982  SwFrame* pNxt = GetPrev();
983  while( pNxt && !pNxt->IsHeaderFrame() )
984  pNxt = pNxt->GetPrev();
985  if( pNxt )
986  nPrtWidth -= pNxt->getFrameArea().Height();
987  pNxt = GetNext();
988  while( pNxt && !pNxt->IsFooterFrame() )
989  pNxt = pNxt->GetNext();
990  if( pNxt )
991  nPrtWidth -= pNxt->getFrameArea().Height();
992  }
993 
994  const tools::Long nDiff = nPrtWidth - (getFrameArea().*fnRect->fnGetWidth)();
996 
997  if( IsNeighbourFrame() && IsRightToLeft() )
998  {
999  (aFrm.*fnRect->fnSubLeft)( nDiff );
1000  }
1001  else
1002  {
1003  (aFrm.*fnRect->fnAddRight)( nDiff );
1004  }
1005  }
1006  else
1007  {
1008  // Don't leave your upper
1009  const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
1010  if( (getFrameArea().*fnRect->fnOverStep)( nDeadLine ) )
1011  {
1012  setFrameAreaSizeValid(false);
1013  }
1014  }
1015  }
1016  }
1017 
1019  {
1020  if ( !oAccess )
1021  {
1022  oAccess.emplace(SwFrame::GetCache(), this);
1023  pAttrs = oAccess->Get();
1024  }
1025  Format( getRootFrame()->GetCurrShell()->GetOut(), pAttrs );
1026  }
1027  } //while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() )
1028 }
1029 
1031 {
1032  if (GetDoc().GetDocumentSettingManager().get( DocumentSettingId::COLLAPSE_EMPTY_CELL_PARA )
1033  && GetText().isEmpty())
1034  {
1035  SwNodeOffset nIdx=GetIndex();
1036  const SwEndNode *pNdBefore=GetNodes()[nIdx-1]->GetEndNode();
1037  const SwEndNode *pNdAfter=GetNodes()[nIdx+1]->GetEndNode();
1038 
1039  // The paragraph is collapsed only if the NdAfter is the end of a cell
1040  bool bInTable = FindTableNode( ) != nullptr;
1041 
1042  SwSortedObjs* pObjs = getLayoutFrame( GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() )->GetDrawObjs( );
1043  const size_t nObjs = ( pObjs != nullptr ) ? pObjs->size( ) : 0;
1044 
1045  return pNdBefore!=nullptr && pNdAfter!=nullptr && nObjs == 0 && bInTable;
1046  }
1047 
1048  return false;
1049 }
1050 
1052 {
1053  if (!IsTextFrame())
1054  return false;
1055 
1056  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>(this);
1057  const SwTextNode *pTextNode = pTextFrame->GetTextNodeForParaProps();
1058  // TODO this SwTextNode function is pointless and should be merged in here
1059  return pTextFrame->GetText().isEmpty() && pTextNode && pTextNode->IsCollapse();
1060 }
1061 
1063 {
1064  if ( isFramePrintAreaValid() )
1065  return;
1066 
1067  setFramePrintAreaValid(true);
1068  SwRectFnSet aRectFnSet(this);
1069  const bool bTextFrame = IsTextFrame();
1070  SwTwips nUpper = 0;
1071  if ( bTextFrame && static_cast<SwTextFrame*>(this)->IsHiddenNow() )
1072  {
1073  if ( static_cast<SwTextFrame*>(this)->HasFollow() )
1074  static_cast<SwTextFrame*>(this)->JoinFrame();
1075 
1076  if( aRectFnSet.GetHeight(getFramePrintArea()) )
1077  {
1078  static_cast<SwTextFrame*>(this)->HideHidden();
1079  }
1080 
1081  {
1083  aPrt.Pos().setX(0);
1084  aPrt.Pos().setY(0);
1085  aRectFnSet.SetWidth( aPrt, aRectFnSet.GetWidth(getFrameArea()) );
1086  aRectFnSet.SetHeight( aPrt, 0 );
1087  }
1088 
1089  nUpper = -( aRectFnSet.GetHeight(getFrameArea()) );
1090  }
1091  else
1092  {
1093  // Simplification: ContentFrames are always variable in height!
1094 
1095  // At the FixSize, the surrounding Frame enforces the size;
1096  // the borders are simply subtracted.
1097  const tools::Long nLeft = rAttrs.CalcLeft( this );
1098  const tools::Long nRight = rAttrs.CalcRight( this );
1099  aRectFnSet.SetXMargins( *this, nLeft, nRight );
1100 
1102  SwTwips nWidthArea;
1103  if( pSh && 0!=(nWidthArea=aRectFnSet.GetWidth(pSh->VisArea())) &&
1104  GetUpper()->IsPageBodyFrame() && // but not for BodyFrames in Columns
1105  pSh->GetViewOptions()->getBrowseMode() )
1106  {
1107  // Do not protrude the edge of the visible area. The page may be
1108  // wider, because there may be objects with excess width
1109  // (RootFrame::ImplCalcBrowseWidth())
1110  tools::Long nMinWidth = 0;
1111 
1112  for (size_t i = 0; GetDrawObjs() && i < GetDrawObjs()->size(); ++i)
1113  {
1114  // #i28701# - consider changed type of
1115  // <SwSortedObjs> entries
1116  SwAnchoredObject* pObj = (*GetDrawObjs())[i];
1117  const SwFrameFormat& rFormat = pObj->GetFrameFormat();
1118  const bool bFly = pObj->DynCastFlyFrame() != nullptr;
1119  if ((bFly && (FAR_AWAY == pObj->GetObjRect().Width()))
1120  || rFormat.GetFrameSize().GetWidthPercent())
1121  {
1122  continue;
1123  }
1124 
1125  if ( RndStdIds::FLY_AS_CHAR == rFormat.GetAnchor().GetAnchorId() )
1126  {
1127  nMinWidth = std::max( nMinWidth,
1128  bFly ? rFormat.GetFrameSize().GetWidth()
1129  : pObj->GetObjRect().Width() );
1130  }
1131  }
1132 
1133  const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
1134  tools::Long nWidth = nWidthArea - 2 * ( IsVertical() ? aBorder.Height() : aBorder.Width() );
1135  nWidth -= aRectFnSet.GetLeft(getFramePrintArea());
1136  nWidth -= rAttrs.CalcRightLine();
1137  nWidth = std::max( nMinWidth, nWidth );
1138 
1140  aRectFnSet.SetWidth( aPrt, std::min( nWidth, aRectFnSet.GetWidth(aPrt) ) );
1141  }
1142 
1143  if ( aRectFnSet.GetWidth(getFramePrintArea()) <= MINLAY )
1144  {
1145  // The PrtArea should already be at least MINLAY wide, matching the
1146  // minimal values of the UI
1148  aRectFnSet.SetWidth( aPrt, std::min( tools::Long(MINLAY), aRectFnSet.GetWidth(getFrameArea()) ) );
1149  SwTwips nTmp = aRectFnSet.GetWidth(getFrameArea()) - aRectFnSet.GetWidth(aPrt);
1150 
1151  if( aRectFnSet.GetLeft(aPrt) > nTmp )
1152  {
1153  aRectFnSet.SetLeft( aPrt, nTmp );
1154  }
1155  }
1156 
1157  // The following rules apply for VarSize:
1158  // 1. The first entry of a chain has no top border
1159  // 2. There is never a bottom border
1160  // 3. The top border is the maximum of the distance
1161  // of Prev downwards and our own distance upwards
1162  // Those three rules apply when calculating spacings
1163  // that are given by UL- and LRSpace. There might be a spacing
1164  // in all directions however; this may be caused by borders
1165  // and / or shadows.
1166  // 4. The spacing for TextFrames corresponds to the interline lead,
1167  // at a minimum.
1168 
1169  nUpper = CalcUpperSpace( &rAttrs );
1170 
1171  SwTwips nLower = CalcLowerSpace( &rAttrs );
1172  if (IsCollapse()) {
1173  nUpper=0;
1174  nLower=0;
1175  }
1176 
1177  {
1179  aRectFnSet.SetPosY( aPrt, !aRectFnSet.IsVert() ? nUpper : nLower);
1180  }
1181 
1182  nUpper += nLower;
1183  nUpper -= aRectFnSet.GetHeight(getFrameArea()) - aRectFnSet.GetHeight(getFramePrintArea());
1184  }
1185  // If there's a difference between old and new size, call Grow() or
1186  // Shrink() respectively.
1187  if ( nUpper )
1188  {
1189  if ( nUpper > 0 )
1190  GrowFrame( nUpper );
1191  else
1192  ShrinkFrame( -nUpper );
1193  }
1194 }
1195 
1196 #define STOP_FLY_FORMAT 10
1197 // - loop prevention
1198 const int cnStopFormat = 15;
1199 
1200 inline void ValidateSz( SwFrame *pFrame )
1201 {
1202  if ( pFrame )
1203  {
1204  pFrame->setFrameAreaSizeValid(true);
1205  pFrame->setFramePrintAreaValid(true);
1206  }
1207 }
1208 
1210 {
1211  OSL_ENSURE( GetUpper(), "no Upper?" );
1212  OSL_ENSURE( IsTextFrame(), "MakeAll(), NoText" );
1213 
1214  if ( !IsFollow() && StackHack::IsLocked() )
1215  return;
1216 
1217  if ( IsJoinLocked() )
1218  return;
1219 
1220  OSL_ENSURE( !static_cast<SwTextFrame*>(this)->IsSwapped(), "Calculation of a swapped frame" );
1221 
1222  StackHack aHack;
1223 
1224  if ( static_cast<SwTextFrame*>(this)->IsLocked() )
1225  {
1226  OSL_FAIL( "Format for locked TextFrame." );
1227  return;
1228  }
1229 
1230  std::optional<SwFrameDeleteGuard> oDeleteGuard(std::in_place, this);
1231  LockJoin();
1232  tools::Long nFormatCount = 0;
1233  // - loop prevention
1234  int nConsecutiveFormatsWithoutChange = 0;
1235  PROTOCOL_ENTER( this, PROT::MakeAll, DbgAction::NONE, nullptr )
1236 
1237  // takes care of the notification in the dtor
1238  std::optional<SwContentNotify> oNotify( std::in_place, this );
1239 
1240  // as long as bMakePage is true, a new page can be created (exactly once)
1241  bool bMakePage = true;
1242  // bMovedBwd gets set to true when the frame flows backwards
1243  bool bMovedBwd = false;
1244  // as long as bMovedFwd is false, the Frame may flow backwards (until
1245  // it has been moved forward once)
1246  bool bMovedFwd = false;
1247  sal_Bool bFormatted = false; // For the widow/orphan rules, we encourage the
1248  // last ContentFrame of a chain to format. This only
1249  // needs to happen once. Every time the Frame is
1250  // moved, the flag will have to be reset.
1251  bool bMustFit = false; // Once the emergency brake is pulled,
1252  // no other prepares will be triggered
1253  bool bFitPromise = false; // If a paragraph didn't fit, but promises
1254  // with WouldFit that it would adjust accordingly,
1255  // this flag is set. If it turns out that it
1256  // didn't keep it's promise, we can act in a
1257  // controlled fashion.
1258  const bool bFly = IsInFly();
1259  const bool bTab = IsInTab();
1260  const bool bFootnote = IsInFootnote();
1261  const bool bSct = IsInSct();
1262  Point aOldFramePos; // This is so we can compare with the last pos
1263  Point aOldPrtPos; // and determine whether it makes sense to Prepare
1264 
1265  SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
1266  const SwBorderAttrs &rAttrs = *aAccess.Get();
1267 
1268  if ( !IsFollow() && rAttrs.JoinedWithPrev( *(this) ) )
1269  {
1270  oNotify->SetBordersJoinedWithPrev();
1271  }
1272 
1273  const bool bKeep = IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem());
1274 
1275  std::unique_ptr<SwSaveFootnoteHeight> pSaveFootnote;
1276  if ( bFootnote )
1277  {
1278  SwFootnoteFrame *pFootnote = FindFootnoteFrame();
1279  SwSectionFrame* pSct = pFootnote->FindSctFrame();
1280  if ( !static_cast<SwTextFrame*>(pFootnote->GetRef())->IsLocked() )
1281  {
1282  SwFootnoteBossFrame* pBoss = pFootnote->GetRef()->FindFootnoteBossFrame(
1283  pFootnote->GetAttr()->GetFootnote().IsEndNote() );
1284  if( !pSct || pSct->IsColLocked() || !pSct->Growable() )
1285  pSaveFootnote.reset( new SwSaveFootnoteHeight( pBoss,
1286  static_cast<SwTextFrame*>(pFootnote->GetRef())->GetFootnoteLine( pFootnote->GetAttr() ) ) );
1287  }
1288  }
1289 
1290  if ( GetUpper()->IsSctFrame() &&
1291  HasFollow() && !GetFollow()->IsDeleteForbidden() &&
1292  &GetFollow()->GetFrame() == GetNext() )
1293  {
1294  static_cast<SwTextFrame&>(*this).JoinFrame();
1295  }
1296 
1297  // #i28701# - move master forward, if it has to move,
1298  // because of its object positioning.
1299  if ( !static_cast<SwTextFrame*>(this)->IsFollow() )
1300  {
1301  sal_uInt32 nToPageNum = 0;
1302  const bool bMoveFwdByObjPos = SwLayouter::FrameMovedFwdByObjPos(
1303  *(GetAttrSet()->GetDoc()),
1304  *static_cast<SwTextFrame*>(this),
1305  nToPageNum );
1306  // #i58182#
1307  // Also move a paragraph forward, which is the first one inside a table cell.
1308  if ( bMoveFwdByObjPos &&
1309  FindPageFrame()->GetPhyPageNum() < nToPageNum &&
1310  ( lcl_Prev( this ) ||
1311  GetUpper()->IsCellFrame() ||
1312  ( GetUpper()->IsSctFrame() &&
1313  GetUpper()->GetUpper()->IsCellFrame() ) ) &&
1314  IsMoveable() )
1315  {
1316  bMovedFwd = true;
1317  MoveFwd( bMakePage, false );
1318  }
1319  }
1320 
1321  // If a Follow sits next to its Master and doesn't fit, we know it can
1322  // be moved right now.
1323  if ( lcl_Prev( this ) && static_cast<SwTextFrame*>(this)->IsFollow() && IsMoveable() )
1324  {
1325  bMovedFwd = true;
1326  // If follow frame is in table, its master will be the last in the
1327  // current table cell. Thus, invalidate the printing area of the master.
1328  if ( IsInTab() )
1329  {
1330  lcl_Prev( this )->InvalidatePrt();
1331  }
1332  MoveFwd( bMakePage, false );
1333  }
1334 
1335  // Check footnote content for forward move.
1336  // If a content of a footnote is on a prior page/column as its invalid
1337  // reference, it can be moved forward.
1338  if ( bFootnote && !isFrameAreaPositionValid() )
1339  {
1340  SwFootnoteFrame* pFootnote = FindFootnoteFrame();
1341  SwContentFrame* pRefCnt = pFootnote ? pFootnote->GetRef() : nullptr;
1342 
1343  if ( pRefCnt && !pRefCnt->isFrameAreaDefinitionValid() )
1344  {
1345  SwFootnoteBossFrame* pFootnoteBossOfFootnote = pFootnote->FindFootnoteBossFrame();
1346  SwFootnoteBossFrame* pFootnoteBossOfRef = pRefCnt->FindFootnoteBossFrame();
1347  //<loop of movefwd until condition held or no move>
1348  if ( pFootnoteBossOfFootnote && pFootnoteBossOfRef &&
1349  pFootnoteBossOfFootnote != pFootnoteBossOfRef &&
1350  pFootnoteBossOfFootnote->IsBefore( pFootnoteBossOfRef ) )
1351  {
1352  bMovedFwd = true;
1353  MoveFwd( bMakePage, false );
1354  }
1355  }
1356  }
1357 
1358  SwRectFnSet aRectFnSet(this);
1359 
1360  SwFrame const* pMoveBwdPre(nullptr);
1361  bool isMoveBwdPreValid(false);
1362 
1363  SwRect aOldFrame_StopFormat, aOldFrame_StopFormat2;
1364  SwRect aOldPrt_StopFormat, aOldPrt_StopFormat2;
1365 
1367  {
1368  // - loop prevention
1369  aOldFrame_StopFormat2 = aOldFrame_StopFormat;
1370  aOldPrt_StopFormat2 = aOldPrt_StopFormat;
1371  aOldFrame_StopFormat = getFrameArea();
1372  aOldPrt_StopFormat = getFramePrintArea();
1373 
1374  bool bMoveable = IsMoveable();
1375  if (bMoveable)
1376  {
1377  SwFrame *pPre = GetIndPrev();
1378  if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) )
1379  {
1380  aRectFnSet.Refresh(this);
1381  bMovedFwd = true;
1382  if ( bMovedBwd )
1383  {
1384  // While flowing back, the Upper was encouraged to
1385  // completely re-paint itself. We can skip this now after
1386  // flowing back and forth.
1388  // The predecessor was invalidated, so this is obsolete as well now.
1389  assert(pPre);
1390  if ((pPre == pMoveBwdPre && isMoveBwdPreValid) && !pPre->IsSctFrame())
1391  ::ValidateSz( pPre );
1392  }
1393  bMoveable = IsMoveable();
1394  }
1395  }
1396 
1397  aOldFramePos = aRectFnSet.GetPos(getFrameArea());
1398  aOldPrtPos = aRectFnSet.GetPos(getFramePrintArea());
1399 
1400  if ( !isFrameAreaPositionValid() )
1401  MakePos();
1402 
1403  //Set FixSize. VarSize is being adjusted by Format().
1404  if ( !isFrameAreaSizeValid() )
1405  {
1406  // invalidate printing area flag, if the following conditions are hold:
1407  // - current frame width is 0.
1408  // - current printing area width is 0.
1409  // - frame width is adjusted to a value greater than 0.
1410  // - printing area flag is true.
1411  // Thus, it's assured that the printing area is adjusted, if the
1412  // frame area width changes its width from 0 to something greater
1413  // than 0.
1414  // Note: A text frame can be in such a situation, if the format is
1415  // triggered by method call <SwCursorShell::SetCursor()> after
1416  // loading the document.
1417  const SwTwips nNewFrameWidth = aRectFnSet.GetWidth(GetUpper()->getFramePrintArea());
1418 
1419  if ( isFramePrintAreaValid() &&
1420  nNewFrameWidth > 0 &&
1421  aRectFnSet.GetWidth(getFrameArea()) == 0 &&
1422  aRectFnSet.GetWidth(getFramePrintArea()) == 0 )
1423  {
1424  setFramePrintAreaValid(false);
1425  }
1426 
1427  {
1429  aRectFnSet.SetWidth( aFrm, nNewFrameWidth );
1430  }
1431 
1432  // When a lower of a vertically aligned fly frame changes its size we need to recalculate content pos.
1433  if( GetUpper() && GetUpper()->IsFlyFrame() &&
1434  GetUpper()->GetFormat()->GetTextVertAdjust().GetValue() != SDRTEXTVERTADJUST_TOP )
1435  {
1436  static_cast<SwFlyFrame*>(GetUpper())->InvalidateContentPos();
1438  }
1439  }
1440  if ( !isFramePrintAreaValid() )
1441  {
1442  const tools::Long nOldW = aRectFnSet.GetWidth(getFramePrintArea());
1443  // #i34730# - keep current frame height
1444  const SwTwips nOldH = aRectFnSet.GetHeight(getFrameArea());
1445  MakePrtArea( rAttrs );
1446  if ( nOldW != aRectFnSet.GetWidth(getFramePrintArea()) )
1448  // #i34730# - check, if frame height has changed.
1449  // If yes, send a PrepareHint::AdjustSizeWithoutFormatting and invalidate the size flag to
1450  // force a format. The format will check in its method
1451  // <SwTextFrame::CalcPreps()>, if the already formatted lines still
1452  // fit and if not, performs necessary actions.
1453  // #i40150# - no check, if frame is undersized.
1454  if ( isFrameAreaSizeValid() && !IsUndersized() && nOldH != aRectFnSet.GetHeight(getFrameArea()) )
1455  {
1456  // #115759# - no PrepareHint::AdjustSizeWithoutFormatting and size
1457  // invalidation, if height decreases only by the additional
1458  // lower space as last content of a table cell and an existing
1459  // follow containing one line exists.
1460  const SwTwips nHDiff = nOldH - aRectFnSet.GetHeight(getFrameArea());
1461  const bool bNoPrepAdjustFrame =
1462  nHDiff > 0 && IsInTab() && GetFollow() &&
1463  (1 == static_cast<SwTextFrame*>(GetFollow())->GetLineCount(TextFrameIndex(COMPLETE_STRING))
1464  || aRectFnSet.GetWidth(static_cast<SwTextFrame*>(GetFollow())->getFrameArea()) < 0) &&
1466  if ( !bNoPrepAdjustFrame )
1467  {
1469  setFrameAreaSizeValid(false);
1470  }
1471  }
1472  }
1473 
1474  // To make the widow and orphan rules work, we need to notify the ContentFrame.
1475  // Criteria:
1476  // - It needs to be movable (otherwise, splitting doesn't make sense)
1477  // - It needs to overlap with the lower edge of the PrtArea of the Upper
1478  if ( !bMustFit )
1479  {
1480  bool bWidow = true;
1481  const SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper());
1482  if( bMoveable && !bFormatted &&
1483  ( GetFollow() || aRectFnSet.OverStep( getFrameArea(), nDeadLine ) ) )
1484  {
1485  Prepare( PrepareHint::WidowsOrphans, nullptr, false );
1486  setFrameAreaSizeValid(false);
1487  bWidow = false;
1488  }
1489  if( aRectFnSet.GetPos(getFrameArea()) != aOldFramePos ||
1490  aRectFnSet.GetPos(getFramePrintArea()) != aOldPrtPos )
1491  {
1492  // In this Prepare, an InvalidateSize_() might happen.
1493  // isFrameAreaSizeValid() becomes false and Format() gets called.
1494  Prepare( PrepareHint::FramePositionChanged, static_cast<const void*>(&bFormatted), false );
1495  if ( bWidow && GetFollow() )
1496  {
1497  Prepare( PrepareHint::WidowsOrphans, nullptr, false );
1498  setFrameAreaSizeValid(false);
1499  }
1500  }
1501  }
1502  if ( !isFrameAreaSizeValid() )
1503  {
1504  setFrameAreaSizeValid(true);
1505  bFormatted = true;
1506  ++nFormatCount;
1507  if( nFormatCount > STOP_FLY_FORMAT )
1508  SetFlyLock( true );
1509  // - loop prevention
1510  // No format any longer, if <cnStopFormat> consecutive formats
1511  // without change occur.
1512  if ( nConsecutiveFormatsWithoutChange <= cnStopFormat )
1513  {
1514  Format(getRootFrame()->GetCurrShell()->GetOut());
1515  }
1516 #if OSL_DEBUG_LEVEL > 0
1517  else
1518  {
1519  OSL_FAIL( "debug assertion: <SwContentFrame::MakeAll()> - format of text frame suppressed by fix b6448963" );
1520  }
1521 #endif
1522  }
1523 
1524  // If this is the first one in a chain, check if this can flow
1525  // backwards (if this is movable at all).
1526  // To prevent oscillations/loops, check that this has not just
1527  // flowed forwards.
1528  bool bDummy;
1529  auto const pTemp(GetIndPrev());
1530  auto const bTemp(pTemp && pTemp->isFrameAreaSizeValid()
1531  && pTemp->isFramePrintAreaValid());
1532  if ( !lcl_Prev( this ) &&
1533  !bMovedFwd &&
1534  ( bMoveable || ( bFly && !bTab ) ) &&
1535  ( !bFootnote || !GetUpper()->FindFootnoteFrame()->GetPrev() )
1536  && MoveBwd( bDummy ) )
1537  {
1538  aRectFnSet.Refresh(this);
1539  pMoveBwdPre = pTemp;
1540  isMoveBwdPreValid = bTemp;
1541  bMovedBwd = true;
1542  bFormatted = false;
1543  if ( bKeep && bMoveable )
1544  {
1545  if( CheckMoveFwd( bMakePage, false, bMovedBwd ) )
1546  {
1547  bMovedFwd = true;
1548  bMoveable = IsMoveable();
1549  aRectFnSet.Refresh(this);
1550  }
1551  Point aOldPos = aRectFnSet.GetPos(getFrameArea());
1552  MakePos();
1553  if( aOldPos != aRectFnSet.GetPos(getFrameArea()) )
1554  {
1555  Prepare( PrepareHint::FramePositionChanged, static_cast<const void*>(&bFormatted), false );
1556  if ( !isFrameAreaSizeValid() )
1557  {
1558  {
1560  aRectFnSet.SetWidth( aFrm, aRectFnSet.GetWidth(GetUpper()->getFramePrintArea()) );
1561  }
1562 
1563  if ( !isFramePrintAreaValid() )
1564  {
1565  const tools::Long nOldW = aRectFnSet.GetWidth(getFramePrintArea());
1566  MakePrtArea( rAttrs );
1567  if( nOldW != aRectFnSet.GetWidth(getFramePrintArea()) )
1568  Prepare( PrepareHint::FixSizeChanged, nullptr, false );
1569  }
1570  if( GetFollow() )
1571  {
1572  Prepare( PrepareHint::WidowsOrphans, nullptr, false );
1573  }
1574 
1575  setFrameAreaSizeValid(true);
1576  bFormatted = true;
1577  Format(getRootFrame()->GetCurrShell()->GetOut());
1578  }
1579  }
1580  SwFrame *pNxt = HasFollow() ? nullptr : FindNext();
1581  while( pNxt && pNxt->IsSctFrame() )
1582  { // Leave empty sections out, go into the other ones.
1583  if( static_cast<SwSectionFrame*>(pNxt)->GetSection() )
1584  {
1585  SwFrame* pTmp = static_cast<SwSectionFrame*>(pNxt)->ContainsAny();
1586  if( pTmp )
1587  {
1588  pNxt = pTmp;
1589  break;
1590  }
1591  }
1592  pNxt = pNxt->FindNext();
1593  }
1594  if ( pNxt )
1595  {
1596  pNxt->Calc(getRootFrame()->GetCurrShell()->GetOut());
1597  if( isFrameAreaPositionValid() && !GetIndNext() )
1598  {
1599  SwSectionFrame *pSct = FindSctFrame();
1600  if( pSct && !pSct->isFrameAreaSizeValid() )
1601  {
1602  SwSectionFrame* pNxtSct = pNxt->FindSctFrame();
1603  if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
1604  {
1606  }
1607  }
1608  else
1609  {
1611  }
1612  }
1613  }
1614  }
1615  }
1616 
1617  // In footnotes, the TextFrame may validate itself, which can lead to the
1618  // situation that it's position is wrong despite being "valid".
1619  if ( isFrameAreaPositionValid() )
1620  {
1621  // #i59341#
1622  // Workaround for inadequate layout algorithm:
1623  // suppress invalidation and calculation of position, if paragraph
1624  // has formatted itself at least STOP_FLY_FORMAT times and
1625  // has anchored objects.
1626  // Thus, the anchored objects get the possibility to format itself
1627  // and this probably solve the layout loop.
1628  if ( bFootnote &&
1629  nFormatCount <= STOP_FLY_FORMAT &&
1630  !GetDrawObjs() )
1631  {
1633  MakePos();
1634  aOldFramePos = aRectFnSet.GetPos(getFrameArea());
1635  aOldPrtPos = aRectFnSet.GetPos(getFramePrintArea());
1636  }
1637  }
1638 
1639  // - loop prevention
1640  {
1641  if ( (aOldFrame_StopFormat == getFrameArea() || aOldFrame_StopFormat2 == getFrameArea() ) &&
1642  (aOldPrt_StopFormat == getFramePrintArea() || aOldPrt_StopFormat2 == getFramePrintArea()))
1643  {
1644  ++nConsecutiveFormatsWithoutChange;
1645  }
1646  else
1647  {
1648  nConsecutiveFormatsWithoutChange = 0;
1649  }
1650  }
1651 
1652  // Yet again an invalid value? Repeat from the start...
1654  continue;
1655 
1656  // Done?
1657  // Attention: because height == 0, it's better to use Top()+Height() instead of
1658  // Bottom(). This might happen with undersized TextFrames on the lower edge of a
1659  // multi-column section
1660  const tools::Long nPrtBottom = aRectFnSet.GetPrtBottom(*GetUpper());
1661  tools::Long nBottomDist = aRectFnSet.BottomDist(getFrameArea(), nPrtBottom);
1662 
1663  // Hide whitespace may require not to insert a new page.
1664  SwPageFrame* pPageFrame = FindPageFrame();
1665  const bool bHeightValid = pPageFrame->CheckPageHeightValidForHideWhitespace(nBottomDist);
1666  if (!bHeightValid)
1667  {
1668  pPageFrame->InvalidateSize();
1669  nBottomDist = 0;
1670  }
1671 
1672  if( nBottomDist >= 0 )
1673  {
1674  if ( bKeep && bMoveable )
1675  {
1676  // We make sure the successor will be formatted the same.
1677  // This way, we keep control until (almost) everything is stable,
1678  // allowing us to avoid endless loops caused by ever repeating
1679  // retries.
1680 
1681  // bMoveFwdInvalid is required for #38407#. This was originally solved
1682  // in flowfrm.cxx rev 1.38, but broke the above schema and
1683  // preferred to play towers of hanoi (#43669#).
1684  SwFrame *pNxt = HasFollow() ? nullptr : FindNext();
1685  // For sections we prefer the content, because it can change
1686  // the page if required.
1687  while( pNxt && pNxt->IsSctFrame() )
1688  {
1689  if( static_cast<SwSectionFrame*>(pNxt)->GetSection() )
1690  {
1691  pNxt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny();
1692  break;
1693  }
1694  pNxt = pNxt->FindNext();
1695  }
1696  if ( pNxt )
1697  {
1698  const bool bMoveFwdInvalid = nullptr != GetIndNext();
1699  const bool bNxtNew =
1700  ( 0 == aRectFnSet.GetHeight(pNxt->getFramePrintArea()) ) &&
1701  (!pNxt->IsTextFrame() ||!static_cast<SwTextFrame*>(pNxt)->IsHiddenNow());
1702 
1703  pNxt->Calc(getRootFrame()->GetCurrShell()->GetOut());
1704 
1705  if ( !bMovedBwd &&
1706  ((bMoveFwdInvalid && !GetIndNext()) ||
1707  bNxtNew) )
1708  {
1709  if( bMovedFwd )
1710  oNotify->SetInvaKeep();
1711  bMovedFwd = false;
1712  }
1713  }
1714  }
1715  continue;
1716  }
1717 
1718  // I don't fit into my parents, so it's time to make changes
1719  // as constructively as possible.
1720 
1721  //If I'm NOT allowed to leave the parent Frame, I've got a problem.
1722  // Following Arthur Dent, we do the only thing that you can do with
1723  // an unsolvable problem: We ignore it with all our power.
1724  if ( !bMoveable || IsUndersized() )
1725  {
1726  if( !bMoveable && IsInTab() )
1727  {
1728  tools::Long nDiff = -aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) );
1729  tools::Long nReal = GetUpper()->Grow( nDiff );
1730  if( nReal )
1731  continue;
1732  }
1733  break;
1734  }
1735 
1736  // If there's no way I can make myself fit into my Upper, the situation
1737  // could still probably be mitigated by splitting up.
1738  // This situation arises with freshly created Follows that had been moved
1739  // to the next page but is still too big for it - ie. needs to be split
1740  // as well.
1741 
1742  // If I'm unable to split (WouldFit()) and can't be fitted, I'm going
1743  // to tell my TextFrame part that, if possible, we still need to split despite
1744  // the "don't split" attribute.
1745  bool bMoveOrFit = false;
1746  bool bDontMoveMe = !GetIndPrev();
1747  if( bDontMoveMe && IsInSct() )
1748  {
1750  bDontMoveMe = !pBoss->IsInSct() ||
1751  ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() );
1752  }
1753 
1754  // Finally, we are able to split table rows. Therefore, bDontMoveMe
1755  // can be set to false:
1756  if( bDontMoveMe && IsInTab() &&
1757  nullptr != GetNextCellLeaf() )
1758  bDontMoveMe = false;
1759 
1760  assert(bMoveable);
1761 
1762  if ( bDontMoveMe && aRectFnSet.GetHeight(getFrameArea()) >
1763  aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) )
1764  {
1765  if ( !bFitPromise )
1766  {
1767  SwTwips nTmp = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) -
1768  aRectFnSet.GetTop(getFramePrintArea());
1769  bool bSplit = !IsFwdMoveAllowed();
1770  if ( nTmp > 0 && WouldFit( nTmp, bSplit, false ) )
1771  {
1772  Prepare( PrepareHint::WidowsOrphans, nullptr, false );
1773  setFrameAreaSizeValid(false);
1774  bFitPromise = true;
1775  continue;
1776  }
1777  /*
1778  * In earlier days, we never tried to fit TextFrames in
1779  * frames and sections using bMoveOrFit by ignoring
1780  * its attributes (Widows, Keep).
1781  * This should have been done at least for column frames;
1782  * as it must be tried anyway with linked frames and sections.
1783  * Exception: If we sit in FormatWidthCols, we must not ignore
1784  * the attributes.
1785  */
1786  else if ( !bFootnote &&
1787  ( !bFly || !FindFlyFrame()->IsColLocked() ) &&
1788  ( !bSct || !FindSctFrame()->IsColLocked() ) )
1789  bMoveOrFit = true;
1790  }
1791 #if OSL_DEBUG_LEVEL > 0
1792  else
1793  {
1794  OSL_FAIL( "+TextFrame didn't respect WouldFit promise." );
1795  }
1796 #endif
1797  }
1798 
1799  // Let's see if I can find some space somewhere...
1800  // footnotes in the neighbourhood are moved into _MoveFootnoteCntFwd
1801  SwFrame *pPre = GetIndPrev();
1802  SwFrame *pOldUp = GetUpper();
1803 
1804 /* MA 13. Oct. 98: What is this supposed to be!?
1805  * AMA 14. Dec 98: If a column section can't find any space for its first ContentFrame, it should be
1806  * moved not only to the next column, but probably even to the next page, creating
1807  * a section-follow there.
1808  */
1809  if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrame() &&
1810  pOldUp->GetUpper()->GetUpper()->IsSctFrame() &&
1811  ( pPre || pOldUp->GetUpper()->GetPrev() ) &&
1812  static_cast<SwSectionFrame*>(pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) )
1813  {
1814  bMovedFwd = false;
1815  }
1816 
1817  const bool bCheckForGrownBody = pOldUp->IsBodyFrame();
1818  const tools::Long nOldBodyHeight = aRectFnSet.GetHeight(pOldUp->getFrameArea());
1819 
1820  if ( !bMovedFwd && !MoveFwd( bMakePage, false ) )
1821  bMakePage = false;
1822  aRectFnSet.Refresh(this);
1823  if (!bMovedFwd && bFootnote && GetIndPrev() != pPre)
1824  { // SwFlowFrame::CutTree() could have formatted and deleted pPre
1825  auto const pPrevFootnoteFrame(static_cast<SwFootnoteFrame const*>(
1826  FindFootnoteFrame())->GetMaster());
1827  bool bReset = true;
1828  if (pPrevFootnoteFrame)
1829  { // use GetIndNext() in case there are sections
1830  for (auto p = pPrevFootnoteFrame->Lower(); p; p = p->GetIndNext())
1831  {
1832  if (p == pPre)
1833  {
1834  bReset = false;
1835  break;
1836  }
1837  }
1838  }
1839  if (bReset)
1840  {
1841  pPre = nullptr;
1842  }
1843  }
1844 
1845  // If MoveFwd moves the paragraph to the next page, a following
1846  // paragraph, which contains footnotes can cause the old upper
1847  // frame to grow. In this case we explicitly allow a new check
1848  // for MoveBwd. Robust: We also check the bMovedBwd flag again.
1849  // If pOldUp was a footnote frame, it has been deleted inside MoveFwd.
1850  // Therefore we only check for growing body frames.
1851  bMovedFwd = !bCheckForGrownBody || bMovedBwd || pOldUp == GetUpper() ||
1852  aRectFnSet.GetHeight(pOldUp->getFrameArea()) <= nOldBodyHeight;
1853 
1854  bFormatted = false;
1855  if ( bMoveOrFit && GetUpper() == pOldUp )
1856  {
1857  // FME 2007-08-30 #i81146# new loop control
1858  if ( nConsecutiveFormatsWithoutChange <= cnStopFormat )
1859  {
1860  Prepare( PrepareHint::MustFit, nullptr, false );
1861  setFrameAreaSizeValid(false);
1862  bMustFit = true;
1863  continue;
1864  }
1865 
1866 #if OSL_DEBUG_LEVEL > 0
1867  OSL_FAIL( "LoopControl in SwContentFrame::MakeAll" );
1868 #endif
1869  }
1870  if ( bMovedBwd && GetUpper() )
1871  { // Retire invalidations that have become useless.
1873  if( pPre && !pPre->IsSctFrame() )
1874  ::ValidateSz( pPre );
1875  }
1876 
1877  } //while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() )
1878 
1879  // NEW: Looping Louie (Light). Should not be applied in balanced sections.
1880  // Should only be applied if there is no better solution!
1881  LOOPING_LOUIE_LIGHT( bMovedFwd && bMovedBwd && !IsInBalancedSection() &&
1882  (
1883 
1884  ( bFootnote && !FindFootnoteFrame()->GetRef()->IsInSct() ) ||
1885 
1886  // #i33887#
1887  ( IsInSct() && bKeep )
1888 
1889  // ... add your conditions here ...
1890 
1891  ),
1892  static_cast<SwTextFrame&>(*this) );
1893 
1894  pSaveFootnote.reset();
1895 
1896  UnlockJoin();
1897  oDeleteGuard.reset();
1898  if ( bMovedFwd || bMovedBwd )
1899  oNotify->SetInvaKeep();
1900  if ( bMovedFwd )
1901  {
1902  oNotify->SetInvalidatePrevPrtArea();
1903  }
1904  oNotify.reset();
1905  SetFlyLock( false );
1906 }
1907 
1908 void MakeNxt( SwFrame *pFrame, SwFrame *pNxt )
1909 {
1910  // fix(25455): Validate, otherwise this leads to a recursion.
1911  // The first try, cancelling with pFrame = 0 if !Valid, leads to a problem, as
1912  // the Keep may not be considered properly anymore (27417).
1913  const bool bOldPos = pFrame->isFrameAreaPositionValid();
1914  const bool bOldSz = pFrame->isFrameAreaSizeValid();
1915  const bool bOldPrt = pFrame->isFramePrintAreaValid();
1916  pFrame->setFrameAreaPositionValid(true);
1917  pFrame->setFrameAreaSizeValid(true);
1918  pFrame->setFramePrintAreaValid(true);
1919 
1920  // fix(29272): Don't call MakeAll - there, pFrame might be invalidated again, and
1921  // we recursively end up in here again.
1922  if ( pNxt->IsContentFrame() )
1923  {
1924  SwContentNotify aNotify( static_cast<SwContentFrame*>(pNxt) );
1925  SwBorderAttrAccess aAccess( SwFrame::GetCache(), pNxt );
1926  const SwBorderAttrs &rAttrs = *aAccess.Get();
1927  if ( !pNxt->isFrameAreaSizeValid() )
1928  {
1930 
1931  if( pNxt->IsVertical() )
1932  {
1933  aFrm.Height( pNxt->GetUpper()->getFramePrintArea().Height() );
1934  }
1935  else
1936  {
1937  aFrm.Width( pNxt->GetUpper()->getFramePrintArea().Width() );
1938  }
1939  }
1940  static_cast<SwContentFrame*>(pNxt)->MakePrtArea( rAttrs );
1941  pNxt->Format( pNxt->getRootFrame()->GetCurrShell()->GetOut(), &rAttrs );
1942  }
1943  else
1944  {
1945  SwLayNotify aNotify( static_cast<SwLayoutFrame*>(pNxt) );
1946  SwBorderAttrAccess aAccess( SwFrame::GetCache(), pNxt );
1947  const SwBorderAttrs &rAttrs = *aAccess.Get();
1948  if ( !pNxt->isFrameAreaSizeValid() )
1949  {
1951 
1952  if( pNxt->IsVertical() )
1953  {
1954  aFrm.Height( pNxt->GetUpper()->getFramePrintArea().Height() );
1955  }
1956  else
1957  {
1958  aFrm.Width( pNxt->GetUpper()->getFramePrintArea().Width() );
1959  }
1960  }
1961  pNxt->Format( pNxt->getRootFrame()->GetCurrShell()->GetOut(), &rAttrs );
1962  }
1963 
1964  pFrame->setFrameAreaPositionValid(bOldPos);
1965  pFrame->setFrameAreaSizeValid(bOldSz);
1966  pFrame->setFramePrintAreaValid(bOldPrt);
1967 }
1968 
1971 static bool lcl_IsNextFootnoteBoss( const SwFrame *pFrame, const SwFrame* pNxt )
1972 {
1973  assert(pFrame && pNxt && "lcl_IsNextFootnoteBoss: No Frames?");
1974  pFrame = pFrame->FindFootnoteBossFrame();
1975  pNxt = pNxt->FindFootnoteBossFrame();
1976  // If pFrame is a last column, we use the page instead.
1977  while( pFrame && pFrame->IsColumnFrame() && !pFrame->GetNext() )
1978  pFrame = pFrame->GetUpper()->FindFootnoteBossFrame();
1979  // If pNxt is a first column, we use the page instead.
1980  while( pNxt && pNxt->IsColumnFrame() && !pNxt->GetPrev() )
1981  pNxt = pNxt->GetUpper()->FindFootnoteBossFrame();
1982  // So... now pFrame and pNxt are either two adjacent pages or columns.
1983  return pFrame && pNxt && pFrame->GetNext() == pNxt;
1984 }
1985 
1987  SwLayoutFrame *pNewUpper,
1988  bool bTstMove,
1989  const bool bObjsInNewUpper )
1990 {
1991  // To have the footnote select its place carefully, it needs
1992  // to be moved in any case if there is at least one page/column
1993  // between the footnote and the new Upper.
1994  SwFootnoteFrame* pFootnoteFrame = nullptr;
1995  if ( IsInFootnote() )
1996  {
1997  if( !lcl_IsNextFootnoteBoss( pNewUpper, this ) )
1998  return true;
1999  pFootnoteFrame = FindFootnoteFrame();
2000  }
2001 
2002  bool bRet;
2003  bool bSplit = !pNewUpper->Lower();
2004  SwContentFrame *pFrame = this;
2005  const SwFrame *pTmpPrev = pNewUpper->Lower();
2006  if( pTmpPrev && pTmpPrev->IsFootnoteFrame() )
2007  pTmpPrev = static_cast<const SwFootnoteFrame*>(pTmpPrev)->Lower();
2008  while ( pTmpPrev && pTmpPrev->GetNext() )
2009  pTmpPrev = pTmpPrev->GetNext();
2010  do
2011  {
2012  // #i46181#
2013  SwTwips nSecondCheck = 0;
2014  SwTwips nOldSpace = nSpace;
2015  bool bOldSplit = bSplit;
2016 
2017  if ( bTstMove || IsInFly() || ( IsInSct() &&
2018  ( pFrame->GetUpper()->IsColBodyFrame() || ( pFootnoteFrame &&
2019  pFootnoteFrame->GetUpper()->GetUpper()->IsColumnFrame() ) ) ) )
2020  {
2021  // This is going to get a bit insidious now. If you're faint of heart,
2022  // you'd better look away here. If a Fly contains columns, then the Contents
2023  // are movable, except ones in the last column (see SwFrame::IsMoveable()).
2024  // Of course they're allowed to float back. WouldFit() only returns a usable
2025  // value if the Frame is movable. To fool WouldFit() into believing there's
2026  // a movable Frame, I'm just going to hang it somewhere else for the time.
2027  // The same procedure applies for column sections to make SwSectionFrame::Growable()
2028  // return the proper value.
2029  // Within footnotes, we may even need to put the SwFootnoteFrame somewhere else, if
2030  // there's no SwFootnoteFrame there.
2031  SwFrame* pTmpFrame = pFrame->IsInFootnote() && !pNewUpper->FindFootnoteFrame() ?
2032  static_cast<SwFrame*>(pFrame->FindFootnoteFrame()) : pFrame;
2033  SwLayoutFrame *pUp = pTmpFrame->GetUpper();
2034  SwFrame *pOldNext = pTmpFrame->GetNext();
2035  pTmpFrame->RemoveFromLayout();
2036  pTmpFrame->InsertBefore( pNewUpper, nullptr );
2037  // tdf#107126 for a section in a footnote, we have only inserted
2038  // the SwTextFrame but no SwSectionFrame - reset mbInfSct flag
2039  // to avoid crashing (but perhaps we should create a temp
2040  // SwSectionFrame here because WidowsAndOrphans checks for that?)
2041  pTmpFrame->InvalidateInfFlags();
2042  if ( pFrame->IsTextFrame() &&
2043  ( bTstMove ||
2044  static_cast<SwTextFrame*>(pFrame)->HasFollow() ||
2045  ( !static_cast<SwTextFrame*>(pFrame)->HasPara() &&
2046  !static_cast<SwTextFrame*>(pFrame)->IsEmpty()
2047  )
2048  )
2049  )
2050  {
2051  bTstMove = true;
2052  bRet = static_cast<SwTextFrame*>(pFrame)->TestFormat( pTmpPrev, nSpace, bSplit );
2053  }
2054  else
2055  bRet = pFrame->WouldFit( nSpace, bSplit, false );
2056 
2057  pTmpFrame->RemoveFromLayout();
2058  pTmpFrame->InsertBefore( pUp, pOldNext );
2059  pTmpFrame->InvalidateInfFlags(); // restore flags
2060  }
2061  else
2062  {
2063  bRet = pFrame->WouldFit( nSpace, bSplit, false );
2064  nSecondCheck = !bSplit ? 1 : 0;
2065  }
2066 
2067  SwBorderAttrAccess aAccess( SwFrame::GetCache(), pFrame );
2068  const SwBorderAttrs &rAttrs = *aAccess.Get();
2069 
2070  // Sad but true: We need to consider the spacing in our calculation.
2071  // This already happened in TestFormat.
2072  if ( bRet && !bTstMove )
2073  {
2074  SwTwips nUpper;
2075 
2076  if ( pTmpPrev )
2077  {
2078  nUpper = CalcUpperSpace( nullptr, pTmpPrev );
2079 
2080  // in balanced columned section frames we do not want the
2081  // common border
2082  bool bCommonBorder = true;
2083  if ( pFrame->IsInSct() && pFrame->GetUpper()->IsColBodyFrame() )
2084  {
2085  const SwSectionFrame* pSct = pFrame->FindSctFrame();
2086  bCommonBorder = pSct->GetFormat()->GetBalancedColumns().GetValue();
2087  }
2088 
2089  // #i46181#
2090  nSecondCheck = ( 1 == nSecondCheck &&
2091  pFrame == this &&
2092  IsTextFrame() &&
2093  bCommonBorder &&
2094  !static_cast<const SwTextFrame*>(this)->IsEmpty() ) ?
2095  nUpper :
2096  0;
2097 
2098  nUpper += bCommonBorder ?
2099  rAttrs.GetBottomLine( *pFrame ) :
2100  rAttrs.CalcBottomLine();
2101 
2102  }
2103  else
2104  {
2105  // #i46181#
2106  nSecondCheck = 0;
2107 
2108  if( pFrame->IsVertical() )
2109  nUpper = pFrame->getFrameArea().Width() - pFrame->getFramePrintArea().Width();
2110  else
2111  nUpper = pFrame->getFrameArea().Height() - pFrame->getFramePrintArea().Height();
2112  }
2113 
2114  nSpace -= nUpper;
2115 
2116  if ( nSpace < 0 )
2117  {
2118  bRet = false;
2119 
2120  // #i46181#
2121  if ( nSecondCheck > 0 )
2122  {
2123  // The following code is intended to solve a (rare) problem
2124  // causing some frames not to move backward:
2125  // SwTextFrame::WouldFit() claims that the whole paragraph
2126  // fits into the given space and subtracts the height of
2127  // all lines from nSpace. nSpace - nUpper is not a valid
2128  // indicator if the frame should be allowed to move backward.
2129  // We do a second check with the original remaining space
2130  // reduced by the required upper space:
2131  nOldSpace -= nSecondCheck;
2132  const bool bSecondRet = nOldSpace >= 0 && pFrame->WouldFit( nOldSpace, bOldSplit, false );
2133  if ( bSecondRet && bOldSplit && nOldSpace >= 0 )
2134  {
2135  bRet = true;
2136  bSplit = true;
2137  }
2138  }
2139  }
2140  }
2141 
2142  // Also consider lower spacing in table cells
2143  IDocumentSettingAccess const& rIDSA(pNewUpper->GetFormat()->getIDocumentSettingAccess());
2144  if ( bRet && IsInTab() &&
2146  {
2147  nSpace -= rAttrs.GetULSpace().GetLower();
2148 
2150  {
2151  nSpace -= rAttrs.CalcLineSpacing();
2152  }
2153  if ( nSpace < 0 )
2154  {
2155  bRet = false;
2156  }
2157  }
2158 
2159  if (bRet && !bSplit && pFrame->IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem()))
2160  {
2161  if( bTstMove )
2162  {
2163  while( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->HasFollow() )
2164  {
2165  pFrame = static_cast<SwTextFrame*>(pFrame)->GetFollow();
2166  }
2167  // If last follow frame of <this> text frame isn't valid,
2168  // a formatting of the next content frame doesn't makes sense.
2169  // Thus, return true.
2170  if ( IsAnFollow( pFrame ) && !pFrame->isFrameAreaDefinitionValid() )
2171  {
2172  OSL_FAIL( "Only a warning for task 108824:/n<SwContentFrame::WouldFit_(..) - follow not valid!" );
2173  return true;
2174  }
2175  }
2176  SwFrame *pNxt;
2177  if( nullptr != (pNxt = pFrame->FindNext()) && pNxt->IsContentFrame() &&
2178  ( !pFootnoteFrame || ( pNxt->IsInFootnote() &&
2179  pNxt->FindFootnoteFrame()->GetAttr() == pFootnoteFrame->GetAttr() ) ) )
2180  {
2181  // TestFormat(?) does not like paragraph- or character anchored objects.
2182 
2183  // current solution for the test formatting doesn't work, if
2184  // objects are present in the remaining area of the new upper
2185  if ( bTstMove &&
2186  ( pNxt->GetDrawObjs() || bObjsInNewUpper ) )
2187  {
2188  return true;
2189  }
2190 
2191  if ( !pNxt->isFrameAreaDefinitionValid() )
2192  {
2193  MakeNxt( pFrame, pNxt );
2194  }
2195 
2196  // Little trick: if the next has a predecessor, then the paragraph
2197  // spacing has been calculated already, and we don't need to re-calculate
2198  // it in an expensive way.
2199  if( lcl_NotHiddenPrev( pNxt ) )
2200  pTmpPrev = nullptr;
2201  else
2202  {
2203  if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow() )
2204  pTmpPrev = lcl_NotHiddenPrev( pFrame );
2205  else
2206  pTmpPrev = pFrame;
2207  }
2208  pFrame = static_cast<SwContentFrame*>(pNxt);
2209  }
2210  else
2211  pFrame = nullptr;
2212  }
2213  else
2214  pFrame = nullptr;
2215 
2216  } while ( bRet && pFrame );
2217 
2218  return bRet;
2219 }
2220 
2221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:830
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:231
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
bool GetValue() const
#define FRM_NEIGHBOUR
Definition: frame.hxx:106
void SetTop(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1385
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_uInt16 CalcBottomLine() const
Definition: frmtool.hxx:516
Base class of the Writer layout elements.
Definition: frame.hxx:314
Base class that provides the general functionalities for frames that are allowed at page breaks (flow...
Definition: flowfrm.hxx:58
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:159
tools::Long GetWidth() const
void PrepareLock(SwFlowFrame *pTab)
Definition: calcmove.cxx:208
virtual SwRect GetObjRect() const =0
void InvalidateInfFlags()
Definition: frame.hxx:608
SwFrameGet fnGetPrtBottom
Definition: frame.hxx:1323
SDRTEXTVERTADJUST_TOP
bool IsFollow() const
Definition: flowfrm.hxx:166
Point GetPos(const SwRect &rRect) const
Definition: frame.hxx:1382
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
SwRectMax fnOverStep
Definition: frame.hxx:1331
void MakePrtArea(const SwBorderAttrs &)
Definition: calcmove.cxx:1062
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: calcmove.cxx:1209
virtual void MakeAll(vcl::RenderContext *pRenderContext)=0
bool IsInFly() const
Definition: frame.hxx:961
bool IsRootFrame() const
Definition: frame.hxx:1174
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1503
void SetPosY(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1400
sal_uInt16 GetLower() const
bool IsInSct() const
Definition: frame.hxx:967
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"Formats" the Frame; Frame and PrtArea.
Definition: wsfrm.cxx:3427
constexpr auto toTwips(N number, Length from)
bool MoveFwd(bool bMakePage, bool bPageBreak, bool bMoveAlways=false)
Return value guarantees that a new page was not created, although false does not NECESSARILY indicate...
Definition: flowfrm.cxx:1938
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1413
const OUString & GetText() const
Definition: ndtxt.hxx:218
void LOOPING_LOUIE_LIGHT(bool bCondition, const SwTextFrame &rTextFrame)
Definition: layouter.cxx:424
std::string GetValue
bool IsColLocked() const
Definition: frame.hxx:886
bool IsBefore(const SwLayoutFrame *_pCheckRefLayFrame) const
method to check relative position of layout frame to a given layout frame.
Definition: findfrm.cxx:258
friend void ValidateSz(SwFrame *pFrame)
Definition: calcmove.cxx:1200
bool IsKeep(SvxFormatKeepItem const &rKeep, SvxFormatBreakItem const &rBreak, bool bBreakCheck=false) const
method to determine if a Keep needs to be considered (Breaks!)
Definition: flowfrm.cxx:234
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Refresh(const SwFrame *pFrame)
Definition: frame.hxx:1358
void SetCompletePaint() const
Definition: frame.hxx:994
bool IsInFootnote() const
Definition: frame.hxx:949
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:597
SwFrameType GetType() const
Definition: frame.hxx:519
bool IsPrevObjMove() const
Definition: flowfrm.cxx:1124
void SetFlyLock(bool bNew)
Definition: flowfrm.hxx:229
static SwFrame * lcl_Prev(SwFrame *pFrame, bool bSectPrv=true)
Definition: calcmove.cxx:504
long Long
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
#define MINLAY
Definition: swtypes.hxx:62
static SwCache & GetCache()
Definition: frame.hxx:521
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
tools::Long CalcRight(const SwFrame *pCaller) const
Definition: frmtool.cxx:2309
bool JoinedWithPrev(const SwFrame &_rFrame, const SwFrame *_pPrevFrame=nullptr) const
Definition: frmtool.cxx:2589
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1210
bool HasFollow() const
Definition: flowfrm.hxx:165
SwTwips CalcLowerSpace(const SwBorderAttrs *_pAttrs=nullptr) const
calculation of lower space
Definition: flowfrm.cxx:1754
bool MoveBwd(bool &rbReformat)
Return value tells whether any changes have been made.
Definition: flowfrm.cxx:2143
sal_uInt16 CalcTopLine() const
Definition: frmtool.hxx:510
bool IsVert() const
Definition: frame.hxx:1366
SwRectGet fnGetWidth
Definition: frame.hxx:1294
void Pos(const Point &rNew)
Definition: swrect.hxx:171
bool IsEndNote() const
Definition: fmtftn.hxx:71
SwFrame * FindNext()
Definition: frame.hxx:1141
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
bool IsCellFrame() const
Definition: frame.hxx:1226
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
virtual const SvxFormatBreakItem & GetBreakItem() const
Definition: findfrm.cxx:711
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1380
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:34
bool WouldFit_(SwTwips nSpace, SwLayoutFrame *pNewUpper, bool bTstMove, const bool bObjsInNewUpper)
Definition: calcmove.cxx:1986
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2709
SwRectSet fnSubLeft
Definition: frame.hxx:1308
The root element of a Writer document layout.
Definition: rootfrm.hxx:81
void PrepareUnlock(SwFlowFrame *pTab)
Definition: calcmove.cxx:212
bool IsFootnoteFrame() const
Definition: frame.hxx:1202
void SetXMargins(SwFrame &rFrame, tools::Long nLeft, tools::Long nRight) const
Definition: frame.hxx:1406
sal_Int32 GetBrowseWidth() const
Definition: viewsh.cxx:2101
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: calcmove.cxx:794
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
static bool bFootnote
Definition: insfnote.cxx:33
void ValidateSz(SwFrame *pFrame)
Definition: calcmove.cxx:1200
SwRectSet fnAddRight
Definition: frame.hxx:1309
bool IsVertLRBT() const
Definition: frame.hxx:983
void PrepareMake(vcl::RenderContext *pRenderContext)
Prepares the Frame for "formatting" (MakeAll()).
Definition: calcmove.cxx:246
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
constexpr tools::Long Width() const
SwTwips CalcUpperSpace(const SwBorderAttrs *pAttrs=nullptr, const SwFrame *pPr=nullptr, const bool _bConsiderGrid=true) const
method to determine the upper space hold by the frame
Definition: flowfrm.cxx:1457
void PrepareCursor()
Definition: calcmove.cxx:403
bool IsFlyFrame() const
Definition: frame.hxx:1210
sal_uInt16 CalcLeftLine() const
Definition: frmtool.hxx:522
wrapper class for the positioning of Writer fly frames and drawing objects
bool IsMoveable(const SwLayoutFrame *_pLayoutFrame=nullptr) const
determine, if frame is moveable in given environment
Definition: findfrm.cxx:1416
const SwFormatNoBalancedColumns & GetBalancedColumns(bool=true) const
Definition: fmtclbl.hxx:42
virtual bool IsLeaveUpperAllowed() const
Definition: tabfrm.cxx:6128
const SwRect & getFrameArea() const
Definition: frame.hxx:179
bool getBrowseMode() const
Definition: viewopt.hxx:472
virtual Size ChgSize(const Size &aNewSize)
Definition: wsfrm.cxx:731
bool IsEmptyPage() const
Definition: pagefrm.hxx:157
bool IsInTab() const
Definition: frame.hxx:955
const SwPageFrame * GetLastPage() const
Definition: rootfrm.hxx:362
bool IsTextFrame() const
Definition: frame.hxx:1234
SwRectFn fnRectVertL2R
Definition: newfrm.cxx:288
void Width(tools::Long nNew)
Definition: swrect.hxx:189
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:100
bool IsPageBodyFrame() const
Definition: layfrm.hxx:215
bool IsSctFrame() const
Definition: frame.hxx:1214
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1111
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1378
bool IsFlowFrame() const
Definition: frame.hxx:1242
SwRectFn fnRectHori
Definition: newfrm.cxx:286
const SvxFormatKeepItem & GetKeep(bool=true) const
Definition: frmatr.hxx:56
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1579
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:731
const SwFrame & GetFrame() const
Definition: flowfrm.hxx:151
bool IsFootnoteLock() const
Definition: sectfrm.hxx:170
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: wsfrm.cxx:2098
bool IsColumnFrame() const
Definition: frame.hxx:1182
SwRectFn fnRectVertL2RB2T
Definition: newfrm.cxx:289
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1107
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1306
friend void MakeNxt(SwFrame *pFrame, SwFrame *pNxt)
Definition: calcmove.cxx:1908
Style of a layout element.
Definition: frmfmt.hxx:59
bool IsContentFrame() const
Definition: frame.hxx:1230
bool CheckPageHeightValidForHideWhitespace(SwTwips nDiff)
Is bottom-of-page-frame - bottom-of-text-frame difference valid in case whitespace is hidden...
Definition: pagechg.cxx:2535
SwFrame * GetIndPrev() const
Definition: frame.hxx:724
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:131
void InvalidatePrt()
Definition: frame.hxx:1036
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1409
bool IsFwdMoveAllowed() const
Definition: flowfrm.hxx:240
const SwRect & VisArea() const
Definition: viewsh.cxx:630
size_t GetContentHeight(const tools::Long nTop, const tools::Long nBottom) const
Calculate the content height of a page (without columns).
Definition: calcmove.cxx:726
SwTwips CalcAddLowerSpaceAsLastInTableCell(const SwBorderAttrs *_pAttrs=nullptr) const
calculation of the additional space to be considered, if flow frame is the last inside a table cell ...
Definition: flowfrm.cxx:1801
SwDoc & GetDoc()
Definition: node.hxx:213
sal_uInt16 GetBottomLine(const SwFrame &_rFrame) const
Definition: frmtool.hxx:494
SwFrameType
Definition: frame.hxx:74
SwFrame * GetIndNext()
Definition: frame.hxx:727
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
bool IsCollapse() const
Definition: calcmove.cxx:1051
size_t size() const
Definition: sortedobjs.cxx:43
const int cnStopFormat
Definition: calcmove.cxx:1198
tools::Long CalcLeft(const SwFrame *pCaller) const
Definition: frmtool.cxx:2371
static bool lcl_IsCalcUpperAllowed(const SwFrame &rFrame)
Definition: calcmove.cxx:219
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:887
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwNodeOffset GetIndex() const
Definition: node.hxx:292
bool IsInBalancedSection() const
Definition: findfrm.cxx:1872
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
bool IsJoinLocked() const
Definition: flowfrm.hxx:175
virtual const SwFlyFrame * DynCastFlyFrame() const
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
bool isFramePrintAreaValid() const
Definition: frame.hxx:168
unsigned char sal_Bool
bool IsUndersized() const
Definition: flowfrm.hxx:158
void LockJoin()
Definition: flowfrm.hxx:139
bool IsRowFrame() const
Definition: frame.hxx:1222
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:460
constexpr tools::Long BROWSE_HEIGHT
Definition: frmtool.hxx:54
Provides access to settings of a document.
SwFrame * GetPrev()
Definition: frame.hxx:677
const SwAttrSet & GetAttrSet() const
Definition: frmtool.hxx:395
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr)
Definition: unusedf.cxx:25
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:703
bool isFrameAreaPositionValid() const
Definition: frame.hxx:166
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
const IDocumentSettingAccess & getIDocumentSettingAccess() const
Provides access to the document settings interface.
Definition: format.cxx:712
void SSize(const Size &rNew)
Definition: swrect.hxx:180
bool IsLocked() const
Definition: txtfrm.hxx:518
bool isFrameAreaSizeValid() const
Definition: frame.hxx:167
A page of the document layout.
Definition: pagefrm.hxx:57
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
sal_uInt8 BwdMoveNecessary(const SwPageFrame *pPage, const SwRect &rRect)
method to determine overlapping of an object that requests floating
Definition: flowfrm.cxx:329
tools::Long SwTwips
Definition: swtypes.hxx:51
const long LONG_MAX
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
SwBorderAttrs * Get()
Definition: frmtool.cxx:2681
void InvalidateSize()
Definition: frame.hxx:1029
void ResetCompletePaint() const
Definition: frame.hxx:998
bool CheckMoveFwd(bool &rbMakePage, bool bKeep, bool bIgnoreMyOwnKeepValue)
Moves the Frame forward if it seems necessary regarding the current conditions and attributes...
Definition: flowfrm.cxx:1846
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:46
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: node.cxx:2099
void setFrameAreaPositionValid(bool bNew)
Definition: wsfrm.cxx:84
static SwFrame * lcl_NotHiddenPrev(SwFrame *pFrame)
Definition: calcmove.cxx:516
void SetPosX(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1399
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool OverStep(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1417
bool Growable() const
checks whether the SectionFrame is still able to grow, as case may be the environment has to be asked...
Definition: sectfrm.cxx:2152
void MakeNxt(SwFrame *pFrame, SwFrame *pNxt)
Definition: calcmove.cxx:1908
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1389
bool IsVertLR() const
Definition: frame.hxx:979
bool IsTabFrame() const
Definition: frame.hxx:1218
static void lcl_CheckObjects(SwSortedObjs &rSortedObjs, const SwFrame *pFrame, tools::Long &rBot)
Definition: calcmove.cxx:698
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
virtual bool ShouldBwdMoved(SwLayoutFrame *pNewUpper, bool &) override
Return value tells whether the Frame should be moved.
Definition: calcmove.cxx:54
void UnlockJoin()
Definition: flowfrm.hxx:140
sal_uInt16 CalcLineSpacing() const
Definition: frmtool.hxx:546
void OptPrepareMake()
Definition: calcmove.cxx:378
virtual SwFrameFormat & GetFrameFormat()=0
constexpr tools::Long Height() const
unsigned char sal_uInt8
sal_uInt16 GetPhyPageNum() const
Definition: trvlfrm.cxx:1695
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:428
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:129
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1390
void RemoveFromLayout()
Definition: wsfrm.cxx:1007
bool IsRightToLeft() const
Definition: frame.hxx:987
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx.
Definition: layfrm.hxx:210
virtual bool WouldFit(SwTwips &nMaxHeight, bool &bSplit, bool bTst)
Definition: unusedf.cxx:35
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:92
bool IsVertL2R() const
Definition: frame.hxx:1367
const SwContentFrame * GetRef() const
Definition: ftnfrm.cxx:2906
bool IsPageFrame() const
Definition: frame.hxx:1178
void * p
const SwTextFootnote * GetAttr() const
Definition: ftnfrm.hxx:122
const Size & GetBrowseBorder() const
Definition: viewsh.cxx:2096
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
static bool lcl_IsNextFootnoteBoss(const SwFrame *pFrame, const SwFrame *pNxt)
This routine checks whether there are no other FootnoteBosses between the pFrame's FootnoteBoss and t...
Definition: calcmove.cxx:1971
bool IsAnFollow(const SwFlowFrame *pFlow) const
Definition: flowfrm.cxx:726
virtual SwTwips ShrinkFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: wsfrm.cxx:2219
#define FAR_AWAY
Definition: frmtool.hxx:53
static bool IsLocked()
Definition: frmtool.hxx:478
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const Size & GetSize() const
Definition: frmtool.hxx:412
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
#define FRM_NOTE_VERT
Definition: frame.hxx:107
bool IsVertical() const
Definition: frame.hxx:973
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
void SetLeft(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1387
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
Ends a section of nodes in the document model.
Definition: node.hxx:343
SwRectFn fnRectVert
Definition: newfrm.cxx:287
#define STOP_FLY_FORMAT
Definition: calcmove.cxx:1196
virtual void MakePos()
Definition: calcmove.cxx:526
static bool FrameMovedFwdByObjPos(const SwDoc &_rDoc, const SwTextFrame &_rTextFrame, sal_uInt32 &_ornToPageNum)
Definition: layouter.cxx:342
bool IsFootnoteContFrame() const
Definition: frame.hxx:1198
bool IsWhitespaceHidden() const
Definition: viewopt.hxx:488
bool IsNeighbourFrame() const
Definition: frame.hxx:912
bool IsBodyFrame() const
Definition: frame.hxx:1206
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: calcmove.cxx:944
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
class for collecting anchored objects
Definition: sortedobjs.hxx:48
void Height(tools::Long nNew)
Definition: swrect.hxx:193
SwContentFrame * JoinFrame()
Definition: frmform.cxx:616
bool IsFooterFrame() const
Definition: frame.hxx:1194
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
std::unique_ptr< SwSortedObjs > m_pSortedObjs
Definition: pagefrm.hxx:61
bool IsCollapse() const
Definition: calcmove.cxx:1030
bool IsHeaderFrame() const
Definition: frame.hxx:1190
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:399
#define PROTOCOL_ENTER(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:92
const SvxULSpaceItem & GetULSpace() const
Definition: frmtool.hxx:396
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
sal_uInt16 CalcRightLine() const
Definition: frmtool.hxx:528
static bool IsMoveBwdJump()
Definition: flowfrm.hxx:154
SwFrame * GetNext()
Definition: frame.hxx:676