LibreOffice Module sw (master)  1
frmform.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 <config_wasm_strip.h>
21 
22 #include <sal/config.h>
23 #include <sal/log.hxx>
24 
26 #include <anchoredobject.hxx>
27 #include <bodyfrm.hxx>
28 #include <hintids.hxx>
29 #include <editeng/keepitem.hxx>
31 #include <pagefrm.hxx>
32 #include <ndtxt.hxx>
33 #include <ftnfrm.hxx>
34 #include <txtftn.hxx>
35 #include <fmtftn.hxx>
36 #include <paratr.hxx>
37 #include <viewopt.hxx>
38 #include <viewsh.hxx>
39 #include <frmatr.hxx>
40 #include <pam.hxx>
41 #include <fmtanchr.hxx>
42 #include "itrform2.hxx"
43 #include "widorp.hxx"
44 #include "txtcache.hxx"
45 #include <sectfrm.hxx>
46 #include <rootfrm.hxx>
47 #include <frmfmt.hxx>
48 #include <sortedobjs.hxx>
49 #include <editeng/tstpitem.hxx>
50 #include <redline.hxx>
51 #include <comphelper/lok.hxx>
52 
53 // Tolerance in formatting and text output
54 #define SLOPPY_TWIPS 5
55 
56 namespace {
57 
58 class FormatLevel
59 {
60  static sal_uInt16 s_nLevel;
61 public:
62  FormatLevel() { ++s_nLevel; }
63  ~FormatLevel() { --s_nLevel; }
64  static sal_uInt16 GetLevel() { return s_nLevel; }
65  static bool LastLevel() { return 10 < s_nLevel; }
66 };
67 
68 }
69 
70 sal_uInt16 FormatLevel::s_nLevel = 0;
71 
72 void ValidateText( SwFrame *pFrame ) // Friend of frame
73 {
74  if ( ( ! pFrame->IsVertical() &&
75  pFrame->getFrameArea().Width() == pFrame->GetUpper()->getFramePrintArea().Width() ) ||
76  ( pFrame->IsVertical() &&
77  pFrame->getFrameArea().Height() == pFrame->GetUpper()->getFramePrintArea().Height() ) )
78  {
79  pFrame->setFrameAreaSizeValid(true);
80  }
81 }
82 
84 {
85  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
86  // Validate surroundings to avoid oscillation
87  SwSwapIfSwapped swap( this );
88 
89  if ( !IsInFly() && !IsInTab() )
90  { // Only validate 'this' when inside a fly, the rest should actually only be
91  // needed for footnotes, which do not exist in flys.
92  SwSectionFrame* pSct = FindSctFrame();
93  if( pSct )
94  {
95  if( !pSct->IsColLocked() )
96  pSct->ColLock();
97  else
98  pSct = nullptr;
99  }
100 
101  SwFrame *pUp = GetUpper();
102  pUp->Calc(pRenderContext);
103  if( pSct )
104  pSct->ColUnlock();
105  }
106  ValidateText( this );
107 
108  // We at least have to save the MustFit flag!
109  assert(HasPara() && "ResetPreps(), missing ParaPortion, SwCache bug?");
110  SwParaPortion *pPara = GetPara();
111  const bool bMustFit = pPara->IsPrepMustFit();
112  ResetPreps();
113  pPara->SetPrepMustFit( bMustFit );
114 }
115 
116 // After a RemoveFootnote the BodyFrame and all Frames contained within it, need to be
117 // recalculated, so that the DeadLine is right.
118 // First we search outwards, on the way back we calculate everything.
119 static void ValidateBodyFrame_( SwFrame *pFrame )
120 {
121  vcl::RenderContext* pRenderContext = pFrame ? pFrame->getRootFrame()->GetCurrShell()->GetOut() : nullptr;
122  if( !pFrame || pFrame->IsCellFrame() )
123  return;
124 
125  if( !pFrame->IsBodyFrame() && pFrame->GetUpper() )
126  ValidateBodyFrame_( pFrame->GetUpper() );
127  if( !pFrame->IsSctFrame() )
128  pFrame->Calc(pRenderContext);
129  else
130  {
131  const bool bOld = static_cast<SwSectionFrame*>(pFrame)->IsContentLocked();
132  static_cast<SwSectionFrame*>(pFrame)->SetContentLock( true );
133  pFrame->Calc(pRenderContext);
134  if( !bOld )
135  static_cast<SwSectionFrame*>(pFrame)->SetContentLock( false );
136  }
137 }
138 
140 {
141  SwSwapIfSwapped swap( this );
142 
143  // See comment in ValidateFrame()
144  if ( !IsInFly() && !IsInTab() &&
145  !( IsInSct() && FindSctFrame()->Lower()->IsColumnFrame() ) )
147 }
148 
149 bool SwTextFrame::GetDropRect_( SwRect &rRect ) const
150 {
151  SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
152 
153  OSL_ENSURE( HasPara(), "SwTextFrame::GetDropRect_: try again next year." );
154  SwTextSizeInfo aInf( const_cast<SwTextFrame*>(this) );
155  SwTextMargin aLine( const_cast<SwTextFrame*>(this), &aInf );
156  if( aLine.GetDropLines() )
157  {
158  rRect.Top( aLine.Y() );
159  rRect.Left( aLine.GetLineStart() );
160  rRect.Height( aLine.GetDropHeight() );
161  rRect.Width( aLine.GetDropLeft() );
162 
163  if ( IsRightToLeft() )
164  SwitchLTRtoRTL( rRect );
165 
166  if ( IsVertical() )
168  return true;
169  }
170 
171  return false;
172 }
173 
175 {
176  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
177  SwSwapIfSwapped swap( this );
178 
179  OSL_ENSURE( HasFollow(), "CalcFollow: missing Follow." );
180 
181  SwTextFrame* pMyFollow = GetFollow();
182 
183  SwParaPortion *pPara = GetPara();
184  const bool bFollowField = pPara && pPara->IsFollowField();
185 
186  if( !pMyFollow->GetOffset() || pMyFollow->GetOffset() != nTextOfst ||
187  bFollowField || pMyFollow->IsFieldFollow() ||
188  ( pMyFollow->IsVertical() && !pMyFollow->getFramePrintArea().Width() ) ||
189  ( ! pMyFollow->IsVertical() && !pMyFollow->getFramePrintArea().Height() ) )
190  {
191 #if OSL_DEBUG_LEVEL > 0
192  const SwFrame *pOldUp = GetUpper();
193 #endif
194 
195  SwRectFnSet aRectFnSet(this);
196  SwTwips nOldBottom = aRectFnSet.GetBottom(GetUpper()->getFrameArea());
197  SwTwips nMyPos = aRectFnSet.GetTop(getFrameArea());
198 
199  const SwPageFrame *pPage = nullptr;
200  bool bOldInvaContent = true;
201  if ( !IsInFly() && GetNext() )
202  {
203  pPage = FindPageFrame();
204  // Minimize (reset if possible) invalidations: see below
205  bOldInvaContent = pPage->IsInvalidContent();
206  }
207 
208  pMyFollow->SetOffset_( nTextOfst );
209  pMyFollow->SetFieldFollow( bFollowField );
210  if( HasFootnote() || pMyFollow->HasFootnote() )
211  {
212  ValidateFrame();
214  if( pPara )
215  {
216  pPara->GetReformat() = SwCharRange();
217  pPara->SetDelta(0);
218  }
219  }
220 
221  // The footnote area must not get larger
223 
224  pMyFollow->CalcFootnoteFlag();
225  if ( !pMyFollow->GetNext() && !pMyFollow->HasFootnote() )
226  nOldBottom = aRectFnSet.IsVert() ? 0 : LONG_MAX;
227 
228  // tdf#122892 check flag:
229  // 1. WidowsAndOrphans::FindWidows() determines follow is a widow
230  // 2. SwTextFrame::PrepWidows() calls SetPrepWidows() on master;
231  // if it can spare lines, master truncates one line
232  // 3. SwTextFrame::CalcPreps() on master (below);
233  // unless IsPrepMustFit(), if master hasn't shrunk via 2., it will SetWidow()
234  // 4. loop must exit then, because the follow didn't grow so nothing will ever change
235  while (!IsWidow())
236  {
237  if( !FormatLevel::LastLevel() )
238  {
239  // If the follow is contained within a column section or column
240  // frame, we need to calculate that first. This is because the
241  // FormatWidthCols() does not work if it is called from MakeAll
242  // of the _locked_ follow.
243  SwSectionFrame* pSct = pMyFollow->FindSctFrame();
244  if( pSct && !pSct->IsAnLower( this ) )
245  {
246  if( pSct->GetFollow() )
247  pSct->SimpleFormat();
248  else if( ( pSct->IsVertical() && !pSct->getFrameArea().Width() ) ||
249  ( ! pSct->IsVertical() && !pSct->getFrameArea().Height() ) )
250  break;
251  }
252  // i#11760 - Intrinsic format of follow is controlled.
253  if ( FollowFormatAllowed() )
254  {
255  // i#11760 - No nested format of follows, if
256  // text frame is contained in a column frame.
257  // Thus, forbid intrinsic format of follow.
258  {
259  bool bIsFollowInColumn = false;
260  SwFrame* pFollowUpper = pMyFollow->GetUpper();
261  while ( pFollowUpper )
262  {
263  if ( pFollowUpper->IsColumnFrame() )
264  {
265  bIsFollowInColumn = true;
266  break;
267  }
268  if ( pFollowUpper->IsPageFrame() ||
269  pFollowUpper->IsFlyFrame() )
270  {
271  break;
272  }
273  pFollowUpper = pFollowUpper->GetUpper();
274  }
275  if ( bIsFollowInColumn )
276  {
277  pMyFollow->ForbidFollowFormat();
278  }
279  }
280 
281  pMyFollow->Calc(pRenderContext);
282  // The Follow can tell from its getFrameArea().Height() that something went wrong
283  OSL_ENSURE( !pMyFollow->GetPrev(), "SwTextFrame::CalcFollow: cheesy follow" );
284  if( pMyFollow->GetPrev() )
285  {
286  pMyFollow->Prepare();
287  pMyFollow->Calc(pRenderContext);
288  OSL_ENSURE( !pMyFollow->GetPrev(), "SwTextFrame::CalcFollow: very cheesy follow" );
289  }
290 
291  // i#11760 - Reset control flag for follow format.
292  pMyFollow->AllowFollowFormat();
293  }
294 
295  // Make sure that the Follow gets painted
296  pMyFollow->SetCompletePaint();
297  }
298 
299  pPara = GetPara();
300  // As long as the Follow requests lines due to Orphans, it is
301  // passed these and is formatted again if possible
302  if( pPara && pPara->IsPrepWidows() )
303  CalcPreps();
304  else
305  break;
306  }
307 
308  if( HasFootnote() || pMyFollow->HasFootnote() )
309  {
311  ValidateFrame();
312  if( pPara )
313  {
314  pPara->GetReformat() = SwCharRange();
315  pPara->SetDelta(0);
316  }
317  }
318 
319  if ( pPage && !bOldInvaContent )
320  pPage->ValidateContent();
321 
322 #if OSL_DEBUG_LEVEL > 0
323  OSL_ENSURE( pOldUp == GetUpper(), "SwTextFrame::CalcFollow: heavy follow" );
324 #endif
325 
326  const tools::Long nRemaining =
327  - aRectFnSet.BottomDist( GetUpper()->getFrameArea(), nOldBottom );
328  if ( nRemaining > 0 &&
329  nRemaining != ( aRectFnSet.IsVert() ?
330  nMyPos - getFrameArea().Right() :
331  getFrameArea().Top() - nMyPos ) )
332  {
333  return true;
334  }
335  }
336 
337  return false;
338 }
339 
341 {
343  // Inform LOK clients about change in position of redlines (if any)
345  return;
346 
347  SwTextNode const* pTextNode = GetTextNodeFirst();
348  const SwRedlineTable& rTable = pTextNode->getIDocumentRedlineAccess().GetRedlineTable();
349  for (SwRedlineTable::size_type nRedlnPos = 0; nRedlnPos < rTable.size(); ++nRedlnPos)
350  {
351  SwRangeRedline* pRedln = rTable[nRedlnPos];
352  if (pTextNode->GetIndex() == pRedln->GetPoint()->nNode.GetNode().GetIndex())
353  {
355  if (GetMergedPara()
356  && pRedln->GetType() == RedlineType::Delete
357  && pRedln->GetPoint()->nNode != pRedln->GetMark()->nNode)
358  {
359  pTextNode = pRedln->End()->nNode.GetNode().GetTextNode();
360  }
361  }
362  }
363 }
364 
365 void SwTextFrame::AdjustFrame( const SwTwips nChgHght, bool bHasToFit )
366 {
367  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
368  if( IsUndersized() )
369  {
370  if( GetOffset() && !IsFollow() ) // A scrolled paragraph (undersized)
371  return;
372  SetUndersized( nChgHght == 0 || bHasToFit );
373  }
374 
375  // AdjustFrame is called with a swapped frame during
376  // formatting but the frame is not swapped during FormatEmpty
377  SwSwapIfSwapped swap( this );
378  SwRectFnSet aRectFnSet(this);
379 
380  // The Frame's size variable is incremented by Grow or decremented by Shrink.
381  // If the size cannot change, nothing should happen!
382  if( nChgHght >= 0)
383  {
384  SwTwips nChgHeight = nChgHght;
385  if( nChgHght && !bHasToFit )
386  {
387  if( IsInFootnote() && !IsInSct() )
388  {
389  SwTwips nReal = Grow( nChgHght, true );
390  if( nReal < nChgHght )
391  {
392  SwTwips nBot = aRectFnSet.YInc( aRectFnSet.GetBottom(getFrameArea()),
393  nChgHght - nReal );
394  SwFrame* pCont = FindFootnoteFrame()->GetUpper();
395 
396  if( aRectFnSet.BottomDist( pCont->getFrameArea(), nBot ) > 0 )
397  {
399  aRectFnSet.AddBottom( aFrm, nChgHght );
400 
402 
403  if( aRectFnSet.IsVert() )
404  {
405  aPrt.AddWidth(nChgHght );
406  }
407  else
408  {
409  aPrt.AddHeight(nChgHght );
410  }
411 
412  return;
413  }
414  }
415  }
416 
417  Grow( nChgHght );
418 
419  if ( IsInFly() )
420  {
421  // If one of the Upper is a Fly, it's very likely that this fly changes its
422  // position by the Grow. Therefore, my position has to be corrected also or
423  // the check further down is not meaningful.
424  // The predecessors need to be calculated, so that the position can be
425  // calculated correctly.
426  if ( GetPrev() )
427  {
428  SwFrame *pPre = GetUpper()->Lower();
429  do
430  { pPre->Calc(pRenderContext);
431  pPre = pPre->GetNext();
432  } while ( pPre && pPre != this );
433  }
434  const Point aOldPos( getFrameArea().Pos() );
435  MakePos();
436  if ( aOldPos != getFrameArea().Pos() )
437  {
438  InvalidateObjs(false);
439  }
440  }
441  nChgHeight = 0;
442  }
443  // A Grow() is always accepted by the Layout, even if the
444  // FixSize of the surrounding layout frame should not allow it.
445  // We text for this case and correct the values.
446  // The Frame must NOT be shrunk further than its size permits
447  // even in the case of an emergency.
448  SwTwips nRstHeight;
449  if ( IsVertical() )
450  {
451  OSL_ENSURE( ! IsSwapped(),"Swapped frame while calculating nRstHeight" );
452 
453  if ( IsVertLR() )
454  nRstHeight = GetUpper()->getFrameArea().Left()
457  - getFrameArea().Left();
458  else
459  nRstHeight = getFrameArea().Left() + getFrameArea().Width() -
461  }
462  else
463  nRstHeight = GetUpper()->getFrameArea().Top()
466  - getFrameArea().Top();
467 
468  // We can get a bit of space in table cells, because there could be some
469  // left through a vertical alignment to the top.
470  // Assure that first lower in upper is the current one or is valid.
471  if ( IsInTab() &&
472  ( GetUpper()->Lower() == this ||
474  {
475  tools::Long nAdd = aRectFnSet.YDiff( aRectFnSet.GetTop(GetUpper()->Lower()->getFrameArea()),
476  aRectFnSet.GetPrtTop(*GetUpper()) );
477  OSL_ENSURE( nAdd >= 0, "Ey" );
478  nRstHeight += nAdd;
479  }
480 
481  // nRstHeight < 0 means that the TextFrame is located completely outside of its Upper.
482  // This can happen, if it's located within a FlyAtContentFrame, which changed sides by a
483  // Grow(). In such a case, it's wrong to execute the following Grow().
484  // In the case of a bug, we end up with an infinite loop.
485  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
486  SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
487 
488  if( nRstHeight < nFrameHeight )
489  {
490  // It can be that I have the right size, but the Upper is too small and can get me some room
491  if( ( nRstHeight >= 0 || ( IsInFootnote() && IsInSct() ) ) && !bHasToFit )
492  nRstHeight += GetUpper()->Grow( nFrameHeight - nRstHeight );
493  // In column sections we do not want to get too big or else more areas are created by
494  // GetNextSctLeaf. Instead, we shrink and remember bUndersized, so that FormatWidthCols
495  // can calculate the right column size.
496  if ( nRstHeight < nFrameHeight )
497  {
498  if( bHasToFit || !IsMoveable() ||
499  ( IsInSct() && !FindSctFrame()->MoveAllowed(this) ) )
500  {
501  SetUndersized( true );
502  Shrink( std::min( ( nFrameHeight - nRstHeight), nPrtHeight ) );
503  }
504  else
505  SetUndersized( false );
506  }
507  }
508  else if( nChgHeight )
509  {
510  if( nRstHeight - nFrameHeight < nChgHeight )
511  nChgHeight = nRstHeight - nFrameHeight;
512  if( nChgHeight )
513  Grow( nChgHeight );
514  }
515  }
516  else
517  Shrink( -nChgHght );
518 }
519 
520 css::uno::Sequence< css::style::TabStop > SwTextFrame::GetTabStopInfo( SwTwips CurrentPos )
521 {
522  SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this );
523  SwTextFormatter aLine( this, &aInf );
524  SwTextCursor TextCursor( this, &aInf );
525  const Point aCharPos( TextCursor.GetTopLeft() );
526 
527  SwTwips nRight = aLine.Right();
528  CurrentPos -= aCharPos.X();
529 
530  // get current tab stop information stored in the Frame
531  const SvxTabStop *pTS = aLine.GetLineInfo().GetTabStop( CurrentPos, nRight );
532 
533  if( !pTS )
534  {
535  return {};
536  }
537 
538  // copy tab stop information into a Sequence, which only contains one element.
539  css::style::TabStop ts;
540  ts.Position = pTS->GetTabPos();
541  ts.DecimalChar = pTS->GetDecimal();
542  ts.FillChar = pTS->GetFill();
543  switch( pTS->GetAdjustment() )
544  {
545  case SvxTabAdjust::Left : ts.Alignment = css::style::TabAlign_LEFT; break;
546  case SvxTabAdjust::Center : ts.Alignment = css::style::TabAlign_CENTER; break;
547  case SvxTabAdjust::Right : ts.Alignment = css::style::TabAlign_RIGHT; break;
548  case SvxTabAdjust::Decimal: ts.Alignment = css::style::TabAlign_DECIMAL; break;
549  case SvxTabAdjust::Default: ts.Alignment = css::style::TabAlign_DEFAULT; break;
550  default: break; // prevent warning
551  }
552 
553  return { ts };
554 }
555 
556 // AdjustFollow expects the following situation:
557 // The SwTextIter points to the lower end of the Master, the Offset is set in the Follow.
558 // nOffset holds the Offset in the text string, from which the Master closes
559 // and the Follow starts.
560 // If it's 0, the FollowFrame is deleted.
562  const TextFrameIndex nOffset, const TextFrameIndex nEnd,
563  const sal_uInt8 nMode )
564 {
565  SwFrameSwapper aSwapper( this, false );
566 
567  // We got the rest of the text mass: Delete all Follows
568  // DummyPortions() are a special case.
569  // Special cases are controlled by parameter <nMode>.
570  if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
571  {
572  while( GetFollow() )
573  {
574  if( GetFollow()->IsLocked() )
575  {
576  // this can happen when follow calls pMaster->GetFormatted()
577  SAL_INFO("sw.core", "+SwTextFrame::JoinFrame: Follow is locked." );
578  return;
579  }
580  if (GetFollow()->IsDeleteForbidden())
581  return;
582  JoinFrame();
583  }
584 
585  return;
586  }
587 
588  // Dancing on the volcano: We'll just format the last line quickly
589  // for the QuoVadis stuff.
590  // The Offset can move of course:
591  const TextFrameIndex nNewOfst = (IsInFootnote() && (!GetIndNext() || HasFollow()))
592  ? rLine.FormatQuoVadis(nOffset) : nOffset;
593 
594  if( !(nMode & 1) )
595  {
596  // We steal text mass from our Follows
597  // It can happen that we have to join some of them
598  while( GetFollow() && GetFollow()->GetFollow() &&
599  nNewOfst >= GetFollow()->GetFollow()->GetOffset() )
600  {
601  JoinFrame();
602  }
603  }
604 
605  // The Offset moved
606  if( GetFollow() )
607  {
608  if ( nMode )
610 
611  if ( CalcFollow( nNewOfst ) ) // CalcFollow only at the end, we do a SetOffset there
612  rLine.SetOnceMore( true );
613  }
614 }
615 
617 {
618  OSL_ENSURE( GetFollow(), "+SwTextFrame::JoinFrame: no follow" );
619  SwTextFrame *pFoll = GetFollow();
620 
621  SwTextFrame *pNxt = pFoll->GetFollow();
622 
623  // All footnotes of the to-be-destroyed Follow are relocated to us
624  TextFrameIndex nStart = pFoll->GetOffset();
625  if ( pFoll->HasFootnote() )
626  {
627  SwFootnoteBossFrame *pFootnoteBoss = nullptr;
628  SwFootnoteBossFrame *pEndBoss = nullptr;
629  SwTextNode const* pNode(nullptr);
630  sw::MergedAttrIter iter(*pFoll);
631  for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
632  {
633  if (RES_TXTATR_FTN == pHt->Which()
634  && nStart <= pFoll->MapModelToView(pNode, pHt->GetStart()))
635  {
636  if (pHt->GetFootnote().IsEndNote())
637  {
638  if (!pEndBoss)
639  pEndBoss = pFoll->FindFootnoteBossFrame();
640  SwFootnoteBossFrame::ChangeFootnoteRef( pFoll, static_cast<const SwTextFootnote*>(pHt), this );
641  }
642  else
643  {
644  if (!pFootnoteBoss)
645  pFootnoteBoss = pFoll->FindFootnoteBossFrame( true );
646  SwFootnoteBossFrame::ChangeFootnoteRef( pFoll, static_cast<const SwTextFootnote*>(pHt), this );
647  }
648  SetFootnote( true );
649  }
650  }
651  }
652 
653 #ifdef DBG_UTIL
654  else if ( pFoll->isFramePrintAreaValid() ||
655  pFoll->isFrameAreaSizeValid() )
656  {
657  pFoll->CalcFootnoteFlag();
658  OSL_ENSURE( !pFoll->HasFootnote(), "Missing FootnoteFlag." );
659  }
660 #endif
661 
662  pFoll->MoveFlyInCnt( this, nStart, TextFrameIndex(COMPLETE_STRING) );
663  pFoll->SetFootnote( false );
664  // i#27138
665  // Notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
666  // Relation CONTENT_FLOWS_FROM for current next paragraph will change
667  // and relation CONTENT_FLOWS_TO for current previous paragraph, which
668  // is <this>, will change.
669 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
670  {
671  SwViewShell* pViewShell( pFoll->getRootFrame()->GetCurrShell() );
672  if ( pViewShell && pViewShell->GetLayout() &&
673  pViewShell->GetLayout()->IsAnyShellAccessible() )
674  {
675  auto pNext = pFoll->FindNextCnt( true );
676  pViewShell->InvalidateAccessibleParaFlowRelation(
677  pNext ? pNext->DynCastTextFrame() : nullptr,
678  this );
679  }
680  }
681 #endif
682 
683  pFoll->Cut();
684  SetFollow(pNxt);
685  SwFrame::DestroyFrame(pFoll);
686  return pNxt;
687 }
688 
690 {
691  SwSwapIfSwapped swap( this );
692 
693  // The Paste sends a Modify() to me
694  // I lock myself, so that my data does not disappear
695  TextFrameLockGuard aLock( this );
696  SwTextFrame *const pNew = static_cast<SwTextFrame *>(GetTextNodeFirst()->MakeFrame(this));
697 
698  pNew->SetFollow( GetFollow() );
699  SetFollow( pNew );
700 
701  pNew->Paste( GetUpper(), GetNext() );
702  // i#27138
703  // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
704  // Relation CONTENT_FLOWS_FROM for current next paragraph will change
705  // and relation CONTENT_FLOWS_TO for current previous paragraph, which
706  // is <this>, will change.
707 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
708  {
709  SwViewShell* pViewShell( pNew->getRootFrame()->GetCurrShell() );
710  if ( pViewShell && pViewShell->GetLayout() &&
711  pViewShell->GetLayout()->IsAnyShellAccessible() )
712  {
713  auto pNext = pNew->FindNextCnt( true );
714  pViewShell->InvalidateAccessibleParaFlowRelation(
715  pNext ? pNext->DynCastTextFrame() : nullptr,
716  this );
717  }
718  }
719 #endif
720 
721  // If footnotes end up in pNew bz our actions, we need
722  // to re-register them
723  if ( HasFootnote() )
724  {
725  SwFootnoteBossFrame *pFootnoteBoss = nullptr;
726  SwFootnoteBossFrame *pEndBoss = nullptr;
727  SwTextNode const* pNode(nullptr);
728  sw::MergedAttrIter iter(*this);
729  for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
730  {
731  if (RES_TXTATR_FTN == pHt->Which()
732  && nTextPos <= MapModelToView(pNode, pHt->GetStart()))
733  {
734  if (pHt->GetFootnote().IsEndNote())
735  {
736  if (!pEndBoss)
737  pEndBoss = FindFootnoteBossFrame();
738  SwFootnoteBossFrame::ChangeFootnoteRef( this, static_cast<const SwTextFootnote*>(pHt), pNew );
739  }
740  else
741  {
742  if (!pFootnoteBoss)
743  pFootnoteBoss = FindFootnoteBossFrame( true );
744  SwFootnoteBossFrame::ChangeFootnoteRef( this, static_cast<const SwTextFootnote*>(pHt), pNew );
745  }
746  pNew->SetFootnote( true );
747  }
748  }
749  }
750 
751 #ifdef DBG_UTIL
752  else
753  {
754  CalcFootnoteFlag( nTextPos - TextFrameIndex(1) );
755  OSL_ENSURE( !HasFootnote(), "Missing FootnoteFlag." );
756  }
757 #endif
758 
759  MoveFlyInCnt( pNew, nTextPos, TextFrameIndex(COMPLETE_STRING) );
760 
761  // No SetOffset or CalcFollow, because an AdjustFollow follows immediately anyways
762 
763  pNew->ManipOfst( nTextPos );
764 }
765 
767 {
768  // We do not need to invalidate our Follow.
769  // We are a Follow, get formatted right away and call
770  // SetOffset() from there
771  mnOffset = nNewOfst;
772  SwParaPortion *pPara = GetPara();
773  if( pPara )
774  {
775  SwCharRange &rReformat = pPara->GetReformat();
776  rReformat.Start() = TextFrameIndex(0);
777  rReformat.Len() = TextFrameIndex(GetText().getLength());
778  pPara->SetDelta(sal_Int32(rReformat.Len()));
779  }
780  InvalidateSize();
781 }
782 
784 {
785  OSL_ENSURE( ! IsVertical() || ! IsSwapped(), "SwTextFrame::CalcPreps with swapped frame" );
786  SwRectFnSet aRectFnSet(this);
787 
788  SwParaPortion *pPara = GetPara();
789  if ( !pPara )
790  return false;
791  const bool bPrep = pPara->IsPrep();
792  const bool bPrepWidows = pPara->IsPrepWidows();
793  const bool bPrepAdjust = pPara->IsPrepAdjust();
794  const bool bPrepMustFit = pPara->IsPrepMustFit();
795  ResetPreps();
796 
797  bool bRet = false;
798  if( bPrep && !pPara->GetReformat().Len() )
799  {
800  // PrepareHint::Widows means that the orphans rule got activated in the Follow.
801  // In unfortunate cases we could also have a PrepAdjust!
802  if( bPrepWidows )
803  {
804  if( !GetFollow() )
805  {
806  OSL_ENSURE( GetFollow(), "+SwTextFrame::CalcPreps: no credits" );
807  return false;
808  }
809 
810  // We need to prepare for two cases:
811  // We were able to hand over a few lines to the Follow
812  // -> we need to shrink
813  // or we need to go on the next page
814  // -> we let our Frame become too big
815 
816  SwTwips nChgHeight = GetParHeight();
817  if( nChgHeight >= aRectFnSet.GetHeight(getFramePrintArea()) )
818  {
819  if( bPrepMustFit )
820  {
821  GetFollow()->SetJustWidow( true );
822  GetFollow()->Prepare();
823  }
824  else if ( aRectFnSet.IsVert() )
825  {
826  {
828  aFrm.Width( aFrm.Width() + aFrm.Left() );
829  aFrm.Left( 0 );
830  }
831 
832  {
834  aPrt.Width( aPrt.Width() + getFrameArea().Left() );
835  }
836 
837  SetWidow( true );
838  }
839  else
840  {
841  // nTmp should be very large, but not so large as to cause overflow later (e.g.,
842  // GetFrameOfModify in sw/source/core/layout/frmtool.cxx calculates nCurrentDist
843  // from, among others, the square of aDiff.getY(), which can be close to nTmp);
844  // the previously used value TWIPS_MAX/2 (i.e., (LONG_MAX - 1)/2) depended on
845  // the range of 'long', while the value (SAL_MAX_INT32 - 1)/2 (which matches the
846  // old value on platforms where 'long' is 'sal_Int32') is empirically shown to
847  // be large enough in practice even on platforms where 'long' is 'sal_Int64':
848  SwTwips const nTmp = sw::WIDOW_MAGIC - (getFrameArea().Top()+10000);
849  SwTwips nDiff = nTmp - getFrameArea().Height();
850 
851  {
853  aFrm.Height( nTmp );
854  }
855 
856  {
858  aPrt.Height( aPrt.Height() + nDiff );
859  }
860 
861  SetWidow( true );
862  }
863  }
864  else
865  {
866  OSL_ENSURE( nChgHeight < aRectFnSet.GetHeight(getFramePrintArea()),
867  "+SwTextFrame::CalcPrep: want to shrink" );
868 
869  nChgHeight = aRectFnSet.GetHeight(getFramePrintArea()) - nChgHeight;
870 
871  GetFollow()->SetJustWidow( true );
872  GetFollow()->Prepare();
873  Shrink( nChgHeight );
874  SwRect &rRepaint = pPara->GetRepaint();
875 
876  if ( aRectFnSet.IsVert() )
877  {
879  SwitchVerticalToHorizontal( aRepaint );
880  rRepaint.Chg( aRepaint.Pos(), aRepaint.SSize() );
881  }
882  else
883  rRepaint.Chg( getFrameArea().Pos() + getFramePrintArea().Pos(), getFramePrintArea().SSize() );
884 
885  if( 0 >= rRepaint.Width() )
886  rRepaint.Width(1);
887  }
888  bRet = true;
889  }
890  else if ( bPrepAdjust )
891  {
892  if ( HasFootnote() )
893  {
894  if( !CalcPrepFootnoteAdjust() )
895  {
896  if( bPrepMustFit )
897  {
898  SwTextLineAccess aAccess( this );
899  aAccess.GetPara()->SetPrepMustFit(true);
900  }
901  return false;
902  }
903  }
904 
905  {
906  SwSwapIfNotSwapped swap( this );
907 
908  SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this );
909  SwTextFormatter aLine( this, &aInf );
910 
911  WidowsAndOrphans aFrameBreak( this );
912  // Whatever the attributes say: we split the paragraph in
913  // MustFit case if necessary
914  if( bPrepMustFit )
915  {
916  aFrameBreak.SetKeep( false );
917  aFrameBreak.ClrOrphLines();
918  }
919  // Before calling FormatAdjust, we need to make sure
920  // that the lines protruding at the bottom get indeed
921  // truncated
922  bool bBreak = aFrameBreak.IsBreakNowWidAndOrp( aLine );
923  bRet = true;
924  while( !bBreak && aLine.Next() )
925  {
926  bBreak = aFrameBreak.IsBreakNowWidAndOrp( aLine );
927  }
928  if( bBreak )
929  {
930  // We run into troubles: when TruncLines is called, the
931  // conditions in IsInside change immediately such that
932  // IsBreakNow can return different results.
933  // For this reason, we tell rFrameBreak that the
934  // end is reached at the location of rLine.
935  // Let's see if it works ...
936  aLine.TruncLines();
937  aFrameBreak.SetRstHeight( aLine );
938  FormatAdjust( aLine, aFrameBreak, TextFrameIndex(aInf.GetText().getLength()), aInf.IsStop() );
939  }
940  else
941  {
942  if( !GetFollow() )
943  {
944  FormatAdjust( aLine, aFrameBreak,
945  TextFrameIndex(aInf.GetText().getLength()), aInf.IsStop() );
946  }
947  else if ( !aFrameBreak.IsKeepAlways() )
948  {
949  // We delete a line before the Master, because the Follow
950  // could hand over a line
951  const SwCharRange aFollowRg(GetFollow()->GetOffset(), TextFrameIndex(1));
952  pPara->GetReformat() += aFollowRg;
953  // We should continue!
954  bRet = false;
955  }
956  }
957  }
958 
959  // A final check, if FormatAdjust() didn't help we need to
960  // truncate
961  if( bPrepMustFit )
962  {
963  const SwTwips nMust = aRectFnSet.GetPrtBottom(*GetUpper());
964  const SwTwips nIs = aRectFnSet.GetBottom(getFrameArea());
965 
966  if( aRectFnSet.IsVert() && nIs < nMust )
967  {
968  Shrink( nMust - nIs );
969 
970  if( getFramePrintArea().Width() < 0 )
971  {
973  aPrt.Width( 0 );
974  }
975 
976  SetUndersized( true );
977  }
978  else if ( ! aRectFnSet.IsVert() && nIs > nMust )
979  {
980  Shrink( nIs - nMust );
981 
982  if( getFramePrintArea().Height() < 0 )
983  {
985  aPrt.Height( 0 );
986  }
987 
988  SetUndersized( true );
989  }
990  }
991  }
992  }
993  pPara->SetPrepMustFit( bPrepMustFit );
994  return bRet;
995 }
996 
997 // Move the as-character objects - footnotes must be moved by RemoveFootnote!
999 {
1000  if( pFrame->GetOffset() < nNew )
1001  pFrame->MoveFlyInCnt( this, TextFrameIndex(0), nNew );
1002  else if( pFrame->GetOffset() > nNew )
1003  MoveFlyInCnt( pFrame, nNew, TextFrameIndex(COMPLETE_STRING) );
1004 }
1005 
1007  WidowsAndOrphans &rFrameBreak,
1008  TextFrameIndex const nStrLen,
1009  const bool bDummy )
1010 {
1011  SwSwapIfNotSwapped swap( this );
1012 
1013  SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1014 
1015  TextFrameIndex nEnd = rLine.GetStart();
1016 
1017  const bool bHasToFit = pPara->IsPrepMustFit();
1018 
1019  // The StopFlag is set by footnotes which want to go onto the next page
1020  // Call base class method <SwTextFrameBreak::IsBreakNow(..)>
1021  // instead of method <WidowsAndOrphans::IsBreakNow(..)> to get a break,
1022  // even if due to widow rule no enough lines exists.
1023  sal_uInt8 nNew = ( !GetFollow() &&
1024  nEnd < nStrLen &&
1025  ( rLine.IsStop() ||
1026  ( bHasToFit
1027  ? ( rLine.GetLineNr() > 1 &&
1028  !rFrameBreak.IsInside( rLine ) )
1029  : rFrameBreak.IsBreakNow( rLine ) ) ) )
1030  ? 1 : 0;
1031  // i#84870
1032  // no split of text frame, which only contains an as-character anchored object
1033  bool bOnlyContainsAsCharAnchoredObj =
1034  !IsFollow() && nStrLen == TextFrameIndex(1) &&
1035  GetDrawObjs() && GetDrawObjs()->size() == 1 &&
1036  (*GetDrawObjs())[0]->GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR;
1037 
1038  // Still try split text frame if we have columns.
1039  if (FindColFrame())
1040  bOnlyContainsAsCharAnchoredObj = false;
1041 
1042  if ( nNew && bOnlyContainsAsCharAnchoredObj )
1043  {
1044  nNew = 0;
1045  }
1046 
1047  if ( nNew )
1048  {
1049  SplitFrame( nEnd );
1050  }
1051 
1052  const SwFrame *pBodyFrame = FindBodyFrame();
1053 
1054  const tools::Long nBodyHeight = pBodyFrame ? ( IsVertical() ?
1055  pBodyFrame->getFrameArea().Width() :
1056  pBodyFrame->getFrameArea().Height() ) : 0;
1057 
1058  // If the current values have been calculated, show that they
1059  // are valid now
1060  pPara->GetReformat() = SwCharRange();
1061  bool bDelta = pPara->GetDelta() != 0;
1062  pPara->SetDelta(0);
1063 
1064  if( rLine.IsStop() )
1065  {
1066  rLine.TruncLines( true );
1067  nNew = 1;
1068  }
1069 
1070  // FindBreak truncates the last line
1071  if( !rFrameBreak.FindBreak( this, rLine, bHasToFit ) )
1072  {
1073  // If we're done formatting, we set nEnd to the end.
1074  // AdjustFollow might execute JoinFrame() because of this.
1075  // Else, nEnd is the end of the last line in the Master.
1076  TextFrameIndex nOld = nEnd;
1077  nEnd = rLine.GetEnd();
1078  if( GetFollow() )
1079  {
1080  if( nNew && nOld < nEnd )
1081  RemoveFootnote( nOld, nEnd - nOld );
1082  ChangeOffset( GetFollow(), nEnd );
1083  if( !bDelta )
1084  GetFollow()->ManipOfst( nEnd );
1085  }
1086  }
1087  else
1088  { // If we pass over lines, we must not call Join in Follows, instead we even
1089  // need to create a Follow.
1090  // We also need to do this if the whole mass of text remains in the Master,
1091  // because a hard line break could necessitate another line (without text mass)!
1092  TextFrameIndex const nOld(nEnd);
1093  nEnd = rLine.GetEnd();
1094  if( GetFollow() )
1095  {
1096  // Another case for not joining the follow:
1097  // Text frame has no content, but a numbering. Then, do *not* join.
1098  // Example of this case: When an empty, but numbered paragraph
1099  // at the end of page is completely displaced by a fly frame.
1100  // Thus, the text frame introduced a follow by a
1101  // <SwTextFrame::SplitFrame(..)> - see below. The follow then shows
1102  // the numbering and must stay.
1103  if ( GetFollow()->GetOffset() != nEnd ||
1104  GetFollow()->IsFieldFollow() ||
1105  (nStrLen == TextFrameIndex(0) && GetTextNodeForParaProps()->GetNumRule()))
1106  {
1107  nNew |= 3;
1108  }
1109  else if (FindTabFrame() && nEnd > TextFrameIndex(0) &&
1110  rLine.GetInfo().GetChar(nEnd - TextFrameIndex(1)) == CH_BREAK)
1111  {
1112  // We are in a table, the paragraph has a follow and the text
1113  // ends with a hard line break. Don't join the follow just
1114  // because the follow would have no content, we may still need it
1115  // for the paragraph mark.
1116  nNew |= 1;
1117  }
1118  // move footnotes if the follow is kept - if RemoveFootnote() is
1119  // called in next format iteration, it will be with the *new*
1120  // offset so no effect!
1121  if (nNew && nOld < nEnd)
1122  {
1123  RemoveFootnote(nOld, nEnd - nOld);
1124  }
1125  ChangeOffset( GetFollow(), nEnd );
1126  GetFollow()->ManipOfst( nEnd );
1127  }
1128  else
1129  {
1130  const SwTextNode* pTextNode = GetTextNodeForParaProps();
1131  bool bHasVisibleNumRule = nStrLen == TextFrameIndex(0) && pTextNode->GetNumRule();
1132 
1133  if (!pTextNode->HasVisibleNumberingOrBullet())
1134  {
1135  bHasVisibleNumRule = false;
1136  }
1137 
1138  // Only split frame, if the frame contains
1139  // content or contains no content, but has a numbering.
1140  // i#84870 - No split, if text frame only contains one
1141  // as-character anchored object.
1142  if ( !bOnlyContainsAsCharAnchoredObj &&
1143  (nStrLen > TextFrameIndex(0) ||
1144  bHasVisibleNumRule )
1145  )
1146  {
1147  SplitFrame( nEnd );
1148  nNew |= 3;
1149  }
1150  }
1151  // If the remaining height changed e.g by RemoveFootnote() we need to
1152  // fill up in order to avoid oscillation.
1153  if( bDummy && pBodyFrame &&
1154  nBodyHeight < ( IsVertical() ?
1155  pBodyFrame->getFrameArea().Width() :
1156  pBodyFrame->getFrameArea().Height() ) )
1157  rLine.MakeDummyLine();
1158  }
1159 
1160  // In AdjustFrame() we set ourselves via Grow/Shrink
1161  // In AdjustFollow() we set our FollowFrame
1162 
1163  const SwTwips nDocPrtTop = getFrameArea().Top() + getFramePrintArea().Top();
1164  const SwTwips nOldHeight = getFramePrintArea().SSize().Height();
1165  SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
1166 
1167  //#i84870# - no shrink of text frame, if it only contains one as-character anchored object.
1168  if ( nChg < 0 && !bDelta && bOnlyContainsAsCharAnchoredObj )
1169  {
1170  nChg = 0;
1171  }
1172 
1173  // Vertical Formatting:
1174  // The (rotated) repaint rectangle's x coordinate refers to the frame.
1175  // If the frame grows (or shirks) the repaint rectangle cannot simply
1176  // be rotated back after formatting, because we use the upper left point
1177  // of the frame for rotation. This point changes when growing/shrinking.
1178 
1179  if ( IsVertical() && !IsVertLR() && nChg )
1180  {
1181  SwRect &rRepaint = pPara->GetRepaint();
1182  rRepaint.Left( rRepaint.Left() - nChg );
1183  rRepaint.Width( rRepaint.Width() - nChg );
1184  }
1185 
1186  AdjustFrame( nChg, bHasToFit );
1187 
1188  if( HasFollow() || IsInFootnote() )
1189  AdjustFollow_( rLine, nEnd, nStrLen, nNew );
1190 
1191  pPara->SetPrepMustFit( false );
1192 }
1193 
1194 // bPrev is set whether Reformat.Start() was called because of Prev().
1195 // Else, wo don't know whether we can limit the repaint or not.
1196 bool SwTextFrame::FormatLine( SwTextFormatter &rLine, const bool bPrev )
1197 {
1198  OSL_ENSURE( ! IsVertical() || IsSwapped(),
1199  "SwTextFrame::FormatLine( rLine, bPrev) with unswapped frame" );
1200  SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1201  const SwLineLayout *pOldCur = rLine.GetCurr();
1202  const TextFrameIndex nOldLen = pOldCur->GetLen();
1203  const SwTwips nOldAscent = pOldCur->GetAscent();
1204  const SwTwips nOldHeight = pOldCur->Height();
1205  const SwTwips nOldWidth = pOldCur->Width() + pOldCur->GetHangingMargin();
1206  const bool bOldHyph = pOldCur->IsEndHyph();
1207  SwTwips nOldTop = 0;
1208  SwTwips nOldBottom = 0;
1209  if( rLine.GetCurr()->IsClipping() )
1210  rLine.CalcUnclipped( nOldTop, nOldBottom );
1211 
1212  TextFrameIndex const nNewStart = rLine.FormatLine( rLine.GetStart() );
1213 
1214  OSL_ENSURE( getFrameArea().Pos().Y() + getFramePrintArea().Pos().Y() == rLine.GetFirstPos(),
1215  "SwTextFrame::FormatLine: frame leaves orbit." );
1216  OSL_ENSURE( rLine.GetCurr()->Height(),
1217  "SwTextFrame::FormatLine: line height is zero" );
1218 
1219  // The current line break object
1220  const SwLineLayout *pNew = rLine.GetCurr();
1221 
1222  bool bUnChg = nOldLen == pNew->GetLen() &&
1223  bOldHyph == pNew->IsEndHyph();
1224  if ( bUnChg && !bPrev )
1225  {
1226  const tools::Long nWidthDiff = nOldWidth > pNew->Width()
1227  ? nOldWidth - pNew->Width()
1228  : pNew->Width() - nOldWidth;
1229 
1230  // we only declare a line as unchanged, if its main values have not
1231  // changed and it is not the last line (!paragraph end symbol!)
1232  bUnChg = nOldHeight == pNew->Height() &&
1233  nOldAscent == pNew->GetAscent() &&
1234  nWidthDiff <= SLOPPY_TWIPS &&
1235  pOldCur->GetNext();
1236  }
1237 
1238  // Calculate rRepaint
1239  const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
1240  SwRepaint &rRepaint = pPara->GetRepaint();
1241  if( bUnChg && rRepaint.Top() == rLine.Y()
1242  && (bPrev || nNewStart <= pPara->GetReformat().Start())
1243  && (nNewStart < TextFrameIndex(GetText().getLength())))
1244  {
1245  rRepaint.Top( nBottom );
1246  rRepaint.Height( 0 );
1247  }
1248  else
1249  {
1250  if( nOldTop )
1251  {
1252  if( nOldTop < rRepaint.Top() )
1253  rRepaint.Top( nOldTop );
1254  if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
1255  {
1256  rRepaint.Bottom( nOldBottom - 1 );
1257  rLine.SetUnclipped( true );
1258  }
1259  }
1260  if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
1261  {
1262  SwTwips nTmpTop, nTmpBottom;
1263  rLine.CalcUnclipped( nTmpTop, nTmpBottom );
1264  if( nTmpTop < rRepaint.Top() )
1265  rRepaint.Top( nTmpTop );
1266  if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
1267  {
1268  rRepaint.Bottom( nTmpBottom - 1 );
1269  rLine.SetUnclipped( true );
1270  }
1271  }
1272  else
1273  {
1274  if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
1275  {
1276  rRepaint.Bottom( nBottom - 1 );
1277  rLine.SetUnclipped( false );
1278  }
1279  }
1280  SwTwips nRght = std::max( nOldWidth, pNew->Width() +
1281  pNew->GetHangingMargin() );
1283  const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : nullptr;
1284  if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
1285  nRght += ( std::max( nOldAscent, pNew->GetAscent() ) );
1286  else
1287  nRght += ( std::max( nOldAscent, pNew->GetAscent() ) / 4);
1288  nRght += rLine.GetLeftMargin();
1289  if( rRepaint.GetOffset() || rRepaint.GetRightOfst() < nRght )
1290  rRepaint.SetRightOfst( nRght );
1291 
1292  // Finally we enlarge the repaint rectangle if we found an underscore
1293  // within our line. 40 Twips should be enough
1294  const bool bHasUnderscore =
1295  ( rLine.GetInfo().GetUnderScorePos() < nNewStart );
1296  if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() )
1297  rRepaint.Bottom( rRepaint.Bottom() + 40 );
1298 
1299  const_cast<SwLineLayout*>(rLine.GetCurr())->SetUnderscore( bHasUnderscore );
1300  }
1301 
1302  // Calculating the good ol' nDelta
1303  const sal_Int32 nDiff = sal_Int32(pNew->GetLen()) - sal_Int32(nOldLen);
1304  pPara->SetDelta(pPara->GetDelta() - nDiff);
1305 
1306  // Stop!
1307  if( rLine.IsStop() )
1308  return false;
1309 
1310  // Absolutely another line
1311  if( rLine.IsNewLine() )
1312  return true;
1313 
1314  // Until the String's end?
1315  if (nNewStart >= TextFrameIndex(GetText().getLength()))
1316  return false;
1317 
1318  if( rLine.GetInfo().IsShift() )
1319  return true;
1320 
1321  // Reached the Reformat's end?
1322  const TextFrameIndex nEnd = pPara->GetReformat().Start() +
1323  pPara->GetReformat().Len();
1324 
1325  if( nNewStart <= nEnd )
1326  return true;
1327 
1328  return 0 != pPara->GetDelta();
1329 }
1330 
1332  const bool bAdjust )
1333 {
1334  OSL_ENSURE( ! IsVertical() || IsSwapped(),"SwTextFrame::Format_ with unswapped frame" );
1335 
1336  SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1337  rLine.SetUnclipped( false );
1338 
1339  const OUString & rString = GetText();
1340  const TextFrameIndex nStrLen(rString.getLength());
1341 
1342  SwCharRange &rReformat = pPara->GetReformat();
1343  SwRepaint &rRepaint = pPara->GetRepaint();
1344  std::unique_ptr<SwRepaint> pFreeze;
1345 
1346  // Due to performance reasons we set rReformat to COMPLETE_STRING in Init()
1347  // In this case we adjust rReformat
1348  if( rReformat.Len() > nStrLen )
1349  rReformat.Len() = nStrLen;
1350 
1351  if( rReformat.Start() + rReformat.Len() > nStrLen )
1352  rReformat.Len() = nStrLen - rReformat.Start();
1353 
1354  SwTwips nOldBottom;
1355  if( GetOffset() && !IsFollow() )
1356  {
1357  rLine.Bottom();
1358  nOldBottom = rLine.Y();
1359  rLine.Top();
1360  }
1361  else
1362  nOldBottom = 0;
1363  rLine.CharToLine( rReformat.Start() );
1364 
1365  // When inserting or removing a Space, words can be moved out of the edited
1366  // line and into the preceding line, hence the preceding line must be
1367  // formatted as well.
1368  // Optimization: If rReformat starts after the first word of the line,
1369  // this line cannot possibly influence the previous one.
1370  // ...Turns out that unfortunately it can: Text size changes + FlyFrames;
1371  // the feedback can affect multiple lines (Frames!)!
1372 
1373  // i#46560
1374  // FME: Yes, consider this case: "(word )" has to go to the next line
1375  // because ")" is a forbidden character at the beginning of a line although
1376  // "(word" would still fit on the previous line. Adding text right in front
1377  // of ")" would not trigger a reformatting of the previous line. Adding 1
1378  // to the result of FindBrk() does not solve the problem in all cases,
1379  // nevertheless it should be sufficient.
1380  bool bPrev = rLine.GetPrev() &&
1381  (FindBrk(rString, rLine.GetStart(), rReformat.Start() + TextFrameIndex(1))
1382  // i#46560
1383  + TextFrameIndex(1)
1384  >= rReformat.Start() ||
1385  rLine.GetCurr()->IsRest() );
1386  if( bPrev )
1387  {
1388  while( rLine.Prev() )
1389  if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
1390  {
1391  if( !rLine.GetStart() )
1392  rLine.Top(); // So that NumDone doesn't get confused
1393  break;
1394  }
1395  TextFrameIndex nNew = rLine.GetStart() + rLine.GetLength();
1396  if( nNew )
1397  {
1398  --nNew;
1399  if (CH_BREAK == rString[sal_Int32(nNew)])
1400  {
1401  ++nNew;
1402  rLine.Next();
1403  bPrev = false;
1404  }
1405  }
1406  rReformat.Len() += rReformat.Start() - nNew;
1407  rReformat.Start() = nNew;
1408  }
1409 
1410  rRepaint.SetOffset( 0 );
1411  rRepaint.SetRightOfst( 0 );
1412  rRepaint.Chg( getFrameArea().Pos() + getFramePrintArea().Pos(), getFramePrintArea().SSize() );
1413  if( pPara->IsMargin() )
1414  rRepaint.Width( rRepaint.Width() + pPara->GetHangingMargin() );
1415  rRepaint.Top( rLine.Y() );
1416  if( 0 >= rRepaint.Width() )
1417  rRepaint.Width(1);
1418  WidowsAndOrphans aFrameBreak( this, rInf.IsTest() ? 1 : 0 );
1419 
1420  // rLine is now set to the first line which needs formatting.
1421  // The bFirst flag makes sure that Next() is not called.
1422  // The whole thing looks weird, but we need to make sure that
1423  // rLine stops at the last non-fitting line when calling IsBreakNow.
1424  bool bFirst = true;
1425  bool bFormat = true;
1426 
1427  // The CharToLine() can also get us into the danger zone.
1428  // In that case we need to walk back until rLine is set
1429  // to the non-fitting line. Or else the mass of text is lost,
1430  // because the Ofst was set wrongly in the Follow.
1431 
1432  bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
1433  && aFrameBreak.IsBreakNowWidAndOrp( rLine );
1434  if( bBreak )
1435  {
1436  bool bPrevDone = nullptr != rLine.Prev();
1437  while( bPrevDone && aFrameBreak.IsBreakNowWidAndOrp(rLine) )
1438  bPrevDone = nullptr != rLine.Prev();
1439  if( bPrevDone )
1440  {
1441  aFrameBreak.SetKeep( false );
1442  rLine.Next();
1443  }
1444  rLine.TruncLines();
1445 
1446  // Play it safe
1447  aFrameBreak.IsBreakNowWidAndOrp(rLine);
1448  }
1449 
1450  /* Meaning if the following flags are set:
1451 
1452  Watch(End/Mid)Hyph: we need to format if we have a break at
1453  the line end/Fly, as long as MaxHyph is reached
1454 
1455  Jump(End/Mid)Flag: the next line which has no break (line end/Fly),
1456  needs to be formatted, because we could wrap now. This might have been
1457  forbidden earlier by MaxHyph
1458 
1459  Watch(End/Mid)Hyph: if the last formatted line got a cutoff point, but
1460  didn't have one before
1461 
1462  Jump(End/Mid)Hyph: if a cutoff point disappears
1463  */
1464  bool bJumpEndHyph = false;
1465  bool bWatchEndHyph = false;
1466  bool bJumpMidHyph = false;
1467  bool bWatchMidHyph = false;
1468 
1469  const SwAttrSet& rAttrSet = GetTextNodeForParaProps()->GetSwAttrSet();
1470  rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens();
1471  bool bMaxHyph = 0 != rInf.MaxHyph();
1472  if ( bMaxHyph )
1473  rLine.InitCntHyph();
1474 
1475  if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOffset() )
1476  {
1477  SwTextFrame *pMaster = FindMaster();
1478  OSL_ENSURE( pMaster, "SwTextFrame::Format: homeless follow" );
1479  const SwLineLayout* pLine=nullptr;
1480  if (pMaster)
1481  {
1482  if (!pMaster->HasPara())
1483  { // master could be locked because it's being formatted upstack
1484  SAL_WARN("sw", "SwTextFrame::Format_: master not formatted!");
1485  }
1486  else
1487  {
1488  SwTextSizeInfo aInf( pMaster );
1489  SwTextIter aMasterLine( pMaster, &aInf );
1490  aMasterLine.Bottom();
1491  pLine = aMasterLine.GetCurr();
1492  assert(aMasterLine.GetEnd() == GetOffset());
1493  }
1494  }
1495  SwLinePortion* pRest = pLine ?
1496  rLine.MakeRestPortion(pLine, GetOffset()) : nullptr;
1497  if( pRest )
1498  rInf.SetRest( pRest );
1499  else
1500  SetFieldFollow( false );
1501  }
1502 
1503  /* Ad cancel criterion:
1504  * In order to recognize, whether a line does not fit onto the page
1505  * anymore, we need to format it. This overflow is removed again in
1506  * e.g. AdjustFollow.
1507  * Another complication: if we are the Master, we need to traverse
1508  * the lines, because it could happen that one line can overflow
1509  * from the Follow to the Master.
1510  */
1511  do
1512  {
1513  if( bFirst )
1514  bFirst = false;
1515  else
1516  {
1517  if ( bMaxHyph )
1518  {
1519  if ( rLine.GetCurr()->IsEndHyph() )
1520  rLine.CntEndHyph()++;
1521  else
1522  rLine.CntEndHyph() = 0;
1523  if ( rLine.GetCurr()->IsMidHyph() )
1524  rLine.CntMidHyph()++;
1525  else
1526  rLine.CntMidHyph() = 0;
1527  }
1528  if( !rLine.Next() )
1529  {
1530  if( !bFormat )
1531  {
1532  SwLinePortion* pRest =
1533  rLine.MakeRestPortion( rLine.GetCurr(), rLine.GetEnd() );
1534  if( pRest )
1535  rInf.SetRest( pRest );
1536  }
1537  rLine.Insert( new SwLineLayout() );
1538  rLine.Next();
1539  bFormat = true;
1540  }
1541  }
1542  if ( !bFormat && bMaxHyph &&
1543  (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
1544  {
1545  if ( rLine.GetCurr()->IsEndHyph() )
1546  {
1547  if ( bWatchEndHyph )
1548  bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1549  }
1550  else
1551  {
1552  bFormat = bJumpEndHyph;
1553  bWatchEndHyph = false;
1554  bJumpEndHyph = false;
1555  }
1556  if ( rLine.GetCurr()->IsMidHyph() )
1557  {
1558  if ( bWatchMidHyph && !bFormat )
1559  bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1560  }
1561  else
1562  {
1563  bFormat |= bJumpMidHyph;
1564  bWatchMidHyph = false;
1565  bJumpMidHyph = false;
1566  }
1567  }
1568  if( bFormat )
1569  {
1570  const bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
1571  const bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
1572  bFormat = FormatLine( rLine, bPrev );
1573  // There can only be one bPrev ... (???)
1574  bPrev = false;
1575  if ( bMaxHyph )
1576  {
1577  if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
1578  {
1579  bWatchEndHyph = !bOldEndHyph;
1580  bJumpEndHyph = bOldEndHyph;
1581  }
1582  if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
1583  {
1584  bWatchMidHyph = !bOldMidHyph;
1585  bJumpMidHyph = bOldMidHyph;
1586  }
1587  }
1588  }
1589 
1590  if( !rInf.IsNewLine() )
1591  {
1592  if( !bFormat )
1593  bFormat = nullptr != rInf.GetRest();
1594  if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
1595  break;
1596  if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
1597  !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
1598  {
1599  if( GetFollow() )
1600  {
1601  while( rLine.Next() )
1602  ; //Nothing
1603  pFreeze.reset(new SwRepaint( rRepaint )); // to minimize painting
1604  }
1605  else
1606  break;
1607  }
1608  }
1609  bBreak = aFrameBreak.IsBreakNowWidAndOrp(rLine);
1610  }while( !bBreak );
1611 
1612  if( pFreeze )
1613  {
1614  rRepaint = *pFreeze;
1615  pFreeze.reset();
1616  }
1617 
1618  if( !rLine.IsStop() )
1619  {
1620  // If we're finished formatting the text and we still
1621  // have other line objects left, these are superfluous
1622  // now because the text has gotten shorter.
1623  bool bTruncLines = false;
1624  if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
1625  rLine.GetCurr()->GetNext() )
1626  {
1627  bTruncLines = true;
1628  }
1629  else if (GetMergedPara() && rLine.GetCurr()->GetNext())
1630  {
1631  // We can also have superfluous lines with redlining in case the current line is shorter
1632  // than the text length, but the total length of lines is still more than expected.
1633  // Truncate in this case as well.
1634  TextFrameIndex nLen(0);
1635  for (const SwLineLayout* pLine = pPara; pLine; pLine = pLine->GetNext())
1636  {
1637  nLen += pLine->GetLen();
1638  }
1639  bTruncLines = nLen > nStrLen;
1640  }
1641 
1642  if (bTruncLines)
1643  {
1644  rLine.TruncLines();
1645  rLine.SetTruncLines( true );
1646  }
1647  }
1648 
1649  if( rInf.IsTest() )
1650  return;
1651 
1652  // FormatAdjust does not pay off at OnceMore
1653  if( bAdjust || !rLine.GetDropFormat() || !rLine.CalcOnceMore() )
1654  {
1655  FormatAdjust( rLine, aFrameBreak, nStrLen, rInf.IsStop() );
1656  }
1657  if( rRepaint.HasArea() )
1658  SetRepaint();
1659  rLine.SetTruncLines( false );
1660  if( nOldBottom ) // We check whether paragraphs that need scrolling can
1661  // be shrunk, so that they don't need scrolling anymore
1662  {
1663  rLine.Bottom();
1664  SwTwips nNewBottom = rLine.Y();
1665  if( nNewBottom < nOldBottom )
1667  }
1668 }
1669 
1671 {
1672  OSL_ENSURE( ! IsVertical() || IsSwapped(),
1673  "A frame is not swapped in SwTextFrame::FormatOnceMore" );
1674 
1675  SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1676  if( !pPara )
1677  return;
1678 
1679  // If necessary the pPara
1680  sal_uInt16 nOld = static_cast<const SwTextMargin&>(rLine).GetDropHeight();
1681  bool bShrink = false;
1682  bool bGrow = false;
1683  bool bGoOn = rLine.IsOnceMore();
1684  sal_uInt8 nGo = 0;
1685  while( bGoOn )
1686  {
1687  ++nGo;
1688  rInf.Init();
1689  rLine.Top();
1690  if( !rLine.GetDropFormat() )
1691  rLine.SetOnceMore( false );
1692  SwCharRange aRange(TextFrameIndex(0), TextFrameIndex(rInf.GetText().getLength()));
1693  pPara->GetReformat() = aRange;
1694  Format_( rLine, rInf );
1695 
1696  bGoOn = rLine.IsOnceMore();
1697  if( bGoOn )
1698  {
1699  const sal_uInt16 nNew = static_cast<const SwTextMargin&>(rLine).GetDropHeight();
1700  if( nOld == nNew )
1701  bGoOn = false;
1702  else
1703  {
1704  if( nOld > nNew )
1705  bShrink = true;
1706  else
1707  bGrow = true;
1708 
1709  if( bShrink == bGrow || 5 < nGo )
1710  bGoOn = false;
1711 
1712  nOld = nNew;
1713  }
1714 
1715  // If something went wrong, we need to reformat again
1716  if( !bGoOn )
1717  {
1718  rInf.CtorInitTextFormatInfo( getRootFrame()->GetCurrShell()->GetOut(), this );
1719  rLine.CtorInitTextFormatter( this, &rInf );
1720  rLine.SetDropLines( 1 );
1721  rLine.CalcDropHeight( 1 );
1722  SwCharRange aTmpRange(TextFrameIndex(0), TextFrameIndex(rInf.GetText().getLength()));
1723  pPara->GetReformat() = aTmpRange;
1724  Format_( rLine, rInf, true );
1725  // We paint everything ...
1726  SetCompletePaint();
1727  }
1728  }
1729  }
1730 }
1731 
1733 {
1734  const bool bIsEmpty = GetText().isEmpty();
1735 
1736  if ( bIsEmpty )
1737  {
1738  // Empty lines do not get tortured for very long:
1739  // pPara is cleared, which is the same as:
1740  // *pPara = SwParaPortion;
1741  const bool bMustFit = pPara->IsPrepMustFit();
1742  pPara->Truncate();
1743  pPara->FormatReset();
1744 
1745  // delete pSpaceAdd and pKanaComp
1746  pPara->FinishSpaceAdd();
1747  pPara->FinishKanaComp();
1748  pPara->ResetFlags();
1749  pPara->SetPrepMustFit( bMustFit );
1750  }
1751 
1752  OSL_ENSURE( ! IsSwapped(), "A frame is swapped before Format_" );
1753 
1754  if ( IsVertical() )
1756 
1757  SwTextFormatInfo aInf( pRenderContext, this );
1758  SwTextFormatter aLine( this, &aInf );
1759 
1761 
1762  Format_( aLine, aInf );
1763 
1764  if( aLine.IsOnceMore() )
1765  FormatOnceMore( aLine, aInf );
1766 
1767  if ( IsVertical() )
1769 
1770  OSL_ENSURE( ! IsSwapped(), "A frame is swapped after Format_" );
1771 
1772  if( 1 >= aLine.GetDropLines() )
1773  return;
1774 
1775  if( SvxAdjust::Left != aLine.GetAdjust() &&
1776  SvxAdjust::Block != aLine.GetAdjust() )
1777  {
1778  aLine.CalcDropAdjust();
1779  aLine.SetPaintDrop( true );
1780  }
1781 
1782  if( aLine.IsPaintDrop() )
1783  {
1784  aLine.CalcDropRepaint();
1785  aLine.SetPaintDrop( false );
1786  }
1787 }
1788 
1789 // We calculate the text frame's size and send a notification.
1790 // Shrink() or Grow() to adjust the frame's size to the changed required space.
1791 void SwTextFrame::Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs * )
1792 {
1793  SwRectFnSet aRectFnSet(this);
1794 
1796 
1797  // The range autopilot or the BASIC interface pass us TextFrames with
1798  // a width <= 0 from time to time
1799  if( aRectFnSet.GetWidth(getFramePrintArea()) <= 0 )
1800  {
1801  // If MustFit is set, we shrink to the Upper's bottom edge if needed.
1802  // Else we just take a standard size of 12 Pt. (240 twip).
1803  SwTextLineAccess aAccess( this );
1804  tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
1805 
1806  if( aAccess.GetPara()->IsPrepMustFit() )
1807  {
1808  const SwTwips nLimit = aRectFnSet.GetPrtBottom(*GetUpper());
1809  const SwTwips nDiff = - aRectFnSet.BottomDist( getFrameArea(), nLimit );
1810  if( nDiff > 0 )
1811  Shrink( nDiff );
1812  }
1813  else if( 240 < nFrameHeight )
1814  {
1815  Shrink( nFrameHeight - 240 );
1816  }
1817  else if( 240 > nFrameHeight )
1818  {
1819  Grow( 240 - nFrameHeight );
1820  }
1821 
1822  nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
1823  const tools::Long nTop = aRectFnSet.GetTopMargin(*this);
1824 
1825  if( nTop > nFrameHeight )
1826  {
1827  aRectFnSet.SetYMargins( *this, nFrameHeight, 0 );
1828  }
1829  else if( aRectFnSet.GetHeight(getFramePrintArea()) < 0 )
1830  {
1832  aRectFnSet.SetHeight( aPrt, 0 );
1833  }
1834 
1835  return;
1836  }
1837 
1838  const TextFrameIndex nStrLen(GetText().getLength());
1839  if ( nStrLen || !FormatEmpty() )
1840  {
1841 
1842  SetEmpty( false );
1843  // In order to not get confused by nested Formats
1844  FormatLevel aLevel;
1845  if( 12 == FormatLevel::GetLevel() )
1846  return;
1847 
1848  // We could be possibly not allowed to alter the format information
1849  if( IsLocked() )
1850  return;
1851 
1852  // Attention: Format() could be triggered by GetFormatted()
1853  if( IsHiddenNow() )
1854  {
1855  tools::Long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
1856  if( nPrtHeight )
1857  {
1858  HideHidden();
1859  Shrink( nPrtHeight );
1860  }
1861  else
1862  {
1863  // Assure that objects anchored
1864  // at paragraph resp. at/as character inside paragraph
1865  // are hidden.
1867  }
1868  ChgThisLines();
1869  return;
1870  }
1871 
1872  // We do not want to be interrupted during formatting
1873  TextFrameLockGuard aLock(this);
1874 
1875  // this is to ensure that the similar code in SwTextFrame::Format_
1876  // finds the master formatted in case it's needed
1877  if (IsFollow() && IsFieldFollow())
1878  {
1879  SwTextFrame *pMaster = FindMaster();
1880  assert(pMaster);
1881  if (!pMaster->HasPara())
1882  {
1883  pMaster->GetFormatted();
1884  }
1885  if (!pMaster->HasPara())
1886  { // master could be locked because it's being formatted upstack
1887  SAL_WARN("sw", "SwTextFrame::Format: failed to format master!");
1888  }
1889  else
1890  {
1891  SwTextSizeInfo aInf( pMaster );
1892  SwTextIter aMasterLine( pMaster, &aInf );
1893  aMasterLine.Bottom();
1894  SetOffset(aMasterLine.GetEnd());
1895  }
1896  }
1897 
1898  SwTextLineAccess aAccess( this );
1899  const bool bNew = !aAccess.IsAvailable();
1900  const bool bSetOffset =
1902 
1903  if( CalcPreps() )
1904  ; // nothing
1905  // We return if already formatted, but if the TextFrame was just created
1906  // and does not have any format information
1907  else if( !bNew && !aAccess.GetPara()->GetReformat().Len() )
1908  {
1910  {
1911  aAccess.GetPara()->SetPrepAdjust();
1912  aAccess.GetPara()->SetPrep();
1913  CalcPreps();
1914  }
1915  SetWidow( false );
1916  }
1917  else if( bSetOffset && IsFollow() )
1918  {
1919  SwTextFrame *pMaster = FindMaster();
1920  OSL_ENSURE( pMaster, "SwTextFrame::Format: homeless follow" );
1921  if( pMaster )
1922  pMaster->Prepare( PrepareHint::FollowFollows );
1923  SwTwips nMaxY = aRectFnSet.GetPrtBottom(*GetUpper());
1924 
1925  if( aRectFnSet.OverStep( getFrameArea(), nMaxY ) )
1926  {
1927  aRectFnSet.SetLimit( *this, nMaxY );
1928  }
1929  else if( aRectFnSet.BottomDist( getFrameArea(), nMaxY ) < 0 )
1930  {
1932  aRectFnSet.AddBottom( aFrm, -aRectFnSet.GetHeight(aFrm) );
1933  }
1934  }
1935  else
1936  {
1937  // bSetOffset here means that we have the "red arrow situation"
1938  if ( bSetOffset )
1940 
1941  const bool bOrphan = IsWidow();
1942  const SwFootnoteBossFrame* pFootnoteBoss = HasFootnote() ? FindFootnoteBossFrame() : nullptr;
1943  SwTwips nFootnoteHeight = 0;
1944  if( pFootnoteBoss )
1945  {
1946  const SwFootnoteContFrame* pCont = pFootnoteBoss->FindFootnoteCont();
1947  nFootnoteHeight = pCont ? aRectFnSet.GetHeight(pCont->getFrameArea()) : 0;
1948  }
1949  do
1950  {
1951  Format_( pRenderContext, aAccess.GetPara() );
1952  if( pFootnoteBoss && nFootnoteHeight )
1953  {
1954  const SwFootnoteContFrame* pCont = pFootnoteBoss->FindFootnoteCont();
1955  SwTwips nNewHeight = pCont ? aRectFnSet.GetHeight(pCont->getFrameArea()) : 0;
1956  // If we lost some footnotes, we may have more space
1957  // for our main text, so we have to format again ...
1958  if( nNewHeight < nFootnoteHeight )
1959  nFootnoteHeight = nNewHeight;
1960  else
1961  break;
1962  }
1963  else
1964  break;
1965  } while ( pFootnoteBoss );
1966  if( bOrphan )
1967  {
1968  ValidateFrame();
1969  SetWidow( false );
1970  }
1971  }
1972  if( IsEmptyMaster() )
1973  {
1974  SwFrame* pPre = GetPrev();
1975  if( pPre &&
1976  // i#10826 It's the first, it cannot keep!
1977  pPre->GetIndPrev() &&
1978  pPre->GetAttrSet()->GetKeep().GetValue() )
1979  {
1980  pPre->InvalidatePos();
1981  }
1982  }
1983  }
1984 
1985  ChgThisLines();
1986 
1987  // the PrepMustFit should not survive a Format operation
1988  SwParaPortion *pPara = GetPara();
1989  if ( pPara )
1990  pPara->SetPrepMustFit( false );
1991 
1993  CalcHeightOfLastLine(); // i#11860 - Adjust spacing implementation for
1994  // object positioning - Compatibility to MS Word
1995  // tdf#117982 -- Fix cell spacing hides content
1996  // Check if the cell's content has greater size than the row height
1998  || (getFramePrintArea().Height() <= 0)))
1999  {
2000  SAL_INFO("sw.core", "Warn: Cell content has greater size than cell height!");
2001  //get font size...
2002  SwTwips aTmpHeight = getFrameArea().Height();
2003  //...and push it into the text frame
2005  //if only bottom margin what we have:
2006  if (GetTopMargin() == 0)
2007  //set the frame to its original location
2008  aPrt.SetTopAndHeight(0, aTmpHeight);
2009  }
2010 }
2011 
2012 // bForceQuickFormat is set if GetFormatted() has been called during the
2013 // painting process. Actually I cannot imagine a situation which requires
2014 // a full formatting of the paragraph during painting, on the other hand
2015 // a full formatting can cause the invalidation of other layout frames,
2016 // e.g., if there are footnotes in this paragraph, and invalid layout
2017 // frames will not calculated during the painting. So I actually want to
2018 // avoid a formatting during painting, but since I'm a coward, I'll only
2019 // force the quick formatting in the situation of issue i29062.
2020 bool SwTextFrame::FormatQuick( bool bForceQuickFormat )
2021 {
2022  OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
2023  "SwTextFrame::FormatQuick with swapped frame" );
2024 
2025  if( IsEmpty() && FormatEmpty() )
2026  return true;
2027 
2028  // We're very picky:
2029  if( HasPara() || IsWidow() || IsLocked()
2030  || !isFrameAreaSizeValid() ||
2032  return false;
2033 
2034  SwTextLineAccess aAccess( this );
2035  SwParaPortion *pPara = aAccess.GetPara();
2036  if( !pPara )
2037  return false;
2038 
2039  SwFrameSwapper aSwapper( this, true );
2040 
2041  TextFrameLockGuard aLock(this);
2042  SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this, false, true );
2043  if( 0 != aInf.MaxHyph() ) // Respect MaxHyphen!
2044  return false;
2045 
2046  SwTextFormatter aLine( this, &aInf );
2047 
2048  // DropCaps are too complicated ...
2049  if( aLine.GetDropFormat() )
2050  return false;
2051 
2052  TextFrameIndex nStart = GetOffset();
2053  const TextFrameIndex nEnd = GetFollow()
2054  ? GetFollow()->GetOffset()
2055  : TextFrameIndex(aInf.GetText().getLength());
2056 
2057  int nLoopProtection = 0;
2058  do
2059  {
2060  TextFrameIndex nNewStart = aLine.FormatLine(nStart);
2061  if (nNewStart == nStart)
2062  ++nLoopProtection;
2063  else
2064  nLoopProtection = 0;
2065  nStart = nNewStart;
2066  const bool bWillEndlessInsert = nLoopProtection > 250;
2067  SAL_WARN_IF(bWillEndlessInsert, "sw", "loop detection triggered");
2068  if ((!bWillEndlessInsert) // Check for special case: line is invisible,
2069  // like in too thin table cell: tdf#66141
2070  && (aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd)))
2071  aLine.Insert( new SwLineLayout() );
2072  } while( aLine.Next() );
2073 
2074  // Last exit: the heights need to match
2075  Point aTopLeft( getFrameArea().Pos() );
2076  aTopLeft += getFramePrintArea().Pos();
2077  const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
2078  const SwTwips nOldHeight = aTopLeft.Y() + getFramePrintArea().Height();
2079 
2080  if( !bForceQuickFormat && nNewHeight != nOldHeight && !IsUndersized() )
2081  {
2082  // Attention: This situation can occur due to FormatLevel==12. Don't panic!
2083  TextFrameIndex const nStrt = GetOffset();
2084  InvalidateRange_( SwCharRange( nStrt, nEnd - nStrt) );
2085  return false;
2086  }
2087 
2088  if (m_pFollow && nStart != static_cast<SwTextFrame*>(m_pFollow)->GetOffset())
2089  return false; // can be caused by e.g. Orphans
2090 
2091  // We made it!
2092 
2093  // Set repaint
2094  pPara->GetRepaint().Pos( aTopLeft );
2095  pPara->GetRepaint().SSize( getFramePrintArea().SSize() );
2096 
2097  // Delete reformat
2098  pPara->GetReformat() = SwCharRange();
2099  pPara->SetDelta(0);
2100 
2101  return true;
2102 }
2103 
2104 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void HideHidden()
Removes Textfrm's attachments, when it's hidden.
Definition: txtfrm.cxx:1446
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:231
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:339
bool GetValue() const
void CalcAdditionalFirstLineOffset()
Simulate format for a list item paragraph, whose list level attributes are in LABEL_ALIGNMENT mode...
Definition: txtfrm.cxx:3491
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:225
Base class of the Writer layout elements.
Definition: frame.hxx:314
sal_uInt8 & GetMaxHyphens()
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:162
bool FindBreak(SwTextFrame *pFrame, SwTextMargin &rLine, bool bHasToFit)
The Find*-Methods do not only search, but adjust the SwTextMargin to the line where the paragraph sho...
Definition: widorp.cxx:353
TextFrameIndex FormatQuoVadis(TextFrameIndex nStart)
Definition: txtftn.cxx:1071
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout...
Definition: txtfrm.cxx:583
const SvxHyphenZoneItem & GetHyphenZone(bool=true) const
Definition: paratr.hxx:206
SwTwips GetParHeight() const
Returns the sum of line height in pLine.
Definition: txtfrm.cxx:3352
void AllowFollowFormat()
Definition: txtfrm.hxx:752
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
bool IsFollow() const
Definition: flowfrm.hxx:166
void SetRstHeight(const SwTextMargin &rLine)
Definition: widorp.cxx:256
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
void Right(const SwTwips nNew)
Definition: itrtxt.hxx:157
void CalcDropRepaint()
Definition: itradj.cxx:828
bool IsPrepAdjust() const
Definition: porlay.hxx:312
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:87
bool IsClipping() const
Definition: porlay.hxx:154
void SetPrepAdjust()
Definition: porlay.hxx:311
bool IsInFly() const
Definition: frame.hxx:961
bool FollowFormatAllowed() const
Definition: txtfrm.hxx:747
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1503
bool IsInSct() const
Definition: frame.hxx:967
const SwTwips WIDOW_MAGIC
Definition: txtfrm.hxx:1026
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1413
bool IsRest() const
Definition: porlay.hxx:129
void MakeDummyLine()
This function creates a Line that reaches to the other Page Margin.
Definition: txtftn.cxx:1275
void ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmform.cxx:998
SwLineLayout * GetNext()
Definition: porlay.hxx:159
bool IsSwapped() const
Definition: txtfrm.hxx:539
const SwFormatDrop * GetDropFormat() const
Definition: itrform2.hxx:196
void ColLock()
Definition: sectfrm.hxx:99
bool IsColLocked() const
Definition: frame.hxx:886
bool HasPara() const
Definition: txtfrm.hxx:823
void CalcBaseOfstForFly()
Definition: txtfrm.cxx:3985
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
void MaybeNotifyRedlinePositionModification(tools::Long nTop)
Definition: docredln.cxx:1189
bool IsNewLine() const
Definition: itrform2.hxx:177
void ClrOrphLines()
Definition: widorp.hxx:63
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
SwNodeIndex nNode
Definition: pam.hxx:38
void SetCompletePaint() const
Definition: frame.hxx:994
SwParaPortion * GetPara()
Definition: txtcache.cxx:50
bool IsInFootnote() const
Definition: frame.hxx:949
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:476
void ValidateText(SwFrame *pFrame)
Definition: frmform.cxx:72
long Long
SwTwips GetHangingMargin() const
Definition: porlay.hxx:176
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true) override
SwContentFrame: the shortcut for the Frames If the void* casts wrongly, it's its own fault! The void*...
Definition: txtfrm.cxx:2744
bool IsStop() const
Definition: itrform2.hxx:174
TextFrameIndex mnOffset
Definition: txtfrm.hxx:202
const SwPosition * GetMark() const
Definition: pam.hxx:210
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:454
bool IsEmptyMaster() const
If there's a Follow and we don't contain text ourselves.
Definition: txtfrm.hxx:450
TextFrameIndex GetUnderScorePos() const
Definition: inftxt.hxx:641
void ValidateContent() const
Definition: pagefrm.hxx:417
sal_uInt16 GetDropHeight() const
Definition: itrtxt.hxx:205
bool HasFollow() const
Definition: flowfrm.hxx:165
void MoveFlyInCnt(SwTextFrame *pNew, TextFrameIndex nStart, TextFrameIndex nEnd)
Rewires FlyInContentFrame, if nEnd > Index >= nStart.
Definition: porfly.cxx:150
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
void InvalidatePos()
Definition: frame.hxx:1043
const SwBodyFrame * FindBodyFrame() const
Definition: frame.hxx:1120
SwNode & GetNode() const
Definition: ndindex.hxx:128
void CharToLine(TextFrameIndex)
Definition: itrtxt.cxx:193
static void ChangeFootnoteRef(const SwContentFrame *pOld, const SwTextFootnote *, SwContentFrame *pNew)
Definition: ftnfrm.cxx:1762
void Format_(vcl::RenderContext *pRenderContext, SwParaPortion *pPara)
Definition: frmform.cxx:1732
void CalcDropAdjust()
Definition: itradj.cxx:745
bool IsVert() const
Definition: frame.hxx:1366
bool GetDropRect_(SwRect &rRect) const
Definition: frmform.cxx:149
const SwLineLayout * Next()
Definition: itrtxt.cxx:107
bool FormatLine(SwTextFormatter &rLine, const bool bPrev)
Definition: frmform.cxx:1196
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:388
void HideAndShowObjects()
Hides respectively shows objects, which are anchored at paragraph, at/as a character of the paragraph...
Definition: txtfrm.cxx:1552
void Pos(const Point &rNew)
Definition: swrect.hxx:171
bool IsPrep() const
Definition: porlay.hxx:306
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
bool IsKeepAlways() const
Definition: widorp.hxx:38
bool IsCellFrame() const
Definition: frame.hxx:1226
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1380
SwTwips Y() const
Definition: itrtxt.hxx:90
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1393
bool IsEndHyph() const
Definition: porlay.hxx:123
sal_uInt8 & MaxHyph()
Definition: inftxt.hxx:554
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:250
void SetTopAndHeight(tools::Long nTop, tools::Long nNew)
Definition: swrect.cxx:156
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
TextFrameIndex & Start()
Definition: porlay.hxx:45
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:91
void SetJustWidow(const bool bNew)
Definition: txtfrm.hxx:250
void CalcFootnoteFlag(TextFrameIndex nStop=TextFrameIndex(COMPLETE_STRING))
Does the Frame have a local footnote (in this Frame or Follow)?
Definition: txtftn.cxx:103
bool IsBreakNowWidAndOrp(SwTextMargin &rLine)
Definition: widorp.hxx:69
bool FormatQuick(bool bForceQuickFormat)
Definition: frmform.cxx:2020
size_type size() const
Definition: docary.hxx:267
void InitCntHyph()
Definition: itrform2.hxx:218
SwTextFormatInfo & GetInfo()
Definition: itrform2.hxx:213
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1363
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
void CalcUnclipped(SwTwips &rTop, SwTwips &rBottom)
Definition: itrform2.cxx:2166
void ValidateBodyFrame()
Definition: frmform.cxx:139
const SwRegisterItem & GetRegister(bool=true) const
Definition: paratr.hxx:198
void InvalidateObjs(const bool _bNoInvaOfAsCharAnchoredObjs=true)
Definition: fly.cxx:2363
bool IsFlyFrame() const
Definition: frame.hxx:1210
bool IsMoveable(const SwLayoutFrame *_pLayoutFrame=nullptr) const
determine, if frame is moveable in given environment
Definition: findfrm.cxx:1416
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
const SwRect & getFrameArea() const
Definition: frame.hxx:179
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1036
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
SwFlowFrame * m_pFollow
Definition: flowfrm.hxx:117
sal_Unicode GetChar(TextFrameIndex const nPos) const
Definition: inftxt.hxx:240
bool IsInTab() const
Definition: frame.hxx:955
sal_Int32 & GetTabPos()
bool IsPaintDrop() const
Definition: itrpaint.hxx:56
void SetDelta(tools::Long nDelta)
Definition: porlay.hxx:289
void FormatReset()
Definition: porlay.hxx:337
void Width(tools::Long nNew)
Definition: swrect.hxx:189
sal_Unicode & GetDecimal()
void ResetFlags()
Definition: porlay.cxx:809
void CtorInitTextFormatInfo(OutputDevice *pRenderContext, SwTextFrame *pFrame, const bool bInterHyph=false, const bool bQuick=false, const bool bTst=false)
Definition: inftxt.cxx:1422
bool IsSctFrame() const
Definition: frame.hxx:1214
bool IsNewLine() const
Definition: inftxt.hxx:578
void SetRepaint() const
Definition: txtfrm.hxx:875
void SetLimit(SwFrame &rFrame, tools::Long nNew) const
Definition: frame.hxx:1416
const SvxFormatKeepItem & GetKeep(bool=true) const
Definition: frmatr.hxx:56
void SetTruncLines(bool bNew)
Definition: itrform2.hxx:205
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:859
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:442
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:731
SvxTabAdjust & GetAdjustment()
bool IsInvalidContent() const
Definition: pagefrm.hxx:235
void SetUndersized(const bool bNew)
Definition: flowfrm.hxx:157
bool CalcFollow(TextFrameIndex nTextOfst)
Definition: frmform.cxx:174
bool IsFollowField() const
Definition: porlay.hxx:314
bool IsColumnFrame() const
Definition: frame.hxx:1182
bool IsEmpty() const
Definition: txtfrm.hxx:525
void ResetPreps()
Definition: txtfrm.cxx:1354
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1107
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:461
void SetDropLines(const sal_uInt16 nNew)
Definition: itrtxt.hxx:203
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1306
bool IsWidow() const
Definition: txtfrm.hxx:523
void Bottom()
Definition: itrtxt.cxx:185
SwTwips GetFirstPos() const
Definition: itrtxt.hxx:129
bool IsShift() const
Definition: inftxt.hxx:580
SwFrame * GetIndPrev() const
Definition: frame.hxx:724
void AdjustFollow_(SwTextFormatter &rLine, TextFrameIndex nOffset, TextFrameIndex nStrEnd, const sal_uInt8 nMode)
Definition: frmform.cxx:561
const IDocumentRedlineAccess & getIDocumentRedlineAccess() const
Provides access to the document redline interface.
Definition: node.cxx:2102
SwTwips GetLineStart() const
Definition: itrcrsr.cxx:381
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1409
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:78
const SwPosition * GetPoint() const
Definition: pam.hxx:208
bool IsInside(SwTextMargin const &rLine) const
BP 18.6.93: Widows.
Definition: widorp.cxx:102
void Top()
Definition: itrtxt.hxx:99
const SwLineInfo & GetLineInfo() const
Definition: itrtxt.hxx:128
SwFrame * GetIndNext()
Definition: frame.hxx:727
void SplitFrame(TextFrameIndex nTextPos)
Methods to manage the FollowFrame.
Definition: frmform.cxx:689
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:173
size_t size() const
Definition: sortedobjs.cxx:43
Mutex aLock
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
SwParaPortion * GetParaPortion()
Definition: inftxt.hxx:121
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:887
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:925
SwCharRange & GetReformat()
Definition: porlay.hxx:287
tools::Long YInc(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1424
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:215
void ManipOfst(TextFrameIndex const nNewOfst)
Definition: txtfrm.hxx:445
SwNodeOffset GetIndex() const
Definition: node.hxx:292
vector_type::size_type size_type
Definition: docary.hxx:222
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
void CtorInitTextFormatter(SwTextFrame *pFrame, SwTextFormatInfo *pInf)
Definition: itrform2.cxx:88
void FinishKanaComp()
Definition: porlay.hxx:201
void SetFollow(SwFlowFrame *const pFollow)
Definition: flowfrm.cxx:91
bool IsParagraph(bool bHard=false) const
Definition: viewopt.hxx:236
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
bool HasArea() const
Definition: swrect.hxx:300
void SetOffset_(TextFrameIndex nNewOfst)
Definition: frmform.cxx:766
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:124
bool isFramePrintAreaValid() const
Definition: frame.hxx:168
bool IsPrepWidows() const
Definition: porlay.hxx:308
SwTwips GetLeftMargin() const
Definition: itrtxt.hxx:328
bool IsUndersized() const
Definition: flowfrm.hxx:158
void FinishSpaceAdd()
Definition: porlay.hxx:186
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2834
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:82
tools::Long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1408
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:460
SwFrame * GetPrev()
Definition: frame.hxx:677
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3392
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1402
void AddWidth(const tools::Long nAdd)
Definition: swrect.cxx:123
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:272
bool IsLineBreak(bool bHard=false) const
Definition: viewopt.hxx:252
css::uno::Sequence< css::style::TabStop > GetTabStopInfo(SwTwips CurrentPos) override
Definition: frmform.cxx:520
void TruncLines(bool bNoteFollow=false)
Definition: itrtxt.cxx:330
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1422
void SSize(const Size &rNew)
Definition: swrect.hxx:180
bool IsLocked() const
Definition: txtfrm.hxx:521
const sal_uInt8 & CntMidHyph() const
Definition: itrform2.hxx:220
bool isFrameAreaSizeValid() const
Definition: frame.hxx:167
bool IsUnclipped() const
Definition: itrform2.hxx:207
TextFrameIndex GetLen() const
Definition: porlin.hxx:76
void CalcHeightOfLastLine(const bool _bUseFont=false)
method to determine height of last line, needed for proportional line spacing
Definition: txtfrm.cxx:3577
A page of the document layout.
Definition: pagefrm.hxx:57
#define SLOPPY_TWIPS
Definition: frmform.cxx:54
SwTwips GetRightOfst() const
Definition: porlay.hxx:72
Point GetTopLeft() const
Definition: itrtxt.hxx:186
tools::Long SwTwips
Definition: swtypes.hxx:51
bool IsMargin() const
Definition: porlay.hxx:321
const long LONG_MAX
#define Y
const OUString & GetText() const
Definition: inftxt.hxx:239
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
Definition: frmform.cxx:1791
bool IsStop() const
Definition: inftxt.hxx:574
SwTwips Shrink(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1547
void InvalidateSize()
Definition: frame.hxx:1029
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
void ValidateFrame()
Definition: frmform.cxx:83
SwFrame * FindColFrame()
Definition: findfrm.cxx:584
void SetUnclipped(bool bNew)
Definition: itrform2.hxx:208
SwTwips & GetAscent()
Definition: porlin.hxx:79
void Truncate()
Definition: porlin.hxx:209
static void ValidateBodyFrame_(SwFrame *pFrame)
Definition: frmform.cxx:119
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:686
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:51
const SwLineLayout * Prev()
Definition: itrtxt.cxx:89
bool IsPrepMustFit() const
Definition: porlay.hxx:310
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool OverStep(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1417
void FormatAdjust(SwTextFormatter &rLine, WidowsAndOrphans &rFrameBreak, TextFrameIndex nStrLen, const bool bDummy)
Definition: frmform.cxx:1006
bool CalcPreps()
Definition: frmform.cxx:783
bool IsBreakNow(SwTextMargin &rLine)
Definition: widorp.cxx:218
void SetYMargins(SwFrame &rFrame, tools::Long nTop, tools::Long nBottom) const
Definition: frame.hxx:1407
TextFrameIndex FormatLine(TextFrameIndex nStart)
Definition: itrform2.cxx:1659
bool IsVertLR() const
Definition: frame.hxx:979
SwTwips CalcBottomLine() const
Definition: itrform2.cxx:2078
bool IsMidHyph() const
Definition: porlay.hxx:125
SwTwips Width() const
Definition: possiz.hxx:51
sal_uInt16 GetDropLeft() const
Definition: itrtxt.hxx:204
sal_Unicode & GetFill()
void CalcDropHeight(const sal_uInt16 nLines)
Definition: txtdrop.cxx:483
void SetOffset(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:869
void SimpleFormat()
Definition: sectfrm.cxx:1173
TextFrameIndex GetLength() const
Definition: itrtxt.hxx:86
#define SAL_WARN_IF(condition, area, stream)
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:737
void ColUnlock()
Definition: sectfrm.hxx:100
unsigned char sal_uInt8
SwRepaint & GetRepaint()
Definition: porlay.hxx:285
void SetFootnote(const bool bNew)
Will be moved soon.
Definition: txtfrm.hxx:603
SwLinePortion * GetRest()
Definition: inftxt.hxx:576
void ForbidFollowFormat()
Definition: txtfrm.hxx:757
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1255
void SetFieldFollow(const bool bNew)
Definition: txtfrm.hxx:252
#define SAL_INFO(area, stream)
void SetOnceMore(bool bNew)
Definition: itrform2.hxx:202
void AdjustFrame(const SwTwips nChgHeight, bool bHasToFit=false)
Definition: frmform.cxx:365
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1390
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:423
void SetRightOfst(const SwTwips nNew)
Definition: porlay.hxx:73
SvxAdjust GetAdjust() const
Definition: itrtxt.hxx:190
bool CalcPrepFootnoteAdjust()
Definition: txtftn.cxx:138
const SwPosition * End() const
Definition: pam.hxx:218
const sal_uInt8 & CntEndHyph() const
Definition: itrform2.hxx:219
virtual void MakePos() override
Definition: frmform.cxx:340
bool IsRightToLeft() const
Definition: frame.hxx:987
void SetKeep(const bool bNew)
Definition: widorp.hxx:40
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1929
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:92
static TextFrameIndex FindBrk(const OUString &rText, TextFrameIndex nStart, TextFrameIndex nEnd)
Returns the first possible break point in the current line.
Definition: txtfrm.cxx:1636
bool FormatEmpty()
Definition: porrst.cxx:384
bool IsPageFrame() const
Definition: frame.hxx:1178
void SetPaintDrop(const bool bNew)
Definition: itrpaint.hxx:55
double getLength(const B2DPolygon &rCandidate)
void SetPrep()
Definition: porlay.hxx:305
void FormatOnceMore(SwTextFormatter &rLine, SwTextFormatInfo &rInf)
Definition: frmform.cxx:1670
void SetWidow(const bool bNew)
Definition: txtfrm.hxx:249
virtual void Cut() override
Definition: wsfrm.cxx:1130
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:43
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:724
const SvxTabStop * GetTabStop(const SwTwips nSearchPos, SwTwips &nRight) const
#i24363# tab stops relative to indent
Definition: txttab.cxx:43
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
void SetPrepMustFit(const bool bNew)
Definition: porlay.hxx:309
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
SwLinePortion * MakeRestPortion(const SwLineLayout *pLine, TextFrameIndex nPos)
Definition: pormulti.cxx:2389
bool IsVertical() const
Definition: frame.hxx:973
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
virtual SwContentFrame * MakeFrame(SwFrame *) override
Virtual methods from ContentNode.
Definition: ndtxt.cxx:271
void Insert(SwLineLayout *pLine)
Definition: itrform2.cxx:124
#define SAL_WARN(area, stream)
SwTwips GetOffset() const
Definition: porlay.hxx:70
tools::Long GetDelta() const
Definition: porlay.hxx:290
bool IsTest() const
Definition: inftxt.hxx:588
bool IsFlyInCntBase() const
Definition: itrform2.hxx:210
SwTwips GetLineHeight() const
Definition: itrtxt.hxx:116
virtual void MakePos()
Definition: calcmove.cxx:526
void SetOffset(const SwTwips nNew)
Definition: porlay.hxx:71
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
bool HasVisibleNumberingOrBullet() const
Returns if the paragraph has a visible numbering or bullet.
Definition: ndtxt.cxx:4174
virtual const SwRedlineTable & GetRedlineTable() const =0
bool IsOnceMore() const
Definition: itrform2.hxx:201
sal_uInt16 GetDropLines() const
Definition: itrtxt.hxx:202
friend void ValidateText(SwFrame *pFrame)
Definition: frmform.cxx:72
bool IsFieldFollow() const
Definition: txtfrm.hxx:528
bool IsBodyFrame() const
Definition: frame.hxx:1206
void SetEmpty(const bool bNew)
Definition: txtfrm.hxx:251
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
void InvalidateRange_(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1696
void Chg(const Point &rNP, const Size &rNS)
Definition: swrect.hxx:166
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...
void SetRest(SwLinePortion *pNewRest)
Definition: inftxt.hxx:577
SwNumRule * GetNumRule(SwTextFormatColl &rTextFormatColl)
determines the list style, which directly set at the given paragraph style
Definition: fmtcol.cxx:76
void Height(tools::Long nNew)
Definition: swrect.hxx:193
void RemoveFootnote(TextFrameIndex nStart, TextFrameIndex nLen=TextFrameIndex(COMPLETE_STRING))
Footnote.
Definition: txtftn.cxx:407
TextFrameIndex & Len()
Definition: porlay.hxx:49
SwContentFrame * JoinFrame()
Definition: frmform.cxx:616
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
bool HasUnderscore() const
Definition: porlay.hxx:147
bool IsAvailable() const
Definition: txtcache.cxx:70
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
bool CalcOnceMore()
Definition: itrform2.cxx:2065
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: wsfrm.cxx:1027
void ChgThisLines()
Definition: txtfrm.cxx:3793
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
SwFrame * GetNext()
Definition: frame.hxx:676
bool HasFootnote() const
Definition: txtfrm.hxx:526