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