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