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