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