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
56namespace {
57
58class FormatLevel
59{
60 static sal_uInt16 s_nLevel;
61public:
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
70sal_uInt16 FormatLevel::s_nLevel = 0;
71
72void 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.
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.
119static 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
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 {
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 {
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()->GetNode().GetIndex())
353 {
355 if (GetMergedPara()
356 && pRedln->GetType() == RedlineType::Delete
357 && pRedln->GetPoint()->GetNode() != pRedln->GetMark()->GetNode())
358 {
359 pTextNode = pRedln->End()->GetNode().GetTextNode();
360 }
361 }
362 }
363}
364
365void 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
520css::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 }
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 );
677 pNext ? pNext->DynCastTextFrame() : nullptr,
678 this );
679 }
680 }
681#endif
682
683 pFoll->Cut();
684 SetFollow(pNxt);
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 );
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 }
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
884
885 if( 0 >= rRepaint.Width() )
886 rRepaint.Width(1);
887 }
888 bRet = true;
889 }
890 else if ( bPrepAdjust )
891 {
892 if ( HasFootnote() )
893 {
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 )
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.
1196bool 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 {
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 ...
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.
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 SwTextLineAccess aAccess( this );
1803 tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
1804
1805 if( aAccess.GetPara()->IsPrepMustFit() )
1806 {
1807 const SwTwips nLimit = aRectFnSet.GetPrtBottom(*GetUpper());
1808 const SwTwips nDiff = - aRectFnSet.BottomDist( getFrameArea(), nLimit );
1809 if( nDiff > 0 )
1810 Shrink( nDiff );
1811 }
1812
1813 nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
1814 const tools::Long nTop = aRectFnSet.GetTopMargin(*this);
1815
1816 if( nTop > nFrameHeight )
1817 {
1818 aRectFnSet.SetYMargins( *this, nFrameHeight, 0 );
1819 }
1820 else if( aRectFnSet.GetHeight(getFramePrintArea()) < 0 )
1821 {
1823 aRectFnSet.SetHeight( aPrt, 0 );
1824 }
1825
1826 return;
1827 }
1828
1829 const TextFrameIndex nStrLen(GetText().getLength());
1830 if ( nStrLen || !FormatEmpty() )
1831 {
1832
1833 SetEmpty( false );
1834 // In order to not get confused by nested Formats
1835 FormatLevel aLevel;
1836 if( 12 == FormatLevel::GetLevel() )
1837 return;
1838
1839 // We could be possibly not allowed to alter the format information
1840 if( IsLocked() )
1841 return;
1842
1843 // Attention: Format() could be triggered by GetFormatted()
1844 if( IsHiddenNow() )
1845 {
1846 tools::Long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea());
1847 if( nPrtHeight )
1848 {
1849 HideHidden();
1850 Shrink( nPrtHeight );
1851 }
1852 else
1853 {
1854 // Assure that objects anchored
1855 // at paragraph resp. at/as character inside paragraph
1856 // are hidden.
1858 }
1859 ChgThisLines();
1860 return;
1861 }
1862
1863 // We do not want to be interrupted during formatting
1864 TextFrameLockGuard aLock(this);
1865
1866 // this is to ensure that the similar code in SwTextFrame::Format_
1867 // finds the master formatted in case it's needed
1868 if (IsFollow() && IsFieldFollow())
1869 {
1870 SwTextFrame *pMaster = FindMaster();
1871 assert(pMaster);
1872 if (!pMaster->HasPara())
1873 {
1874 pMaster->GetFormatted();
1875 }
1876 if (!pMaster->HasPara())
1877 { // master could be locked because it's being formatted upstack
1878 SAL_WARN("sw", "SwTextFrame::Format: failed to format master!");
1879 }
1880 else
1881 {
1882 SwTextSizeInfo aInf( pMaster );
1883 SwTextIter aMasterLine( pMaster, &aInf );
1884 aMasterLine.Bottom();
1885 SetOffset(aMasterLine.GetEnd());
1886 }
1887 }
1888
1889 SwTextLineAccess aAccess( this );
1890 const bool bNew = !aAccess.IsAvailable();
1891 const bool bSetOffset =
1893
1894 if( CalcPreps() )
1895 ; // nothing
1896 // We return if already formatted, but if the TextFrame was just created
1897 // and does not have any format information
1898 else if( !bNew && !aAccess.GetPara()->GetReformat().Len() )
1899 {
1901 {
1902 aAccess.GetPara()->SetPrepAdjust();
1903 aAccess.GetPara()->SetPrep();
1904 CalcPreps();
1905 }
1906 SetWidow( false );
1907 }
1908 else if( bSetOffset && IsFollow() )
1909 {
1910 SwTextFrame *pMaster = FindMaster();
1911 OSL_ENSURE( pMaster, "SwTextFrame::Format: homeless follow" );
1912 if( pMaster )
1914 SwTwips nMaxY = aRectFnSet.GetPrtBottom(*GetUpper());
1915
1916 if( aRectFnSet.OverStep( getFrameArea(), nMaxY ) )
1917 {
1918 aRectFnSet.SetLimit( *this, nMaxY );
1919 }
1920 else if( aRectFnSet.BottomDist( getFrameArea(), nMaxY ) < 0 )
1921 {
1923 aRectFnSet.AddBottom( aFrm, -aRectFnSet.GetHeight(aFrm) );
1924 }
1925 }
1926 else
1927 {
1928 // bSetOffset here means that we have the "red arrow situation"
1929 if ( bSetOffset )
1931
1932 const bool bOrphan = IsWidow();
1933 const SwFootnoteBossFrame* pFootnoteBoss = HasFootnote() ? FindFootnoteBossFrame() : nullptr;
1934 SwTwips nFootnoteHeight = 0;
1935 if( pFootnoteBoss )
1936 {
1937 const SwFootnoteContFrame* pCont = pFootnoteBoss->FindFootnoteCont();
1938 nFootnoteHeight = pCont ? aRectFnSet.GetHeight(pCont->getFrameArea()) : 0;
1939 }
1940 do
1941 {
1942 Format_( pRenderContext, aAccess.GetPara() );
1943 if( pFootnoteBoss && nFootnoteHeight )
1944 {
1945 const SwFootnoteContFrame* pCont = pFootnoteBoss->FindFootnoteCont();
1946 SwTwips nNewHeight = pCont ? aRectFnSet.GetHeight(pCont->getFrameArea()) : 0;
1947 // If we lost some footnotes, we may have more space
1948 // for our main text, so we have to format again ...
1949 if( nNewHeight < nFootnoteHeight )
1950 nFootnoteHeight = nNewHeight;
1951 else
1952 break;
1953 }
1954 else
1955 break;
1956 } while ( pFootnoteBoss );
1957 if( bOrphan )
1958 {
1959 ValidateFrame();
1960 SetWidow( false );
1961 }
1962 }
1963 if( IsEmptyMaster() )
1964 {
1965 SwFrame* pPre = GetPrev();
1966 if( pPre &&
1967 // i#10826 It's the first, it cannot keep!
1968 pPre->GetIndPrev() &&
1969 pPre->GetAttrSet()->GetKeep().GetValue() )
1970 {
1971 pPre->InvalidatePos();
1972 }
1973 }
1974 }
1975
1976 ChgThisLines();
1977
1978 // the PrepMustFit should not survive a Format operation
1979 SwParaPortion *pPara = GetPara();
1980 if ( pPara )
1981 pPara->SetPrepMustFit( false );
1982
1984 CalcHeightOfLastLine(); // i#11860 - Adjust spacing implementation for
1985 // object positioning - Compatibility to MS Word
1986 // tdf#117982 -- Fix cell spacing hides content
1987 // Check if the cell's content has greater size than the row height
1989 || (getFramePrintArea().Height() <= 0)))
1990 {
1991 SAL_INFO("sw.core", "Warn: Cell content has greater size than cell height!");
1992 //get font size...
1993 SwTwips aTmpHeight = getFrameArea().Height();
1994 //...and push it into the text frame
1996 //if only bottom margin what we have:
1997 if (GetTopMargin() == 0)
1998 //set the frame to its original location
1999 aPrt.SetTopAndHeight(0, aTmpHeight);
2000 }
2001}
2002
2003// bForceQuickFormat is set if GetFormatted() has been called during the
2004// painting process. Actually I cannot imagine a situation which requires
2005// a full formatting of the paragraph during painting, on the other hand
2006// a full formatting can cause the invalidation of other layout frames,
2007// e.g., if there are footnotes in this paragraph, and invalid layout
2008// frames will not calculated during the painting. So I actually want to
2009// avoid a formatting during painting, but since I'm a coward, I'll only
2010// force the quick formatting in the situation of issue i29062.
2011bool SwTextFrame::FormatQuick( bool bForceQuickFormat )
2012{
2013 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
2014 "SwTextFrame::FormatQuick with swapped frame" );
2015
2016 if( IsEmpty() && FormatEmpty() )
2017 return true;
2018
2019 // We're very picky:
2020 if( HasPara() || IsWidow() || IsLocked()
2021 || !isFrameAreaSizeValid() ||
2023 return false;
2024
2025 SwTextLineAccess aAccess( this );
2026 SwParaPortion *pPara = aAccess.GetPara();
2027 if( !pPara )
2028 return false;
2029
2030 SwFrameSwapper aSwapper( this, true );
2031
2032 TextFrameLockGuard aLock(this);
2033 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this, false, true );
2034 if( 0 != aInf.MaxHyph() ) // Respect MaxHyphen!
2035 return false;
2036
2037 SwTextFormatter aLine( this, &aInf );
2038
2039 // DropCaps are too complicated ...
2040 if( aLine.GetDropFormat() )
2041 return false;
2042
2043 TextFrameIndex nStart = GetOffset();
2044 const TextFrameIndex nEnd = GetFollow()
2045 ? GetFollow()->GetOffset()
2046 : TextFrameIndex(aInf.GetText().getLength());
2047
2048 int nLoopProtection = 0;
2049 do
2050 {
2051 TextFrameIndex nNewStart = aLine.FormatLine(nStart);
2052 if (nNewStart == nStart)
2053 ++nLoopProtection;
2054 else
2055 nLoopProtection = 0;
2056 nStart = nNewStart;
2057 const bool bWillEndlessInsert = nLoopProtection > 250;
2058 SAL_WARN_IF(bWillEndlessInsert, "sw", "loop detection triggered");
2059 if ((!bWillEndlessInsert) // Check for special case: line is invisible,
2060 // like in too thin table cell: tdf#66141
2061 && (aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd)))
2062 aLine.Insert( new SwLineLayout() );
2063 } while( aLine.Next() );
2064
2065 // Last exit: the heights need to match
2066 Point aTopLeft( getFrameArea().Pos() );
2067 aTopLeft += getFramePrintArea().Pos();
2068 const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
2069 const SwTwips nOldHeight = aTopLeft.Y() + getFramePrintArea().Height();
2070
2071 if( !bForceQuickFormat && nNewHeight != nOldHeight && !IsUndersized() )
2072 {
2073 // Attention: This situation can occur due to FormatLevel==12. Don't panic!
2074 TextFrameIndex const nStrt = GetOffset();
2075 InvalidateRange_( SwCharRange( nStrt, nEnd - nStrt) );
2076 return false;
2077 }
2078
2079 if (m_pFollow && nStart != static_cast<SwTextFrame*>(m_pFollow)->GetOffset())
2080 return false; // can be caused by e.g. Orphans
2081
2082 // We made it!
2083
2084 // Set repaint
2085 pPara->GetRepaint().Pos( aTopLeft );
2086 pPara->GetRepaint().SSize( getFramePrintArea().SSize() );
2087
2088 // Delete reformat
2089 pPara->GetReformat() = SwCharRange();
2090 pPara->SetDelta(0);
2091
2092 return true;
2093}
2094
2095/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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...
virtual const SwRedlineTable & GetRedlineTable() const =0
bool GetValue() const
sal_uInt8 & GetMaxHyphens()
sal_Unicode & GetFill()
sal_Int32 & GetTabPos()
sal_Unicode & GetDecimal()
SvxTabAdjust & GetAdjustment()
const SvxFormatKeepItem & GetKeep(bool=true) const
Definition: frmatr.hxx:56
const SvxHyphenZoneItem & GetHyphenZone(bool=true) const
Definition: paratr.hxx:206
const SwRegisterItem & GetRegister(bool=true) const
Definition: paratr.hxx:198
TextFrameIndex & Len()
Definition: porlay.hxx:49
TextFrameIndex & Start()
Definition: porlay.hxx:45
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:58
virtual void Cut() override
Definition: wsfrm.cxx:1136
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: wsfrm.cxx:1033
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:737
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:765
static void ChangeFootnoteRef(const SwContentFrame *pOld, const SwTextFootnote *, SwContentFrame *pNew)
Definition: ftnfrm.cxx:1762
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1036
const SwRect & getFrameArea() const
Definition: frame.hxx:179
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
bool isFramePrintAreaValid() const
Definition: frame.hxx:168
bool isFrameAreaSizeValid() const
Definition: frame.hxx:167
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:92
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:928
Base class of the Writer layout elements.
Definition: frame.hxx:315
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1510
bool IsCellFrame() const
Definition: frame.hxx:1227
const SwBodyFrame * FindBodyFrame() const
Definition: frame.hxx:1121
SwFrame * GetIndPrev() const
Definition: frame.hxx:725
SwTwips Shrink(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1554
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1116
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1100
SwFrame * GetNext()
Definition: frame.hxx:677
bool IsPageFrame() const
Definition: frame.hxx:1179
bool IsColLocked() const
Definition: frame.hxx:887
bool IsColumnFrame() const
Definition: frame.hxx:1183
bool IsInFootnote() const
Definition: frame.hxx:950
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1799
void InvalidateObjs(const bool _bNoInvaOfAsCharAnchoredObjs=true)
Definition: fly.cxx:2399
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:565
bool IsInTab() const
Definition: frame.hxx:956
virtual void MakePos()
Definition: calcmove.cxx:526
bool IsRightToLeft() const
Definition: frame.hxx:988
bool IsInFly() const
Definition: frame.hxx:962
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:888
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame,...
Definition: findfrm.cxx:742
bool IsMoveable(const SwLayoutFrame *_pLayoutFrame=nullptr) const
determine, if frame is moveable in given environment
Definition: findfrm.cxx:1427
void InvalidatePos()
Definition: frame.hxx:1044
SwLayoutFrame * GetUpper()
Definition: frame.hxx:679
bool IsVertical() const
Definition: frame.hxx:974
SwRootFrame * getRootFrame()
Definition: frame.hxx:680
void SetCompletePaint() const
Definition: frame.hxx:995
bool IsFlyFrame() const
Definition: frame.hxx:1211
friend void ValidateText(SwFrame *pFrame)
Definition: frmform.cxx:72
SwFrame * GetPrev()
Definition: frame.hxx:678
SwFrame * FindColFrame()
Definition: findfrm.cxx:595
bool IsSctFrame() const
Definition: frame.hxx:1215
bool IsVertLR() const
Definition: frame.hxx:980
void InvalidateSize()
Definition: frame.hxx:1030
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:216
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1108
SwFrame * GetIndNext()
Definition: frame.hxx:728
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:471
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:388
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:43
bool IsBodyFrame() const
Definition: frame.hxx:1207
bool IsInSct() const
Definition: frame.hxx:968
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:232
const SwFrame * Lower() const
Definition: layfrm.hxx:101
const SvxTabStop * GetTabStop(const SwTwips nSearchPos, SwTwips &nRight) const
#i24363# tab stops relative to indent
Definition: txttab.cxx:43
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:79
bool IsRest() const
Definition: porlay.hxx:129
void FinishSpaceAdd()
Definition: porlay.hxx:186
SwLineLayout * GetNext()
Definition: porlay.hxx:159
void ResetFlags()
Definition: porlay.cxx:831
void FinishKanaComp()
Definition: porlay.hxx:201
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:239
bool IsMidHyph() const
Definition: porlay.hxx:125
SwTwips GetHangingMargin() const
Definition: porlay.hxx:176
bool IsClipping() const
Definition: porlay.hxx:154
bool HasUnderscore() const
Definition: porlay.hxx:147
bool IsEndHyph() const
Definition: porlay.hxx:123
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:52
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
void Truncate()
Definition: porlin.hxx:214
SwTwips & GetAscent()
Definition: porlin.hxx:80
const IDocumentRedlineAccess & getIDocumentRedlineAccess() const
Provides access to the document redline interface.
Definition: node.cxx:2155
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
SwNodeOffset GetIndex() const
Definition: node.hxx:312
const SwPosition * GetMark() const
Definition: pam.hxx:263
const SwPosition * End() const
Definition: pam.hxx:271
const SwPosition * GetPoint() const
Definition: pam.hxx:261
A page of the document layout.
Definition: pagefrm.hxx:58
void ValidateContent() const
Definition: pagefrm.hxx:417
bool IsInvalidContent() const
Definition: pagefrm.hxx:235
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:251
bool IsMargin() const
Definition: porlay.hxx:321
bool IsPrepMustFit() const
Definition: porlay.hxx:310
bool IsPrepWidows() const
Definition: porlay.hxx:308
bool IsPrepAdjust() const
Definition: porlay.hxx:312
bool IsPrep() const
Definition: porlay.hxx:306
SwCharRange & GetReformat()
Definition: porlay.hxx:287
void FormatReset()
Definition: porlay.hxx:337
void SetDelta(tools::Long nDelta)
Definition: porlay.hxx:289
void SetPrepAdjust()
Definition: porlay.hxx:311
void SetPrep()
Definition: porlay.hxx:305
bool IsFollowField() const
Definition: porlay.hxx:314
void SetPrepMustFit(const bool bNew)
Definition: porlay.hxx:309
SwRepaint & GetRepaint()
Definition: porlay.hxx:285
tools::Long GetDelta() const
Definition: porlay.hxx:290
SwTwips Width() const
Definition: possiz.hxx:51
void MaybeNotifyRedlinePositionModification(tools::Long nTop)
Definition: docredln.cxx:1201
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1940
bool IsVert() const
Definition: frame.hxx:1367
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1382
tools::Long YInc(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1425
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1403
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1381
void SetYMargins(SwFrame &rFrame, tools::Long nTop, tools::Long nBottom) const
Definition: frame.hxx:1408
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1391
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1377
void SetLimit(SwFrame &rFrame, tools::Long nNew) const
Definition: frame.hxx:1417
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1394
bool OverStep(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1418
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1423
tools::Long GetPrtTop(const SwFrame &rFrame) const
Definition: frame.hxx:1409
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1378
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1414
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1410
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Chg(const Point &rNP, const Size &rNS)
Definition: swrect.hxx:166
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool HasArea() const
Definition: swrect.hxx:300
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void SetTopAndHeight(tools::Long nTop, tools::Long nNew)
Definition: swrect.cxx:156
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
void Pos(const Point &rNew)
Definition: swrect.hxx:171
void SSize(const Size &rNew)
Definition: swrect.hxx:180
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:124
void AddWidth(const tools::Long nAdd)
Definition: swrect.cxx:123
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
size_type size() const
Definition: docary.hxx:267
vector_type::size_type size_type
Definition: docary.hxx:222
void SetRightOfst(const SwTwips nNew)
Definition: porlay.hxx:73
SwTwips GetOffset() const
Definition: porlay.hxx:70
SwTwips GetRightOfst() const
Definition: porlay.hxx:72
void SetOffset(const SwTwips nNew)
Definition: porlay.hxx:71
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:391
void ColUnlock()
Definition: sectfrm.hxx:100
void SimpleFormat()
Definition: sectfrm.cxx:1173
void ColLock()
Definition: sectfrm.hxx:99
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:173
size_t size() const
Definition: sortedobjs.cxx:43
void CalcDropRepaint()
Definition: itradj.cxx:828
void CalcDropAdjust()
Definition: itradj.cxx:745
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
SwTextAttr subclass for footnotes and endnotes.
Definition: txtftn.hxx:34
void CtorInitTextFormatInfo(OutputDevice *pRenderContext, SwTextFrame *pFrame, const bool bInterHyph=false, const bool bQuick=false, const bool bTst=false)
Definition: inftxt.cxx:1448
void SetRest(SwLinePortion *pNewRest)
Definition: inftxt.hxx:580
bool IsTest() const
Definition: inftxt.hxx:591
bool IsShift() const
Definition: inftxt.hxx:583
sal_uInt8 & MaxHyph()
Definition: inftxt.hxx:557
SwLinePortion * GetRest()
Definition: inftxt.hxx:579
bool IsNewLine() const
Definition: inftxt.hxx:581
TextFrameIndex GetUnderScorePos() const
Definition: inftxt.hxx:644
bool IsStop() const
Definition: inftxt.hxx:577
bool IsFlyInCntBase() const
Definition: itrform2.hxx:210
void SetUnclipped(bool bNew)
Definition: itrform2.hxx:208
bool IsOnceMore() const
Definition: itrform2.hxx:201
bool CalcOnceMore()
Definition: itrform2.cxx:2262
const sal_uInt8 & CntMidHyph() const
Definition: itrform2.hxx:220
void InitCntHyph()
Definition: itrform2.hxx:218
const sal_uInt8 & CntEndHyph() const
Definition: itrform2.hxx:219
void SetOnceMore(bool bNew)
Definition: itrform2.hxx:202
void MakeDummyLine()
This function creates a Line that reaches to the other Page Margin.
Definition: txtftn.cxx:1276
void SetTruncLines(bool bNew)
Definition: itrform2.hxx:205
void CalcUnclipped(SwTwips &rTop, SwTwips &rBottom)
Definition: itrform2.cxx:2363
void CalcDropHeight(const sal_uInt16 nLines)
Definition: txtdrop.cxx:484
void CtorInitTextFormatter(SwTextFrame *pFrame, SwTextFormatInfo *pInf)
Definition: itrform2.cxx:93
bool IsStop() const
Definition: itrform2.hxx:174
bool IsNewLine() const
Definition: itrform2.hxx:177
const SwFormatDrop * GetDropFormat() const
Definition: itrform2.hxx:196
TextFrameIndex FormatQuoVadis(TextFrameIndex nStart)
Definition: txtftn.cxx:1072
SwLinePortion * MakeRestPortion(const SwLineLayout *pLine, TextFrameIndex nPos)
Definition: pormulti.cxx:2397
TextFrameIndex FormatLine(TextFrameIndex nStart)
Definition: itrform2.cxx:1856
bool IsUnclipped() const
Definition: itrform2.hxx:207
SwTwips CalcBottomLine() const
Definition: itrform2.cxx:2275
SwTextFormatInfo & GetInfo()
Definition: itrform2.hxx:213
void Insert(SwLineLayout *pLine)
Definition: itrform2.cxx:129
bool IsBreakNow(SwTextMargin &rLine)
Definition: widorp.cxx:218
void SetRstHeight(const SwTextMargin &rLine)
Definition: widorp.cxx:256
void SetKeep(const bool bNew)
Definition: widorp.hxx:40
bool IsKeepAlways() const
Definition: widorp.hxx:38
bool IsInside(SwTextMargin const &rLine) const
BP 18.6.93: Widows.
Definition: widorp.cxx:102
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
void FormatOnceMore(SwTextFormatter &rLine, SwTextFormatInfo &rInf)
Definition: frmform.cxx:1670
void Format_(vcl::RenderContext *pRenderContext, SwParaPortion *pPara)
Definition: frmform.cxx:1732
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3396
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout.
Definition: txtfrm.cxx:580
bool CalcPrepFootnoteAdjust()
Definition: txtftn.cxx:139
bool FollowFormatAllowed() const
Definition: txtfrm.hxx:749
void SetOffset(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:871
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:861
void CalcFootnoteFlag(TextFrameIndex nStop=TextFrameIndex(COMPLETE_STRING))
Does the Frame have a local footnote (in this Frame or Follow)?
Definition: txtftn.cxx:104
void HideAndShowObjects()
Hides respectively shows objects, which are anchored at paragraph, at/as a character of the paragraph...
Definition: txtfrm.cxx:1549
void ValidateFrame()
Definition: frmform.cxx:83
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:444
bool HasPara() const
Definition: txtfrm.hxx:825
void FormatAdjust(SwTextFormatter &rLine, WidowsAndOrphans &rFrameBreak, TextFrameIndex nStrLen, const bool bDummy)
Definition: frmform.cxx:1006
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:683
bool FormatQuick(bool bForceQuickFormat)
Definition: frmform.cxx:2011
bool IsWidow() const
Definition: txtfrm.hxx:525
void RemoveFootnote(TextFrameIndex nStart, TextFrameIndex nLen=TextFrameIndex(COMPLETE_STRING))
Footnote.
Definition: txtftn.cxx:408
bool IsSwapped() const
Definition: txtfrm.hxx:541
void HideHidden()
Removes Textfrm's attachments, when it's hidden.
Definition: txtfrm.cxx:1443
void CalcBaseOfstForFly()
Definition: txtfrm.cxx:4024
void SetFootnote(const bool bNew)
Will be moved soon.
Definition: txtfrm.hxx:605
bool CalcFollow(TextFrameIndex nTextOfst)
Definition: frmform.cxx:174
bool IsEmptyMaster() const
If there's a Follow and we don't contain text ourselves.
Definition: txtfrm.hxx:452
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
Definition: frmform.cxx:1791
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:456
bool FormatLine(SwTextFormatter &rLine, const bool bPrev)
Definition: frmform.cxx:1196
void AdjustFrame(const SwTwips nChgHeight, bool bHasToFit=false)
Definition: frmform.cxx:365
bool HasFootnote() const
Definition: txtfrm.hxx:528
SwContentFrame * JoinFrame()
Definition: frmform.cxx:616
void SetWidow(const bool bNew)
Definition: txtfrm.hxx:251
void ResetPreps()
Definition: txtfrm.cxx:1351
void CalcHeightOfLastLine(const bool _bUseFont=false)
method to determine height of last line, needed for proportional line spacing
Definition: txtfrm.cxx:3581
void CalcAdditionalFirstLineOffset()
Simulate format for a list item paragraph, whose list level attributes are in LABEL_ALIGNMENT mode,...
Definition: txtfrm.cxx:3495
SwTwips GetParHeight() const
Returns the sum of line height in pLine.
Definition: txtfrm.cxx:3356
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1252
bool IsFieldFollow() const
Definition: txtfrm.hxx:530
void AllowFollowFormat()
Definition: txtfrm.hxx:754
virtual void MakePos() override
Definition: frmform.cxx:340
bool GetDropRect_(SwRect &rRect) const
Definition: frmform.cxx:149
bool IsLocked() const
Definition: txtfrm.hxx:523
void InvalidateRange_(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1693
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout.
Definition: txtfrm.cxx:473
bool CalcPreps()
Definition: frmform.cxx:783
void SetFieldFollow(const bool bNew)
Definition: txtfrm.hxx:254
static TextFrameIndex FindBrk(std::u16string_view aText, TextFrameIndex nStart, TextFrameIndex nEnd)
Returns the first possible break point in the current line.
Definition: txtfrm.cxx:1633
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1360
void SetJustWidow(const bool bNew)
Definition: txtfrm.hxx:252
void ValidateBodyFrame()
Definition: frmform.cxx:139
void ChgThisLines()
Definition: txtfrm.cxx:3832
void ChangeOffset(SwTextFrame *pFrame, TextFrameIndex nNew)
Definition: frmform.cxx:998
void AdjustFollow_(SwTextFormatter &rLine, TextFrameIndex nOffset, TextFrameIndex nStrEnd, const sal_uInt8 nMode)
Definition: frmform.cxx:561
void ForbidFollowFormat()
Definition: txtfrm.hxx:759
void MoveFlyInCnt(SwTextFrame *pNew, TextFrameIndex nStart, TextFrameIndex nEnd)
Rewires FlyInContentFrame, if nEnd > Index >= nStart.
Definition: porfly.cxx:150
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:463
void SetOffset_(TextFrameIndex nNewOfst)
Definition: frmform.cxx:766
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!...
Definition: txtfrm.cxx:2748
void ManipOfst(TextFrameIndex const nNewOfst)
Definition: txtfrm.hxx:447
css::uno::Sequence< css::style::TabStop > GetTabStopInfo(SwTwips CurrentPos) override
Definition: frmform.cxx:520
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:420
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1293
void SetRepaint() const
Definition: txtfrm.hxx:877
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1303
bool FormatEmpty()
Definition: porrst.cxx:406
void SplitFrame(TextFrameIndex nTextPos)
Methods to manage the FollowFrame.
Definition: frmform.cxx:689
TextFrameIndex mnOffset
Definition: txtfrm.hxx:204
void SetEmpty(const bool bNew)
Definition: txtfrm.hxx:253
bool IsEmpty() const
Definition: txtfrm.hxx:527
SwParaPortion * GetParaPortion()
Definition: inftxt.hxx:121
TextFrameIndex GetLength() const
Definition: itrtxt.hxx:86
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
SwTwips Y() const
Definition: itrtxt.hxx:90
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
void TruncLines(bool bNoteFollow=false)
Definition: itrtxt.cxx:365
void Bottom()
Definition: itrtxt.cxx:186
void Top()
Definition: itrtxt.hxx:99
SwTwips GetLineHeight() const
Definition: itrtxt.hxx:116
const SwLineLayout * Next()
Definition: itrtxt.cxx:108
SwTwips GetFirstPos() const
Definition: itrtxt.hxx:129
void CharToLine(TextFrameIndex)
Definition: itrtxt.cxx:194
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
const SwLineLayout * Prev()
Definition: itrtxt.cxx:90
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:87
const SwLineInfo & GetLineInfo() const
Definition: itrtxt.hxx:128
const SwLineLayout * GetPrev()
Definition: itrtxt.cxx:83
bool IsAvailable() const
Definition: txtcache.cxx:70
SwParaPortion * GetPara()
Definition: txtcache.cxx:50
sal_uInt16 GetDropLeft() const
Definition: itrtxt.hxx:204
sal_uInt16 GetDropLines() const
Definition: itrtxt.hxx:202
Point GetTopLeft() const
Definition: itrtxt.hxx:186
SwTwips GetLeftMargin() const
Definition: itrtxt.hxx:329
void SetDropLines(const sal_uInt16 nNew)
Definition: itrtxt.hxx:203
sal_uInt16 GetDropHeight() const
Definition: itrtxt.hxx:205
SvxAdjust GetAdjust() const
Definition: itrtxt.hxx:190
SwTwips GetLineStart() const
Definition: itrcrsr.cxx:381
void Right(const SwTwips nNew)
Definition: itrtxt.hxx:157
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:111
virtual SwContentFrame * MakeFrame(SwFrame *) override
Virtual methods from ContentNode.
Definition: ndtxt.cxx:285
bool HasVisibleNumberingOrBullet() const
Returns if the paragraph has a visible numbering or bullet.
Definition: ndtxt.cxx:4276
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2919
bool IsPaintDrop() const
Definition: itrpaint.hxx:56
void SetPaintDrop(const bool bNew)
Definition: itrpaint.hxx:55
sal_Unicode GetChar(TextFrameIndex const nPos) const
Definition: inftxt.hxx:241
const OUString & GetText() const
Definition: inftxt.hxx:240
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:273
bool IsParagraph(bool bHard=false) const
Definition: viewopt.hxx:313
bool IsLineBreak(bool bHard=false) const
Definition: viewopt.hxx:333
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:347
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:434
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2160
void InvalidateAccessibleParaFlowRelation(const SwTextFrame *_pFromTextFrame, const SwTextFrame *_pToTextFrame)
invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs
Definition: viewsh.cxx:2592
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
bool IsBreakNowWidAndOrp(SwTextMargin &rLine)
Definition: widorp.hxx:69
void ClrOrphLines()
Definition: widorp.hxx:63
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:91
static void ValidateBodyFrame_(SwFrame *pFrame)
Definition: frmform.cxx:119
#define SLOPPY_TWIPS
Definition: frmform.cxx:54
void ValidateText(SwFrame *pFrame)
Definition: frmform.cxx:72
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
const long LONG_MAX
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
SwNumRule * GetNumRule(SwTextFormatColl &rTextFormatColl)
determines the list style, which directly set at the given paragraph style
Definition: fmtcol.cxx:74
double getLength(const B2DPolygon &rCandidate)
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
const SwTwips WIDOW_MAGIC
Definition: txtfrm.hxx:1028
long Long
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
#define Y
SwNode & GetNode() const
Definition: pam.hxx:80
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
tools::Long SwTwips
Definition: swtypes.hxx:51
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
Left
Right
unsigned char sal_uInt8