LibreOffice Module sw (master) 1
txtfrm.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 <hintids.hxx>
23#include <hints.hxx>
24#include <svl/ctloptions.hxx>
25#include <editeng/lspcitem.hxx>
26#include <editeng/lrspitem.hxx>
27#include <editeng/brushitem.hxx>
28#include <editeng/pgrditem.hxx>
30#include <swmodule.hxx>
31#include <SwSmartTagMgr.hxx>
32#include <doc.hxx>
36#include <rootfrm.hxx>
37#include <pagefrm.hxx>
38#include <viewsh.hxx>
39#include <pam.hxx>
40#include <ndtxt.hxx>
41#include <paratr.hxx>
42#include <viewopt.hxx>
43#include <flyfrm.hxx>
44#include <tabfrm.hxx>
45#include <frmatr.hxx>
46#include <frmtool.hxx>
47#include <tgrditem.hxx>
48#include <dbg_lay.hxx>
49#include <fmtfld.hxx>
50#include <fmtftn.hxx>
51#include <txtfld.hxx>
52#include <txtftn.hxx>
53#include <ftninfo.hxx>
54#include <fmtline.hxx>
55#include <txtfrm.hxx>
56#include <notxtfrm.hxx>
57#include <sectfrm.hxx>
58#include "itrform2.hxx"
59#include "widorp.hxx"
60#include "txtcache.hxx"
61#include <fntcache.hxx>
62#include <SwGrammarMarkUp.hxx>
63#include <lineinfo.hxx>
64#include <SwPortionHandler.hxx>
65#include <dcontact.hxx>
66#include <sortedobjs.hxx>
67#include <txtflcnt.hxx>
68#include <fmtflcnt.hxx>
69#include <fmtcntnt.hxx>
70#include <numrule.hxx>
71#include <IGrammarContact.hxx>
72#include <calbck.hxx>
73#include <ftnidx.hxx>
74#include <ftnfrm.hxx>
75
76#include <wrtsh.hxx>
77#include <view.hxx>
78#include <edtwin.hxx>
80
81namespace sw {
82
84 : m_pMerged(rFrame.GetMergedPara())
85 , m_pNode(m_pMerged ? nullptr : rFrame.GetTextNodeFirst())
86 , m_CurrentExtent(0)
87 , m_CurrentHint(0)
88 {
89 }
90
92 {
93 if (m_pMerged)
94 {
95 while (m_CurrentExtent < m_pMerged->extents.size())
96 {
98 if (SwpHints const*const pHints = rExtent.pNode->GetpSwpHints())
99 {
100 while (m_CurrentHint < pHints->Count())
101 {
102 SwTextAttr *const pHint(pHints->Get(m_CurrentHint));
103 if (rExtent.nEnd < pHint->GetStart()
104 // <= if it has no end or isn't empty
105 || (rExtent.nEnd == pHint->GetStart()
106 && (!pHint->GetEnd()
107 || *pHint->GetEnd() != pHint->GetStart())))
108 {
109 break;
110 }
112 if (rExtent.nStart <= pHint->GetStart())
113 {
114 if (ppNode)
115 {
116 *ppNode = rExtent.pNode;
117 }
118 return pHint;
119 }
120 }
121 }
123 if (m_CurrentExtent < m_pMerged->extents.size() &&
124 rExtent.pNode != m_pMerged->extents[m_CurrentExtent].pNode)
125 {
126 m_CurrentHint = 0; // reset
127 }
128 }
129 return nullptr;
130 }
131 else
132 {
133 SwpHints const*const pHints(m_pNode->GetpSwpHints());
134 if (pHints)
135 {
136 if (m_CurrentHint < pHints->Count())
137 {
138 SwTextAttr const*const pHint(pHints->Get(m_CurrentHint));
140 if (ppNode)
141 {
142 *ppNode = m_pNode;
143 }
144 return pHint;
145 }
146 }
147 return nullptr;
148 }
149 }
150
152 : m_pNode(rFrame.GetMergedPara() ? nullptr : rFrame.GetTextNodeFirst())
153 , m_CurrentHint(0)
154 {
155 if (!m_pNode)
156 {
157 MergedAttrIterReverse iter(rFrame);
158 SwTextNode const* pNode(nullptr);
159 while (SwTextAttr const* pHint = iter.PrevAttr(&pNode))
160 {
161 m_Hints.emplace_back(pNode, pHint);
162 }
163 }
164 }
165
167 {
168 if (m_pNode)
169 {
170 SwpHints const*const pHints(m_pNode->GetpSwpHints());
171 if (pHints)
172 {
173 if (m_CurrentHint < pHints->Count())
174 {
175 SwTextAttr const*const pHint(
178 rpNode = m_pNode;
179 return pHint;
180 }
181 }
182 return nullptr;
183 }
184 else
185 {
186 if (m_CurrentHint < m_Hints.size())
187 {
188 auto const ret = m_Hints[m_Hints.size() - m_CurrentHint - 1];
190 rpNode = ret.first;
191 return ret.second;
192 }
193 return nullptr;
194 }
195 }
196
198 {
199 assert(0 < m_CurrentHint); // should only rewind as far as 0
201 }
202
204 : MergedAttrIterBase(rFrame)
205 {
206 if (m_pMerged)
207 {
209 SwpHints const*const pHints(0 < m_CurrentExtent
210 ? m_pMerged->extents[m_CurrentExtent-1].pNode->GetpSwpHints()
211 : nullptr);
212 if (pHints)
213 {
214 pHints->SortIfNeedBe();
215 m_CurrentHint = pHints->Count();
216 }
217 }
218 else
219 {
220 if (SwpHints const*const pHints = m_pNode->GetpSwpHints())
221 {
222 pHints->SortIfNeedBe();
223 m_CurrentHint = pHints->Count();
224 }
225 }
226 }
227
229 {
230 if (m_pMerged)
231 {
232 while (0 < m_CurrentExtent)
233 {
234 sw::Extent const& rExtent(m_pMerged->extents[m_CurrentExtent-1]);
235 if (SwpHints const*const pHints = rExtent.pNode->GetpSwpHints())
236 {
237 while (0 < m_CurrentHint)
238 {
239 SwTextAttr *const pHint(
240 pHints->GetSortedByEnd(m_CurrentHint - 1));
241 if (pHint->GetAnyEnd() < rExtent.nStart
242 // <= if it has end and isn't empty
243 || (pHint->GetEnd()
244 && *pHint->GetEnd() != pHint->GetStart()
245 && *pHint->GetEnd() == rExtent.nStart))
246 {
247 break;
248 }
250 if (pHint->GetAnyEnd() <= rExtent.nEnd)
251 {
252 if (ppNode)
253 {
254 *ppNode = rExtent.pNode;
255 }
256 return pHint;
257 }
258 }
259 }
261 if (0 < m_CurrentExtent &&
262 rExtent.pNode != m_pMerged->extents[m_CurrentExtent-1].pNode)
263 {
264 SwpHints const*const pHints(
265 m_pMerged->extents[m_CurrentExtent-1].pNode->GetpSwpHints());
266 m_CurrentHint = pHints ? pHints->Count() : 0; // reset
267 if (pHints)
268 pHints->SortIfNeedBe();
269 }
270 }
271 return nullptr;
272 }
273 else
274 {
275 SwpHints const*const pHints(m_pNode->GetpSwpHints());
276 if (pHints && 0 < m_CurrentHint)
277 {
278 SwTextAttr const*const pHint(pHints->GetSortedByEnd(m_CurrentHint - 1));
280 if (ppNode)
281 {
282 *ppNode = m_pNode;
283 }
284 return pHint;
285 }
286 return nullptr;
287 }
288 }
289
290 bool FrameContainsNode(SwContentFrame const& rFrame, SwNodeOffset const nNodeIndex)
291 {
292 if (rFrame.IsTextFrame())
293 {
294 SwTextFrame const& rTextFrame(static_cast<SwTextFrame const&>(rFrame));
295 if (sw::MergedPara const*const pMerged = rTextFrame.GetMergedPara())
296 {
297 SwNodeOffset const nFirst(pMerged->pFirstNode->GetIndex());
298 SwNodeOffset const nLast(pMerged->pLastNode->GetIndex());
299 return (nFirst <= nNodeIndex && nNodeIndex <= nLast);
300 }
301 else
302 {
303 return rTextFrame.GetTextNodeFirst()->GetIndex() == nNodeIndex;
304 }
305 }
306 else
307 {
308 assert(rFrame.IsNoTextFrame());
309 return static_cast<SwNoTextFrame const&>(rFrame).GetNode()->GetIndex() == nNodeIndex;
310 }
311 }
312
313 bool IsParaPropsNode(SwRootFrame const& rLayout, SwTextNode const& rNode)
314 {
315 if (rLayout.HasMergedParas())
316 {
317 if (SwTextFrame const*const pFrame = static_cast<SwTextFrame*>(rNode.getLayoutFrame(&rLayout)))
318 {
319 sw::MergedPara const*const pMerged(pFrame->GetMergedPara());
320 if (pMerged && pMerged->pParaPropsNode != &rNode)
321 {
322 return false;
323 }
324 }
325 }
326 return true;
327 }
328
329 SwTextNode *
330 GetParaPropsNode(SwRootFrame const& rLayout, SwNode const& rPos)
331 {
332 const SwTextNode *const pTextNode(rPos.GetTextNode());
333 if (pTextNode && !sw::IsParaPropsNode(rLayout, *pTextNode))
334 {
335 return static_cast<SwTextFrame*>(pTextNode->getLayoutFrame(&rLayout))->GetMergedPara()->pParaPropsNode;
336 }
337 else
338 {
339 return const_cast<SwTextNode*>(pTextNode);
340 }
341 }
342
344 GetParaPropsPos(SwRootFrame const& rLayout, SwPosition const& rPos)
345 {
346 SwPosition pos(rPos);
347 SwTextNode const*const pNode(pos.GetNode().GetTextNode());
348 if (pNode)
349 pos.Assign( *sw::GetParaPropsNode(rLayout, *pNode) );
350 return pos;
351 }
352
353 std::pair<SwTextNode *, SwTextNode *>
354 GetFirstAndLastNode(SwRootFrame const& rLayout, SwNode const& rPos)
355 {
356 SwTextNode *const pTextNode(const_cast<SwTextNode*>(rPos.GetTextNode()));
357 if (pTextNode && rLayout.HasMergedParas())
358 {
359 if (SwTextFrame const*const pFrame = static_cast<SwTextFrame*>(pTextNode->getLayoutFrame(&rLayout)))
360 {
361 if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
362 {
363 return std::make_pair(pMerged->pFirstNode, const_cast<SwTextNode*>(pMerged->pLastNode));
364 }
365 }
366 }
367 return std::make_pair(pTextNode, pTextNode);
368 }
369
371 SwTextNode const& rNode, SwRootFrame const*const pLayout)
372 {
373 rNode.SwContentNode::GetAttr(rFormatSet);
374 if (pLayout && pLayout->HasMergedParas())
375 {
376 auto pFrame = static_cast<SwTextFrame*>(rNode.getLayoutFrame(pLayout));
377 if (sw::MergedPara const*const pMerged = pFrame ? pFrame->GetMergedPara() : nullptr)
378 {
379 if (pMerged->pFirstNode != &rNode)
380 {
381 rFormatSet.ClearItem(RES_PAGEDESC);
382 rFormatSet.ClearItem(RES_BREAK);
383 static_assert(RES_PAGEDESC + 1 == sal_uInt16(RES_BREAK),
384 "first-node items must be adjacent");
386 pMerged->pFirstNode->SwContentNode::GetAttr(firstSet);
387 rFormatSet.Put(firstSet);
388
389 }
390 if (pMerged->pParaPropsNode != &rNode)
391 {
392 for (sal_uInt16 i = RES_PARATR_BEGIN; i != RES_FRMATR_END; ++i)
393 {
394 if (i != RES_PAGEDESC && i != RES_BREAK)
395 {
396 rFormatSet.ClearItem(i);
397 }
398 }
399 for (sal_uInt16 i = XATTR_FILL_FIRST; i <= XATTR_FILL_LAST; ++i)
400 {
401 rFormatSet.ClearItem(i);
402 }
406 propsSet(*rFormatSet.GetPool());
407 pMerged->pParaPropsNode->SwContentNode::GetAttr(propsSet);
408 rFormatSet.Put(propsSet);
409 return *pMerged->pParaPropsNode;
410 }
411 // keep all the CHRATR/UNKNOWNATR anyway...
412 }
413 }
414 return rNode;
415 }
416
417} // namespace sw
418
421{
422 {
424
425 if ( ! mbIsSwapped )
426 {
427 const tools::Long nPrtOfstX = aPrt.Pos().X();
428 aPrt.Pos().setX( aPrt.Pos().Y() );
429
430 if( IsVertLR() )
431 {
432 aPrt.Pos().setY( nPrtOfstX );
433 }
434 else
435 {
436 aPrt.Pos().setY( getFrameArea().Width() - ( nPrtOfstX + aPrt.Width() ) );
437 }
438 }
439 else
440 {
441 const tools::Long nPrtOfstY = aPrt.Pos().Y();
442 aPrt.Pos().setY( aPrt.Pos().X() );
443
444 if( IsVertLR() )
445 {
446 aPrt.Pos().setX( nPrtOfstY );
447 }
448 else
449 {
450 aPrt.Pos().setX( getFrameArea().Height() - ( nPrtOfstY + aPrt.Height() ) );
451 }
452 }
453
454 const tools::Long nPrtWidth = aPrt.Width();
455 aPrt.Width( aPrt.Height() );
456 aPrt.Height( nPrtWidth );
457 }
458
459 {
460 const tools::Long nFrameWidth = getFrameArea().Width();
462 aFrm.Width( aFrm.Height() );
463 aFrm.Height( nFrameWidth );
464 }
465
467}
468
474{
475 // calc offset inside frame
476 tools::Long nOfstX, nOfstY;
477 if ( IsVertLR() )
478 {
479 if (IsVertLRBT())
480 {
481 // X and Y offsets here mean the position of the point that will be the top left corner
482 // after the switch.
483 nOfstX = rRect.Left() + rRect.Width() - getFrameArea().Left();
484 nOfstY = rRect.Top() - getFrameArea().Top();
485 }
486 else
487 {
488 nOfstX = rRect.Left() - getFrameArea().Left();
489 nOfstY = rRect.Top() - getFrameArea().Top();
490 }
491 }
492 else
493 {
494 nOfstX = rRect.Left() - getFrameArea().Left();
495 nOfstY = rRect.Top() + rRect.Height() - getFrameArea().Top();
496 }
497
498 const tools::Long nWidth = rRect.Width();
499 const tools::Long nHeight = rRect.Height();
500
501 if ( IsVertLR() )
502 {
503 rRect.Left(getFrameArea().Left() + nOfstY);
504 }
505 else
506 {
507 if ( mbIsSwapped )
508 rRect.Left( getFrameArea().Left() + getFrameArea().Height() - nOfstY );
509 else
510 // frame is rotated
511 rRect.Left( getFrameArea().Left() + getFrameArea().Width() - nOfstY );
512 }
513
514 if (IsVertLRBT())
515 {
516 if (mbIsSwapped)
517 rRect.Top(getFrameArea().Top() + getFrameArea().Width() - nOfstX);
518 else
519 rRect.Top(getFrameArea().Top() + getFrameArea().Height() - nOfstX);
520 }
521 else
522 rRect.Top(getFrameArea().Top() + nOfstX);
523 rRect.Width( nHeight );
524 rRect.Height( nWidth );
525}
526
532{
533 if (IsVertLRBT())
534 {
535 // The horizontal origo is the top left corner, the LRBT origo is the
536 // bottom left corner. Finally x and y has to be swapped.
537 SAL_WARN_IF(!mbIsSwapped, "sw.core",
538 "SwTextFrame::SwitchHorizontalToVertical, IsVertLRBT, not swapped");
539 Point aPoint(rPoint);
540 rPoint.setX(getFrameArea().Left() + (aPoint.Y() - getFrameArea().Top()));
541 // This would be bottom - x delta, but bottom is top + height, finally
542 // width (and not height), as it's swapped.
543 rPoint.setY(getFrameArea().Top() + getFrameArea().Width()
544 - (aPoint.X() - getFrameArea().Left()));
545 return;
546 }
547
548 // calc offset inside frame
549 const tools::Long nOfstX = rPoint.X() - getFrameArea().Left();
550 const tools::Long nOfstY = rPoint.Y() - getFrameArea().Top();
551 if ( IsVertLR() )
552 rPoint.setX( getFrameArea().Left() + nOfstY );
553 else
554 {
555 if ( mbIsSwapped )
556 rPoint.setX( getFrameArea().Left() + getFrameArea().Height() - nOfstY );
557 else
558 // calc rotated coords
559 rPoint.setX( getFrameArea().Left() + getFrameArea().Width() - nOfstY );
560 }
561
562 rPoint.setY( getFrameArea().Top() + nOfstX );
563}
564
570{
571 Point aTmp( 0, nLimit );
573 return aTmp.X();
574}
575
581{
582 tools::Long nOfstX;
583
584 // calc offset inside frame
585 if ( IsVertLR() )
586 nOfstX = rRect.Left() - getFrameArea().Left();
587 else
588 {
589 if ( mbIsSwapped )
590 nOfstX = getFrameArea().Left() + getFrameArea().Height() - ( rRect.Left() + rRect.Width() );
591 else
592 nOfstX = getFrameArea().Left() + getFrameArea().Width() - ( rRect.Left() + rRect.Width() );
593 }
594
595 tools::Long nOfstY;
596 if (IsVertLRBT())
597 {
598 // Note that mbIsSwapped only affects the frame area, not rRect, so rRect.Height() is used
599 // here unconditionally.
600 if (mbIsSwapped)
601 nOfstY = getFrameArea().Top() + getFrameArea().Width() - (rRect.Top() + rRect.Height());
602 else
603 nOfstY = getFrameArea().Top() + getFrameArea().Height() - (rRect.Top() + rRect.Height());
604 }
605 else
606 nOfstY = rRect.Top() - getFrameArea().Top();
607 const tools::Long nWidth = rRect.Height();
608 const tools::Long nHeight = rRect.Width();
609
610 // calc rotated coords
611 rRect.Left( getFrameArea().Left() + nOfstY );
612 rRect.Top( getFrameArea().Top() + nOfstX );
613 rRect.Width( nWidth );
614 rRect.Height( nHeight );
615}
616
622{
623 tools::Long nOfstX;
624
625 // calc offset inside frame
626 if ( IsVertLR() )
627 // X offset is Y - left.
628 nOfstX = rPoint.X() - getFrameArea().Left();
629 else
630 {
631 // X offset is right - X.
632 if ( mbIsSwapped )
633 nOfstX = getFrameArea().Left() + getFrameArea().Height() - rPoint.X();
634 else
635 nOfstX = getFrameArea().Left() + getFrameArea().Width() - rPoint.X();
636 }
637
638 tools::Long nOfstY;
639 if (IsVertLRBT())
640 {
641 // Y offset is bottom - Y.
642 if (mbIsSwapped)
643 nOfstY = getFrameArea().Top() + getFrameArea().Width() - rPoint.Y();
644 else
645 nOfstY = getFrameArea().Top() + getFrameArea().Height() - rPoint.Y();
646 }
647 else
648 // Y offset is Y - top.
649 nOfstY = rPoint.Y() - getFrameArea().Top();
650
651 // calc rotated coords
652 rPoint.setX( getFrameArea().Left() + nOfstY );
653 rPoint.setY( getFrameArea().Top() + nOfstX );
654}
655
661{
662 Point aTmp( nLimit, 0 );
664 return aTmp.Y();
665}
666
667SwFrameSwapper::SwFrameSwapper( const SwTextFrame* pTextFrame, bool bSwapIfNotSwapped )
668 : pFrame( pTextFrame ), bUndo( false )
669{
670 if (pFrame->IsVertical() && bSwapIfNotSwapped != pFrame->IsSwapped())
671 {
672 bUndo = true;
673 const_cast<SwTextFrame*>(pFrame)->SwapWidthAndHeight();
674 }
675}
676
678{
679 if ( bUndo )
680 const_cast<SwTextFrame*>(pFrame)->SwapWidthAndHeight();
681}
682
684{
685 SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
686
687 tools::Long nWidth = rRect.Width();
688 rRect.Left( 2 * ( getFrameArea().Left() + getFramePrintArea().Left() ) +
689 getFramePrintArea().Width() - rRect.Right() - 1 );
690
691 rRect.Width( nWidth );
692}
693
694void SwTextFrame::SwitchLTRtoRTL( Point& rPoint ) const
695{
696 SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
697
698 rPoint.setX( 2 * ( getFrameArea().Left() + getFramePrintArea().Left() ) + getFramePrintArea().Width() - rPoint.X() - 1 );
699}
700
702 m_rOut( rOutp ), m_nOldLayoutMode( rOutp.GetLayoutMode() )
703{
704}
705
707{
708 const_cast<OutputDevice&>(m_rOut).SetLayoutMode( m_nOldLayoutMode );
709}
710
711void SwLayoutModeModifier::Modify( bool bChgToRTL )
712{
713 const_cast<OutputDevice&>(m_rOut).SetLayoutMode( bChgToRTL ?
716}
717
719{
720 const vcl::text::ComplexTextLayoutFlags nNewLayoutMode = m_nOldLayoutMode & ~vcl::text::ComplexTextLayoutFlags::BiDiStrong;
721 const_cast<OutputDevice&>(m_rOut).SetLayoutMode( nNewLayoutMode );
722}
723
725 rOut( rOutp ), nOldLanguageType( rOutp.GetDigitLanguage() )
726{
727 LanguageType eLang = eCurLang;
729 eLang = LANGUAGE_ENGLISH_US;
730 else
731 {
732 const SvtCTLOptions::TextNumerals nTextNumerals = SW_MOD()->GetCTLOptions().GetCTLTextNumerals();
733
734 if ( SvtCTLOptions::NUMERALS_HINDI == nTextNumerals )
736 else if ( SvtCTLOptions::NUMERALS_ARABIC == nTextNumerals )
737 eLang = LANGUAGE_ENGLISH;
738 else if ( SvtCTLOptions::NUMERALS_SYSTEM == nTextNumerals )
739 eLang = ::GetAppLanguage();
740 }
741
742 const_cast<OutputDevice&>(rOut).SetDigitLanguage( eLang );
743}
744
746{
747 const_cast<OutputDevice&>(rOut).SetDigitLanguage( nOldLanguageType );
748}
749
751{
752 OSL_ENSURE( !IsLocked(), "+SwTextFrame::Init: this is locked." );
753 if( !IsLocked() )
754 {
755 ClearPara();
757 // set flags directly to save a ResetPreps call,
758 // and thereby an unnecessary GetPara call
759 // don't set bOrphan, bLocked or bWait to false!
760 // bOrphan = bFlag7 = bFlag8 = false;
761 }
762}
763
765 sw::FrameMode const eMode)
766 : SwContentFrame( pNode, pSib )
767 , mnAllLines( 0 )
768 , mnThisLines( 0 )
769 , mnFlyAnchorOfst( 0 )
770 , mnFlyAnchorOfstNoWrap( 0 )
771 , mnFlyAnchorVertOfstNoWrap( 0 )
772 , mnFootnoteLine( 0 )
773 , mnHeightOfLastLine( 0 )
774 , mnAdditionalFirstLineOffset( 0 )
775 , mnOffset( 0 )
776 , mnCacheIndex( USHRT_MAX )
777 , mbLocked( false )
778 , mbWidow( false )
779 , mbJustWidow( false )
780 , mbEmpty( false )
781 , mbInFootnoteConnect( false )
782 , mbFootnote( false )
783 , mbRepaint( false )
784 , mbHasRotatedPortions( false )
785 , mbFieldFollow( false )
786 , mbHasAnimation( false )
787 , mbIsSwapped( false )
788 , mbFollowFormatAllowed( true )
789{
791 // note: this may call SwClientNotify if it's in a list so do it last
792 // note: this may change this->pRegisteredIn to m_pMergedPara->listeners
793 m_pMergedPara = CheckParaRedlineMerge(*this, *pNode, eMode);
794}
795
796namespace sw {
797
798SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *const pSibling,
799 sw::FrameMode const eMode)
800{
801 return new SwTextFrame(&rNode, pSibling, eMode);
802}
803
805 SwRootFrame const& rLayout, SwTextNode const& rTextNode,
806 std::vector<std::pair<sal_Int32, sal_Int32>> const*const pExtents)
807{
808 if (pExtents && pExtents->empty())
809 {
810 return; // nothing to do
811 }
812 const SwFootnoteIdxs &rFootnoteIdxs = rTextNode.GetDoc().GetFootnoteIdxs();
813 size_t nPos = 0;
814 SwNodeOffset const nIndex = rTextNode.GetIndex();
815 rFootnoteIdxs.SeekEntry( rTextNode, &nPos );
816 if (nPos < rFootnoteIdxs.size())
817 {
818 while (nPos && rTextNode == (rFootnoteIdxs[ nPos ]->GetTextNode()))
819 --nPos;
820 if (nPos || rTextNode != (rFootnoteIdxs[ nPos ]->GetTextNode()))
821 ++nPos;
822 }
823 size_t iter(0);
824 for ( ; nPos < rFootnoteIdxs.size(); ++nPos)
825 {
826 SwTextFootnote* pTextFootnote = rFootnoteIdxs[ nPos ];
827 if (pTextFootnote->GetTextNode().GetIndex() > nIndex)
828 break;
829 if (pExtents)
830 {
831 while ((*pExtents)[iter].second <= pTextFootnote->GetStart())
832 {
833 ++iter;
834 if (iter == pExtents->size())
835 {
836 return;
837 }
838 }
839 if (pTextFootnote->GetStart() < (*pExtents)[iter].first)
840 {
841 continue;
842 }
843 }
844 pTextFootnote->DelFrames(&rLayout);
845 }
846}
847
848} // namespace sw
849
851{
852 // Remove associated SwParaPortion from s_pTextCache
853 ClearPara();
854
855 assert(!GetDoc().IsInDtor()); // this shouldn't be happening with ViewShell owning layout
856 if (!GetDoc().IsInDtor() && HasFootnote())
857 {
858 if (m_pMergedPara)
859 {
860 SwTextNode const* pNode(nullptr);
861 for (auto const& e : m_pMergedPara->extents)
862 {
863 if (e.pNode != pNode)
864 {
865 pNode = e.pNode;
866 // sw_redlinehide: not sure if it's necessary to check
867 // if the nodes are still alive here, which would require
868 // accessing WriterMultiListener::m_vDepends
869 sw::RemoveFootnotesForNode(*getRootFrame(), *pNode, nullptr);
870 }
871 }
872 }
873 else
874 {
875 SwTextNode *const pNode(static_cast<SwTextNode*>(GetDep()));
876 if (pNode)
877 {
878 sw::RemoveFootnotesForNode(*getRootFrame(), *pNode, nullptr);
879 }
880 }
881 }
882
883 if (!GetDoc().IsInDtor())
884 {
885 if (SwView* pView = GetActiveView())
886 pView->GetEditWin().GetFrameControlsManager().RemoveControls(this);
887 }
888
890}
891
893{
895}
896
897namespace sw {
898
899// 1. if real insert => correct nStart/nEnd for full nLen
900// 2. if rl un-delete => do not correct nStart/nEnd but just include un-deleted
902 bool const isRealInsert,
903 SwTextNode const& rNode, sal_Int32 const nIndex, sal_Int32 const nLen)
904{
905 assert(!isRealInsert || nLen); // can 0 happen? yes, for redline in empty node
906 assert(nIndex <= rNode.Len());
907 assert(nIndex + nLen <= rNode.Len());
908 assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
909 if (!nLen)
910 {
911 return TextFrameIndex(0);
912 }
913 OUStringBuffer text(rMerged.mergedText);
914 sal_Int32 nTFIndex(0); // index used for insertion at the end
915 sal_Int32 nInserted(0);
916 bool bInserted(false);
917 bool bFoundNode(false);
918 auto itInsert(rMerged.extents.end());
919 for (auto it = rMerged.extents.begin(); it != rMerged.extents.end(); ++it)
920 {
921 if (it->pNode == &rNode)
922 {
923 if (isRealInsert)
924 {
925 bFoundNode = true;
926 if (it->nStart <= nIndex && nIndex <= it->nEnd)
927 { // note: this can happen only once
928 text.insert(nTFIndex + (nIndex - it->nStart),
929 rNode.GetText().subView(nIndex, nLen));
930 it->nEnd += nLen;
931 nInserted = nLen;
932 assert(!bInserted);
933 bInserted = true;
934 }
935 else if (nIndex < it->nStart)
936 {
937 if (itInsert == rMerged.extents.end())
938 {
939 itInsert = it;
940 }
941 it->nStart += nLen;
942 it->nEnd += nLen;
943 }
944 }
945 else
946 {
947 assert(it == rMerged.extents.begin() || (it-1)->pNode != &rNode || (it-1)->nEnd < nIndex);
948 if (nIndex + nLen < it->nStart)
949 {
950 itInsert = it;
951 break;
952 }
953 if (nIndex < it->nStart)
954 {
955 text.insert(nTFIndex,
956 rNode.GetText().subView(nIndex, it->nStart - nIndex));
957 nInserted += it->nStart - nIndex;
958 it->nStart = nIndex;
959 bInserted = true;
960 }
961 assert(it->nStart <= nIndex);
962 if (nIndex <= it->nEnd)
963 {
964 nTFIndex += it->nEnd - it->nStart;
965 while (it->nEnd < nIndex + nLen)
966 {
967 auto *const pNext(
968 (it+1) != rMerged.extents.end() && (it+1)->pNode == it->pNode
969 ? &*(it+1)
970 : nullptr);
971 if (pNext && pNext->nStart <= nIndex + nLen)
972 {
973 text.insert(nTFIndex,
974 rNode.GetText().subView(it->nEnd, pNext->nStart - it->nEnd));
975 nTFIndex += pNext->nStart - it->nEnd;
976 nInserted += pNext->nStart - it->nEnd;
977 pNext->nStart = it->nStart;
978 it = rMerged.extents.erase(it);
979 }
980 else
981 {
982 text.insert(nTFIndex,
983 rNode.GetText().subView(it->nEnd, nIndex + nLen - it->nEnd));
984 nTFIndex += nIndex + nLen - it->nEnd;
985 nInserted += nIndex + nLen - it->nEnd;
986 it->nEnd = nIndex + nLen;
987 }
988 }
989 bInserted = true;
990 break;
991 }
992 }
993 }
994 else if (rNode.GetIndex() < it->pNode->GetIndex() || bFoundNode)
995 {
996 if (itInsert == rMerged.extents.end())
997 {
998 itInsert = it;
999 }
1000 break;
1001 }
1002 if (itInsert == rMerged.extents.end())
1003 {
1004 nTFIndex += it->nEnd - it->nStart;
1005 }
1006 }
1007// assert((bFoundNode || rMerged.extents.empty()) && "text node not found - why is it sending hints to us");
1008 if (!bInserted)
1009 { // must be in a gap
1010 rMerged.extents.emplace(itInsert, const_cast<SwTextNode*>(&rNode), nIndex, nIndex + nLen);
1011 text.insert(nTFIndex, rNode.GetText().subView(nIndex, nLen));
1012 nInserted = nLen;
1013 if (rMerged.extents.size() == 1 // also if it was empty!
1014 || rMerged.pParaPropsNode->GetIndex() < rNode.GetIndex())
1015 { // text inserted after current para-props node
1017 rMerged.pParaPropsNode = &const_cast<SwTextNode&>(rNode);
1019 }
1020 // called from SwRangeRedline::InvalidateRange()
1022 {
1023 const_cast<SwTextNode&>(rNode).SetRedlineMergeFlag(SwNode::Merge::NonFirst);
1024 }
1025 }
1026 rMerged.mergedText = text.makeStringAndClear();
1027 return TextFrameIndex(nInserted);
1028}
1029
1030// 1. if real delete => correct nStart/nEnd for full nLen
1031// 2. if rl delete => do not correct nStart/nEnd but just exclude deleted
1033 bool const isRealDelete,
1034 SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 const nLen)
1035{
1036 assert(nIndex <= rNode.Len());
1037 assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
1038 OUStringBuffer text(rMerged.mergedText);
1039 sal_Int32 nTFIndex(0);
1040 sal_Int32 nToDelete(nLen);
1041 sal_Int32 nDeleted(0);
1042 size_t nFoundNode(0);
1043 size_t nErased(0);
1044 auto it = rMerged.extents.begin();
1045 for (; it != rMerged.extents.end(); )
1046 {
1047 bool bErase(false);
1048 if (it->pNode == &rNode)
1049 {
1050 ++nFoundNode;
1051 if (nIndex + nToDelete < it->nStart)
1052 {
1053 nToDelete = 0;
1054 if (!isRealDelete)
1055 {
1056 break;
1057 }
1058 it->nStart -= nLen;
1059 it->nEnd -= nLen;
1060 }
1061 else
1062 {
1063 if (nIndex < it->nStart)
1064 {
1065 // do not adjust nIndex into the text frame index space!
1066 nToDelete -= it->nStart - nIndex;
1067 nIndex = it->nStart;
1068 // note: continue with the if check below, no else!
1069 }
1070 if (it->nStart <= nIndex && nIndex < it->nEnd)
1071 {
1072 sal_Int32 const nDeleteHere(nIndex + nToDelete <= it->nEnd
1073 ? nToDelete
1074 : it->nEnd - nIndex);
1075 text.remove(nTFIndex + (nIndex - it->nStart), nDeleteHere);
1076 bErase = nDeleteHere == it->nEnd - it->nStart;
1077 if (bErase)
1078 {
1079 ++nErased;
1080 assert(it->nStart == nIndex);
1081 it = rMerged.extents.erase(it);
1082 }
1083 else if (isRealDelete)
1084 { // adjust for deleted text
1085 it->nStart -= (nLen - nToDelete);
1086 it->nEnd -= (nLen - nToDelete + nDeleteHere);
1087 if (it != rMerged.extents.begin()
1088 && (it-1)->pNode == &rNode
1089 && (it-1)->nEnd == it->nStart)
1090 { // merge adjacent extents
1091 nTFIndex += it->nEnd - it->nStart;
1092 (it-1)->nEnd = it->nEnd;
1093 it = rMerged.extents.erase(it);
1094 bErase = true; // skip increment
1095 }
1096 }
1097 else
1098 { // exclude text marked as deleted
1099 if (nIndex + nDeleteHere == it->nEnd)
1100 {
1101 it->nEnd -= nDeleteHere;
1102 }
1103 else
1104 {
1105 if (nIndex == it->nStart)
1106 {
1107 it->nStart += nDeleteHere;
1108 }
1109 else
1110 {
1111 sal_Int32 const nOldEnd(it->nEnd);
1112 it->nEnd = nIndex;
1113 it = rMerged.extents.emplace(it+1,
1114 it->pNode, nIndex + nDeleteHere, nOldEnd);
1115 }
1116 assert(nDeleteHere == nToDelete);
1117 }
1118 }
1119 nDeleted += nDeleteHere;
1120 nToDelete -= nDeleteHere;
1121 nIndex += nDeleteHere;
1122 if (!isRealDelete && nToDelete == 0)
1123 {
1124 break;
1125 }
1126 }
1127 }
1128 }
1129 else if (nFoundNode != 0)
1130 {
1131 break;
1132 }
1133 if (!bErase)
1134 {
1135 nTFIndex += it->nEnd - it->nStart;
1136 ++it;
1137 }
1138 }
1139// assert(nFoundNode != 0 && "text node not found - why is it sending hints to us");
1140 assert(nIndex <= rNode.Len() + nLen);
1141 // if there's a remaining deletion, it must be in gap at the end of the node
1142// can't do: might be last one in node was erased assert(nLen == 0 || rMerged.empty() || (it-1)->nEnd <= nIndex);
1143 // note: if first node gets deleted then that must call DelFrames as
1144 // pFirstNode is never updated
1145 if (nErased && nErased == nFoundNode)
1146 { // all visible text from node was erased
1147#if 1
1148 if (rMerged.pParaPropsNode == &rNode)
1149 {
1151 rMerged.pParaPropsNode = rMerged.extents.empty()
1152 ? const_cast<SwTextNode*>(rMerged.pLastNode)
1153 : rMerged.extents.front().pNode;
1155 }
1156#endif
1157// NOPE must listen on all non-hidden nodes; particularly on pLastNode rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode));
1158 }
1159 rMerged.mergedText = text.makeStringAndClear();
1160 return TextFrameIndex(nDeleted);
1161}
1162
1163std::pair<SwTextNode*, sal_Int32>
1164MapViewToModel(MergedPara const& rMerged, TextFrameIndex const i_nIndex)
1165{
1166 sal_Int32 nIndex(i_nIndex);
1167 sw::Extent const* pExtent(nullptr);
1168 for (const auto& rExt : rMerged.extents)
1169 {
1170 pExtent = &rExt;
1171 if (nIndex < (pExtent->nEnd - pExtent->nStart))
1172 {
1173 return std::make_pair(pExtent->pNode, pExtent->nStart + nIndex);
1174 }
1175 nIndex = nIndex - (pExtent->nEnd - pExtent->nStart);
1176 }
1177 assert(nIndex == 0 && "view index out of bounds");
1178 return pExtent
1179 ? std::make_pair(pExtent->pNode, pExtent->nEnd) //1-past-the-end index
1180 : std::make_pair(const_cast<SwTextNode*>(rMerged.pLastNode), rMerged.pLastNode->Len());
1181}
1182
1183TextFrameIndex MapModelToView(MergedPara const& rMerged, SwTextNode const*const pNode, sal_Int32 const nIndex)
1184{
1185 assert(rMerged.pFirstNode->GetIndex() <= pNode->GetIndex()
1186 && pNode->GetIndex() <= rMerged.pLastNode->GetIndex());
1187 sal_Int32 nRet(0);
1188 bool bFoundNode(false);
1189 for (auto const& e : rMerged.extents)
1190 {
1191 if (pNode->GetIndex() < e.pNode->GetIndex())
1192 {
1193 return TextFrameIndex(nRet);
1194 }
1195 if (e.pNode == pNode)
1196 {
1197 if (e.nStart <= nIndex && nIndex <= e.nEnd)
1198 {
1199 return TextFrameIndex(nRet + (nIndex - e.nStart));
1200 }
1201 else if (nIndex < e.nStart)
1202 {
1203 // in gap before this extent => map to 0 here TODO???
1204 return TextFrameIndex(nRet);
1205 }
1206 bFoundNode = true;
1207 }
1208 else if (bFoundNode)
1209 {
1210 break;
1211 }
1212 nRet += e.nEnd - e.nStart;
1213 }
1214 if (bFoundNode)
1215 {
1216 // must be in a gap at the end of the node
1217 assert(nIndex <= pNode->Len());
1218 return TextFrameIndex(nRet);
1219 }
1220 else if (rMerged.extents.empty())
1221 {
1222 assert(nIndex <= pNode->Len());
1223 return TextFrameIndex(0);
1224 }
1225 return TextFrameIndex(rMerged.mergedText.getLength());
1226}
1227
1228} // namespace sw
1229
1230std::pair<SwTextNode*, sal_Int32>
1232{
1233//nope assert(GetPara());
1234 sw::MergedPara const*const pMerged(GetMergedPara());
1235 if (pMerged)
1236 {
1237 return sw::MapViewToModel(*pMerged, nIndex);
1238 }
1239 else
1240 {
1241 return std::make_pair(static_cast<SwTextNode*>(const_cast<sw::BroadcastingModify*>(
1242 SwFrame::GetDep())), sal_Int32(nIndex));
1243 }
1244}
1245
1247{
1248 std::pair<SwTextNode*, sal_Int32> const ret(MapViewToModel(nIndex));
1249 return SwPosition(*ret.first, ret.second);
1250}
1251
1252TextFrameIndex SwTextFrame::MapModelToView(SwTextNode const*const pNode, sal_Int32 const nIndex) const
1253{
1254//nope assert(GetPara());
1255 sw::MergedPara const*const pMerged(GetMergedPara());
1256 if (pMerged)
1257 {
1258 return sw::MapModelToView(*pMerged, pNode, nIndex);
1259 }
1260 else
1261 {
1262 assert(static_cast<SwTextNode*>(const_cast<sw::BroadcastingModify*>(SwFrame::GetDep())) == pNode);
1263 return TextFrameIndex(nIndex);
1264 }
1265}
1266
1268{
1269 SwTextNode const*const pNode(rPos.GetNode().GetTextNode());
1270 sal_Int32 const nIndex(rPos.GetContentIndex());
1271 return MapModelToView(pNode, nIndex);
1272}
1273
1274void SwTextFrame::SetMergedPara(std::unique_ptr<sw::MergedPara> p)
1275{
1276 SwTextNode *const pFirst(m_pMergedPara ? m_pMergedPara->pFirstNode : nullptr);
1277 m_pMergedPara = std::move(p);
1278 if (pFirst)
1279 {
1280 if (m_pMergedPara)
1281 {
1282 assert(pFirst == m_pMergedPara->pFirstNode);
1283 }
1284 else
1285 {
1286 pFirst->Add(this); // must register at node again
1287 }
1288 }
1289 // postcondition: frame must be listening somewhere
1290 assert(m_pMergedPara || GetDep());
1291}
1292
1293const OUString& SwTextFrame::GetText() const
1294{
1295//nope assert(GetPara());
1296 sw::MergedPara const*const pMerged(GetMergedPara());
1297 if (pMerged)
1298 return pMerged->mergedText;
1299 else
1300 return static_cast<SwTextNode const*>(SwFrame::GetDep())->GetText();
1301}
1302
1304{
1305 // FIXME can GetPara be 0 ? yes... this is needed in SwContentNotify::SwContentNotify() which is called before any formatting is started
1306//nope assert(GetPara());
1307 sw::MergedPara const*const pMerged(GetMergedPara());
1308 if (pMerged)
1309 {
1310// assert(pMerged->pFirstNode == pMerged->pParaPropsNode); // surprising news!
1311 return pMerged->pParaPropsNode;
1312 }
1313 else
1314 return static_cast<SwTextNode const*>(SwFrame::GetDep());
1315}
1316
1318{
1319 sw::MergedPara const*const pMerged(GetMergedPara());
1320 if (pMerged)
1321 return pMerged->extents.empty()
1322 ? pMerged->pFirstNode
1323 : pMerged->extents.front().pNode;
1324 else
1325 return static_cast<SwTextNode const*>(SwFrame::GetDep());
1326}
1327
1329{
1330//nope assert(GetPara());
1331 sw::MergedPara const*const pMerged(GetMergedPara());
1332 if (pMerged)
1333 return pMerged->pFirstNode;
1334 else
1335 return static_cast<SwTextNode const*>(SwFrame::GetDep());
1336}
1337
1339{
1340 return GetTextNodeFirst()->GetDoc();
1341}
1342
1344 sal_uInt16 const nScript, bool const bNoChar) const
1345{
1346 // a single character can be mapped uniquely!
1347 std::pair<SwTextNode const*, sal_Int32> const pos(MapViewToModel(nIndex));
1348 return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript);
1349}
1350
1352{
1353 if ( GetCacheIdx() != USHRT_MAX )
1354 {
1355 if (SwParaPortion *pPara = GetPara())
1356 pPara->ResetPreps();
1357 }
1358}
1359
1361{
1362 SwFrameSwapper aSwapper( this, true );
1363
1364 if( !getFrameArea().Width() && isFrameAreaDefinitionValid() && GetUpper()->isFrameAreaDefinitionValid() ) // invalid when stack overflows (StackHack)!
1365 {
1366// OSL_FAIL( "SwTextFrame::IsHiddenNow: thin frame" );
1367 return true;
1368 }
1369
1370 bool bHiddenCharsHidePara(false);
1371 bool bHiddenParaField(false);
1372 if (m_pMergedPara)
1373 {
1374 TextFrameIndex nHiddenStart(COMPLETE_STRING);
1375 TextFrameIndex nHiddenEnd(0);
1376 if (auto const pScriptInfo = GetScriptInfo())
1377 {
1378 pScriptInfo->GetBoundsOfHiddenRange(TextFrameIndex(0),
1379 nHiddenStart, nHiddenEnd);
1380 }
1381 else // ParaPortion is created in Format, but this is called earlier
1382 {
1383 SwScriptInfo aInfo;
1384 aInfo.InitScriptInfo(*m_pMergedPara->pFirstNode, m_pMergedPara.get(), IsRightToLeft());
1386 nHiddenStart, nHiddenEnd);
1387 }
1388 if (TextFrameIndex(0) == nHiddenStart &&
1389 TextFrameIndex(GetText().getLength()) <= nHiddenEnd)
1390 {
1391 bHiddenCharsHidePara = true;
1392 }
1393 sw::MergedAttrIter iter(*this);
1394 SwTextNode const* pNode(nullptr);
1395 int nNewResultWeight = 0;
1396 for (SwTextAttr const* pHint = iter.NextAttr(&pNode); pHint; pHint = iter.NextAttr(&pNode))
1397 {
1398 if (pHint->Which() == RES_TXTATR_FIELD)
1399 {
1400 // see also SwpHints::CalcHiddenParaField()
1401 const SwFormatField& rField = pHint->GetFormatField();
1402 int nCurWeight = pNode->GetDoc().FieldCanHideParaWeight(rField.GetField()->GetTyp()->Which());
1403 if (nCurWeight > nNewResultWeight)
1404 {
1405 nNewResultWeight = nCurWeight;
1406 bHiddenParaField = pNode->GetDoc().FieldHidesPara(*rField.GetField());
1407 }
1408 else if (nCurWeight == nNewResultWeight && bHiddenParaField)
1409 {
1410 // Currently, for both supported hiding types (HiddenPara, Database), "Don't hide"
1411 // takes precedence - i.e., if there's a "Don't hide" field of that weight, we only
1412 // care about fields of higher weight.
1413 bHiddenParaField = pNode->GetDoc().FieldHidesPara(*rField.GetField());
1414 }
1415 }
1416 }
1417 }
1418 else
1419 {
1420 bHiddenCharsHidePara = static_cast<SwTextNode const*>(SwFrame::GetDep())->HasHiddenCharAttribute( true );
1421 bHiddenParaField = static_cast<SwTextNode const*>(SwFrame::GetDep())->IsHiddenByParaField();
1422 }
1423 const SwViewShell* pVsh = getRootFrame()->GetCurrShell();
1424
1425 if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
1426 {
1427
1428 if (
1429 ( bHiddenParaField &&
1430 ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
1431 !pVsh->GetViewOptions()->IsFieldName() ) ) ||
1432 ( bHiddenCharsHidePara &&
1433 !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
1434 {
1435 return true;
1436 }
1437 }
1438
1439 return false;
1440}
1441
1444{
1445 OSL_ENSURE( !GetFollow() && IsHiddenNow(),
1446 "HideHidden on visible frame of hidden frame has follow" );
1447
1450
1451 // format information is obsolete
1452 ClearPara();
1453}
1454
1456{
1457 SwPageFrame *pPage = nullptr;
1458 sw::MergedAttrIter iter(*this);
1459 SwTextNode const* pNode(nullptr);
1460 for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
1461 {
1462 if (pHt->Which() == RES_TXTATR_FTN)
1463 {
1464 TextFrameIndex const nIdx(MapModelToView(pNode, pHt->GetStart()));
1465 if (nEnd < nIdx)
1466 break;
1467 if (nStart <= nIdx)
1468 {
1469 if (!pPage)
1470 pPage = FindPageFrame();
1471 pPage->RemoveFootnote( this, static_cast<const SwTextFootnote*>(pHt) );
1472 }
1473 }
1474 }
1475}
1476
1486bool sw_HideObj( const SwTextFrame& _rFrame,
1487 const RndStdIds _eAnchorType,
1488 SwPosition const& rAnchorPos,
1489 SwAnchoredObject* _pAnchoredObj )
1490{
1491 bool bRet( true );
1492
1493 if (_eAnchorType == RndStdIds::FLY_AT_CHAR)
1494 {
1495 const IDocumentSettingAccess *const pIDSA = &_rFrame.GetDoc().getIDocumentSettingAccess();
1500 _rFrame.IsInDocBody() && !_rFrame.FindNextCnt() )
1501 {
1502 SwTextNode const& rNode(*rAnchorPos.GetNode().GetTextNode());
1503 assert(FrameContainsNode(_rFrame, rNode.GetIndex()));
1504 sal_Int32 const nObjAnchorPos(rAnchorPos.GetContentIndex());
1505 const sal_Unicode cAnchorChar = nObjAnchorPos < rNode.Len()
1506 ? rNode.GetText()[nObjAnchorPos]
1507 : 0;
1508 if (cAnchorChar == CH_TXTATR_BREAKWORD)
1509 {
1510 const SwTextAttr* const pHint(
1511 rNode.GetTextAttrForCharAt(nObjAnchorPos, RES_TXTATR_FLYCNT));
1512 if ( pHint )
1513 {
1514 const SwFrameFormat* pFrameFormat =
1515 static_cast<const SwTextFlyCnt*>(pHint)->GetFlyCnt().GetFrameFormat();
1516 if ( pFrameFormat->Which() == RES_FLYFRMFMT )
1517 {
1518 SwNodeIndex nContentIndex = *(pFrameFormat->GetContent().GetContentIdx());
1519 ++nContentIndex;
1520 if ( nContentIndex.GetNode().IsNoTextNode() )
1521 {
1522 bRet = false;
1523 // set needed data structure values for object positioning
1524 SwRectFnSet aRectFnSet(&_rFrame);
1525 SwRect aLastCharRect( _rFrame.getFrameArea() );
1526 aRectFnSet.SetWidth( aLastCharRect, 1 );
1527 _pAnchoredObj->maLastCharRect = aLastCharRect;
1528 _pAnchoredObj->mnLastTopOfLine = aRectFnSet.GetTop(aLastCharRect);
1529 }
1530 }
1531 }
1532 }
1533 }
1534 }
1535
1536 return bRet;
1537}
1538
1550{
1551 if ( GetDrawObjs() )
1552 {
1553 if ( IsHiddenNow() )
1554 {
1555 // complete paragraph is hidden. Thus, hide all objects
1556 for (SwAnchoredObject* i : *GetDrawObjs())
1557 {
1558 SdrObject* pObj = i->DrawObj();
1559 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
1560 // under certain conditions
1561 const RndStdIds eAnchorType( pContact->GetAnchorId() );
1562 if ((eAnchorType != RndStdIds::FLY_AT_CHAR) ||
1563 sw_HideObj(*this, eAnchorType, pContact->GetContentAnchor(),
1564 i ))
1565 {
1566 pContact->MoveObjToInvisibleLayer( pObj );
1567 }
1568 }
1569 }
1570 else
1571 {
1572 // paragraph is visible, but can contain hidden text portion.
1573 // first we check if objects are allowed to be hidden:
1574 const SwViewShell* pVsh = getRootFrame()->GetCurrShell();
1575 const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
1576 !pVsh->GetViewOptions()->IsShowHiddenChar();
1577
1578 // Thus, show all objects, which are anchored at paragraph and
1579 // hide/show objects, which are anchored at/as character, according
1580 // to the visibility of the anchor character.
1581 for (SwAnchoredObject* i : *GetDrawObjs())
1582 {
1583 SdrObject* pObj = i->DrawObj();
1584 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
1585 // Determine anchor type only once
1586 const RndStdIds eAnchorType( pContact->GetAnchorId() );
1587
1588 if (eAnchorType == RndStdIds::FLY_AT_PARA)
1589 {
1590 pContact->MoveObjToVisibleLayer( pObj );
1591 }
1592 else if ((eAnchorType == RndStdIds::FLY_AT_CHAR) ||
1593 (eAnchorType == RndStdIds::FLY_AS_CHAR))
1594 {
1595 sal_Int32 nHiddenStart;
1596 sal_Int32 nHiddenEnd;
1597 const SwPosition& rAnchor = pContact->GetContentAnchor();
1599 *rAnchor.GetNode().GetTextNode(),
1600 rAnchor.GetContentIndex(), nHiddenStart, nHiddenEnd);
1601 // Under certain conditions
1602 if ( nHiddenStart != COMPLETE_STRING && bShouldBeHidden &&
1603 sw_HideObj(*this, eAnchorType, rAnchor, i))
1604 {
1605 pContact->MoveObjToInvisibleLayer( pObj );
1606 }
1607 else
1608 pContact->MoveObjToVisibleLayer( pObj );
1609 }
1610 else
1611 {
1612 OSL_FAIL( "<SwTextFrame::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
1613 }
1614 }
1615 }
1616 }
1617
1618 if (IsFollow())
1619 {
1620 SwTextFrame *pMaster = FindMaster();
1621 OSL_ENSURE(pMaster, "SwTextFrame without master");
1622 if (pMaster)
1623 pMaster->HideAndShowObjects();
1624 }
1625}
1626
1634 const TextFrameIndex nStart,
1635 const TextFrameIndex nEnd)
1636{
1637 sal_Int32 nFound = sal_Int32(nStart);
1638 const sal_Int32 nEndLine = std::min(sal_Int32(nEnd), rText.getLength() - 1);
1639
1640 // Skip all leading blanks.
1641 while( nFound <= nEndLine && ' ' == rText[nFound] )
1642 {
1643 nFound++;
1644 }
1645
1646 // A tricky situation with the TextAttr-Dummy-character (in this case "$"):
1647 // "Dr.$Meyer" at the beginning of the second line. Typing a blank after that
1648 // doesn't result in the word moving into first line, even though that would work.
1649 // For this reason we don't skip the dummy char.
1650 while( nFound <= nEndLine && ' ' != rText[nFound] )
1651 {
1652 nFound++;
1653 }
1654
1655 return TextFrameIndex(nFound);
1656}
1657
1659{
1660// Silence over-eager warning emitted at least by GCC trunk towards 6:
1661#if defined __GNUC__ && !defined __clang__
1662#pragma GCC diagnostic push
1663#pragma GCC diagnostic ignored "-Wstrict-overflow"
1664#endif
1665 if (nLen != TextFrameIndex(COMPLETE_STRING) && GetOffset() > nPos + nLen) // the range preceded us
1666#if defined __GNUC__ && !defined __clang__
1667#pragma GCC diagnostic pop
1668#endif
1669 return false;
1670
1671 if( !GetFollow() ) // the range doesn't precede us,
1672 return true; // nobody follows us.
1673
1674 TextFrameIndex const nMax = GetFollow()->GetOffset();
1675
1676 // either the range overlap or our text has been deleted
1677 // sw_redlinehide: GetText() should be okay here because it has already
1678 // been updated in the INS/DEL hint case
1679 if (nMax > nPos || nMax > TextFrameIndex(GetText().getLength()))
1680 return true;
1681
1682 // changes made in the first line of a follow can modify the master
1683 const SwParaPortion* pPara = GetFollow()->GetPara();
1684 return pPara && ( nPos <= nMax + pPara->GetLen() );
1685}
1686
1687inline void SwTextFrame::InvalidateRange(const SwCharRange &aRange, const tools::Long nD)
1688{
1689 if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
1690 InvalidateRange_( aRange, nD );
1691}
1692
1694{
1695 if ( !HasPara() )
1696 { InvalidateSize();
1697 return;
1698 }
1699
1700 SetWidow( false );
1701 SwParaPortion *pPara = GetPara();
1702
1703 bool bInv = false;
1704 if( 0 != nD )
1705 {
1706 // In nDelta the differences between old and new
1707 // linelengths are being added, that's why it's negative
1708 // if chars have been added and positive, if chars have
1709 // deleted
1710 pPara->SetDelta(pPara->GetDelta() + nD);
1711 bInv = true;
1712 }
1713 SwCharRange &rReformat = pPara->GetReformat();
1714 if(aRange != rReformat) {
1715 if (TextFrameIndex(COMPLETE_STRING) == rReformat.Len())
1716 rReformat = aRange;
1717 else
1718 rReformat += aRange;
1719 bInv = true;
1720 }
1721 if(bInv)
1722 {
1724 }
1725}
1726
1728{
1729 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
1730 "SwTextFrame::CalcLineSpace with swapped frame!" );
1731
1732 if( IsLocked() || !HasPara() )
1733 return;
1734
1735 if( GetDrawObjs() ||
1736 GetTextNodeForParaProps()->GetSwAttrSet().GetLRSpace().IsAutoFirst())
1737 {
1738 Init();
1739 return;
1740 }
1741
1742 SwParaPortion *const pPara(GetPara());
1743 assert(pPara);
1744 if (pPara->IsFixLineHeight())
1745 {
1746 Init();
1747 return;
1748 }
1749
1750 Size aNewSize( getFramePrintArea().SSize() );
1751
1752 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this );
1753 SwTextFormatter aLine( this, &aInf );
1754 if( aLine.GetDropLines() )
1755 {
1756 Init();
1757 return;
1758 }
1759
1760 aLine.Top();
1761 aLine.RecalcRealHeight();
1762
1763 aNewSize.setHeight( (aLine.Y() - getFrameArea().Top()) + aLine.GetLineHeight() );
1764
1765 SwTwips nDelta = aNewSize.Height() - getFramePrintArea().Height();
1766 // Underflow with free-flying frames
1767 if( aInf.GetTextFly().IsOn() )
1768 {
1769 SwRect aTmpFrame( getFrameArea() );
1770 if( nDelta < 0 )
1771 aTmpFrame.Height( getFramePrintArea().Height() );
1772 else
1773 aTmpFrame.Height( aNewSize.Height() );
1774 if( aInf.GetTextFly().Relax( aTmpFrame ) )
1775 {
1776 Init();
1777 return;
1778 }
1779 }
1780
1781 if( !nDelta )
1782 return;
1783
1784 SwTextFrameBreak aBreak( this );
1785 if( GetFollow() || aBreak.IsBreakNow( aLine ) )
1786 {
1787 // if there is a Follow() or if we need to break here, reformat
1788 Init();
1789 }
1790 else
1791 {
1792 // everything is business as usual...
1793 pPara->SetPrepAdjust();
1794 pPara->SetPrep();
1795 }
1796}
1797
1798static void lcl_SetWrong( SwTextFrame& rFrame, SwTextNode const& rNode,
1799 sal_Int32 const nPos, sal_Int32 const nCnt, bool const bMove)
1800{
1801 if ( !rFrame.IsFollow() )
1802 {
1803 SwTextNode* pTextNode = const_cast<SwTextNode*>(&rNode);
1804 IGrammarContact* pGrammarContact = getGrammarContact( *pTextNode );
1805 SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
1806 pGrammarContact->getGrammarCheck( *pTextNode, false ) :
1807 pTextNode->GetGrammarCheck();
1808 bool bGrammarProxy = pWrongGrammar != pTextNode->GetGrammarCheck();
1809 if( bMove )
1810 {
1811 if( pTextNode->GetWrong() )
1812 pTextNode->GetWrong()->Move( nPos, nCnt );
1813 if( pWrongGrammar )
1814 pWrongGrammar->MoveGrammar( nPos, nCnt );
1815 if( bGrammarProxy && pTextNode->GetGrammarCheck() )
1816 pTextNode->GetGrammarCheck()->MoveGrammar( nPos, nCnt );
1817 if( pTextNode->GetSmartTags() )
1818 pTextNode->GetSmartTags()->Move( nPos, nCnt );
1819 }
1820 else
1821 {
1822 if( pTextNode->GetWrong() )
1823 pTextNode->GetWrong()->Invalidate( nPos, nCnt );
1824 if( pWrongGrammar )
1825 pWrongGrammar->Invalidate( nPos, nCnt );
1826 if( pTextNode->GetSmartTags() )
1827 pTextNode->GetSmartTags()->Invalidate( nPos, nCnt );
1828 }
1829 const sal_Int32 nEnd = nPos + (nCnt > 0 ? nCnt : 1 );
1830 if ( !pTextNode->GetWrong() && !pTextNode->IsWrongDirty() )
1831 {
1832 pTextNode->SetWrong( std::make_unique<SwWrongList>( WRONGLIST_SPELL ) );
1833 pTextNode->GetWrong()->SetInvalid( nPos, nEnd );
1834 }
1835 if ( !pTextNode->GetSmartTags() && !pTextNode->IsSmartTagDirty() )
1836 {
1837 pTextNode->SetSmartTags( std::make_unique<SwWrongList>( WRONGLIST_SMARTTAG ) );
1838 pTextNode->GetSmartTags()->SetInvalid( nPos, nEnd );
1839 }
1841 pTextNode->SetGrammarCheckDirty( true );
1842 pTextNode->SetWordCountDirty( true );
1843 pTextNode->SetAutoCompleteWordDirty( true );
1844 pTextNode->SetSmartTagDirty( true );
1845 }
1846
1847 SwRootFrame *pRootFrame = rFrame.getRootFrame();
1848 if (pRootFrame)
1849 {
1850 pRootFrame->SetNeedGrammarCheck( true );
1851 }
1852
1853 SwPageFrame *pPage = rFrame.FindPageFrame();
1854 if( pPage )
1855 {
1856 pPage->InvalidateSpelling();
1858 pPage->InvalidateWordCount();
1859 pPage->InvalidateSmartTags();
1860 }
1861}
1862
1863static void lcl_SetScriptInval(SwTextFrame& rFrame, TextFrameIndex const nPos)
1864{
1865 if( rFrame.GetPara() )
1867}
1868
1869// note: SwClientNotify will be called once for every frame => just fix own Ofst
1870static void lcl_ModifyOfst(SwTextFrame & rFrame,
1871 TextFrameIndex const nPos, TextFrameIndex const nLen,
1872 TextFrameIndex (* op)(TextFrameIndex const&, TextFrameIndex const&))
1873{
1874 assert(nLen != TextFrameIndex(COMPLETE_STRING));
1875 if (rFrame.IsFollow() && nPos < rFrame.GetOffset())
1876 {
1877 rFrame.ManipOfst( std::max(nPos, op(rFrame.GetOffset(), nLen)) );
1878 assert(sal_Int32(rFrame.GetOffset()) <= rFrame.GetText().getLength());
1879 }
1880}
1881
1882namespace {
1883
1884void UpdateMergedParaForMove(sw::MergedPara & rMerged,
1885 SwTextFrame & rTextFrame,
1886 bool & o_rbRecalcFootnoteFlag,
1887 SwTextNode const& rDestNode,
1888 SwTextNode const& rNode,
1889 sal_Int32 const nDestStart,
1890 sal_Int32 const nSourceStart,
1891 sal_Int32 const nLen)
1892{
1893 std::vector<std::pair<sal_Int32, sal_Int32>> deleted;
1894 sal_Int32 const nSourceEnd(nSourceStart + nLen);
1895 sal_Int32 nLastEnd(0);
1896 for (const auto& rExt : rMerged.extents)
1897 {
1898 if (rExt.pNode == &rNode)
1899 {
1900 sal_Int32 const nStart(std::max(nLastEnd, nSourceStart));
1901 sal_Int32 const nEnd(std::min(rExt.nStart, nSourceEnd));
1902 if (nStart < nEnd)
1903 {
1904 deleted.emplace_back(nStart, nEnd);
1905 }
1906 nLastEnd = rExt.nEnd;
1907 if (nSourceEnd <= rExt.nEnd)
1908 {
1909 break;
1910 }
1911 }
1912 else if (rNode.GetIndex() < rExt.pNode->GetIndex())
1913 {
1914 break;
1915 }
1916 }
1917 if (nLastEnd != rNode.Len()) // without nLen, string yet to be removed
1918 {
1919 if (nLastEnd < nSourceEnd)
1920 {
1921 deleted.emplace_back(std::max(nLastEnd, nSourceStart), nSourceEnd);
1922 }
1923 }
1924 if (deleted.empty())
1925 return;
1926
1927 o_rbRecalcFootnoteFlag = true;
1928 for (auto const& it : deleted)
1929 {
1930 sal_Int32 const nStart(it.first - nSourceStart + nDestStart);
1931 TextFrameIndex const nDeleted = UpdateMergedParaForDelete(rMerged, false,
1932 rDestNode, nStart, it.second - it.first);
1933//FIXME asserts valid for join - but if called from split, the new node isn't there yet and it will be added later... assert(nDeleted);
1934// assert(nDeleted == it.second - it.first);
1935 if(nDeleted)
1936 {
1937 // InvalidateRange/lcl_SetScriptInval was called sufficiently for SwInsText
1938 lcl_SetWrong(rTextFrame, rDestNode, nStart, it.first - it.second, false);
1939 TextFrameIndex const nIndex(sw::MapModelToView(rMerged, &rDestNode, nStart));
1940 lcl_ModifyOfst(rTextFrame, nIndex, nDeleted, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
1941 }
1942 }
1943}
1944
1945} // namespace
1946
1951#if !ENABLE_WASM_STRIP_ACCESSIBILITY
1952static bool isA11yRelevantAttribute(sal_uInt16 nWhich)
1953{
1954 return nWhich != RES_CHRATR_RSID;
1955}
1956
1957static bool hasA11yRelevantAttribute( const std::vector<sal_uInt16>& rWhichFmtAttr )
1958{
1959 for( sal_uInt16 nWhich : rWhichFmtAttr )
1960 if ( isA11yRelevantAttribute( nWhich ) )
1961 return true;
1962
1963 return false;
1964}
1965#endif // ENABLE_WASM_STRIP_ACCESSIBILITY
1966
1967// Note: for now this overrides SwClient::SwClientNotify; the intermediary
1968// classes still override SwClient::Modify, which should continue to work
1969// as their implementation of SwClientNotify is SwClient's which calls Modify.
1970// Therefore we also don't need to call SwClient::SwClientNotify(rModify, rHint)
1971// because that's all it does, and this implementation calls
1972// SwContentFrame::SwClientNotify() when appropriate.
1973void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
1974{
1975 SfxPoolItem const* pOld(nullptr);
1976 SfxPoolItem const* pNew(nullptr);
1977 sw::MoveText const* pMoveText(nullptr);
1978 sw::RedlineDelText const* pRedlineDelText(nullptr);
1979 sw::RedlineUnDelText const* pRedlineUnDelText(nullptr);
1980
1981 sal_uInt16 nWhich = 0;
1982 if (rHint.GetId() == SfxHintId::SwLegacyModify)
1983 {
1984 auto pHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
1985 pOld = pHint->m_pOld;
1986 pNew = pHint->m_pNew;
1987 nWhich = pHint->GetWhich();
1988 }
1989 else if (auto const pHt = dynamic_cast<sw::MoveText const*>(&rHint))
1990 {
1991 pMoveText = pHt;
1992 }
1993 else if (auto const pHynt = dynamic_cast<sw::RedlineDelText const*>(&rHint))
1994 {
1995 pRedlineDelText = pHynt;
1996 }
1997 else if (auto const pHnt = dynamic_cast<sw::RedlineUnDelText const*>(&rHint))
1998 {
1999 pRedlineUnDelText = pHnt;
2000 }
2001 else
2002 {
2003 assert(!"unexpected hint");
2004 }
2005
2006 if (m_pMergedPara)
2007 {
2008 assert(m_pMergedPara->listener.IsListeningTo(&rModify));
2009 }
2010
2011 SwTextNode const& rNode(static_cast<SwTextNode const&>(rModify));
2012
2013 // modifications concerning frame attributes are processed by the base class
2014 if( IsInRange( aFrameFormatSetRange, nWhich ) || RES_FMT_CHG == nWhich )
2015 {
2016 if (m_pMergedPara)
2017 { // ignore item set changes that don't apply
2018 SwTextNode const*const pAttrNode(
2019 (nWhich == RES_PAGEDESC || nWhich == RES_BREAK)
2020 ? m_pMergedPara->pFirstNode
2021 : m_pMergedPara->pParaPropsNode);
2022 if (pAttrNode != &rModify)
2023 {
2024 return;
2025 }
2026 }
2028 if( nWhich == RES_FMT_CHG && getRootFrame()->GetCurrShell() )
2029 {
2030 // collection has changed
2031 Prepare();
2033 lcl_SetWrong( *this, rNode, 0, COMPLETE_STRING, false );
2034 SetDerivedR2L( false );
2036 // Force complete paint due to existing indents.
2039 }
2040 return;
2041 }
2042
2043 if (m_pMergedPara && m_pMergedPara->pParaPropsNode != &rModify)
2044 {
2045 if (isPARATR(nWhich) || isPARATR_LIST(nWhich)) // FRMATR handled above
2046 {
2047 return; // ignore it
2048 }
2049 }
2050
2051 Broadcast(SfxHint()); // notify SwAccessibleParagraph
2052
2053 // while locked ignore all modifications
2054 if( IsLocked() )
2055 return;
2056
2057 // save stack
2058 // warning: one has to ensure that all variables are set
2060 TextFrameIndex nLen;
2061 bool bSetFieldsDirty = false;
2062 bool bRecalcFootnoteFlag = false;
2063
2064 if (pRedlineDelText)
2065 {
2066 if (m_pMergedPara)
2067 {
2068 sal_Int32 const nNPos = pRedlineDelText->nStart;
2069 sal_Int32 const nNLen = pRedlineDelText->nLen;
2070 nPos = MapModelToView(&rNode, nNPos);
2071 // update merged before doing anything else
2072 nLen = UpdateMergedParaForDelete(*m_pMergedPara, false, rNode, nNPos, nNLen);
2073 const sal_Int32 m = -nNLen;
2074 if (nLen && IsIdxInside(nPos, nLen))
2075 {
2077 }
2078 lcl_SetWrong( *this, rNode, nNPos, m, false );
2079 if (nLen)
2080 {
2081 lcl_SetScriptInval( *this, nPos );
2082 bSetFieldsDirty = bRecalcFootnoteFlag = true;
2083 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2084 }
2085 }
2086 }
2087 else if (pRedlineUnDelText)
2088 {
2089 if (m_pMergedPara)
2090 {
2091 sal_Int32 const nNPos = pRedlineUnDelText->nStart;
2092 sal_Int32 const nNLen = pRedlineUnDelText->nLen;
2093 nPos = MapModelToView(&rNode, nNPos);
2094 nLen = UpdateMergedParaForInsert(*m_pMergedPara, false, rNode, nNPos, nNLen);
2095 if (IsIdxInside(nPos, nLen))
2096 {
2097 if (!nLen)
2098 {
2099 // Refresh NumPortions even when line is empty!
2100 if (nPos)
2102 else
2103 Prepare();
2104 }
2105 else
2106 InvalidateRange_( SwCharRange( nPos, nLen ), nNLen );
2107 }
2108 lcl_SetWrong( *this, rNode, nNPos, nNLen, false );
2109 lcl_SetScriptInval( *this, nPos );
2110 bSetFieldsDirty = true;
2111 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator+<sal_Int32, Tag_TextFrameIndex>);
2112 }
2113 }
2114 else if (pMoveText)
2115 {
2116 if (m_pMergedPara
2117 && m_pMergedPara->pFirstNode->GetIndex() <= pMoveText->pDestNode->GetIndex()
2118 && pMoveText->pDestNode->GetIndex() <= m_pMergedPara->pLastNode->GetIndex())
2119 { // if it's not 2 nodes in merged frame, assume the target node doesn't have frames at all
2120 assert(abs(rNode.GetIndex() - pMoveText->pDestNode->GetIndex()) == SwNodeOffset(1));
2121 UpdateMergedParaForMove(*m_pMergedPara,
2122 *this,
2123 bRecalcFootnoteFlag,
2124 *pMoveText->pDestNode, rNode,
2125 pMoveText->nDestStart,
2126 pMoveText->nSourceStart,
2127 pMoveText->nLen);
2128 }
2129 else
2130 {
2131 // there is a situation where this is okay: from JoinNext, which will then call CheckResetRedlineMergeFlag, which will then create merged from scratch for this frame
2132 // assert(!m_pMergedPara || !getRootFrame()->IsHideRedlines() || !pMoveText->pDestNode->getLayoutFrame(getRootFrame()));
2133 }
2134 }
2135 else switch (nWhich)
2136 {
2137 case RES_LINENUMBER:
2138 {
2139 assert(false); // should have been forwarded to SwContentFrame
2141 }
2142 break;
2143 case RES_INS_TXT:
2144 {
2145 sal_Int32 const nNPos = static_cast<const SwInsText*>(pNew)->nPos;
2146 sal_Int32 const nNLen = static_cast<const SwInsText*>(pNew)->nLen;
2147 nPos = MapModelToView(&rNode, nNPos);
2148 // unlike redlines, inserting into fieldmark must be explicitly handled
2149 bool isHidden(false);
2150 switch (getRootFrame()->GetFieldmarkMode())
2151 {
2153 isHidden = static_cast<const SwInsText*>(pNew)->isInsideFieldmarkResult;
2154 break;
2156 isHidden = static_cast<const SwInsText*>(pNew)->isInsideFieldmarkCommand;
2157 break;
2158 case sw::FieldmarkMode::ShowBoth: // just to avoid the warning
2159 break;
2160 }
2161 if (!isHidden)
2162 {
2163 nLen = TextFrameIndex(nNLen);
2164 if (m_pMergedPara)
2165 {
2166 UpdateMergedParaForInsert(*m_pMergedPara, true, rNode, nNPos, nNLen);
2167 }
2168 if( IsIdxInside( nPos, nLen ) )
2169 {
2170 if( !nLen )
2171 {
2172 // Refresh NumPortions even when line is empty!
2173 if( nPos )
2175 else
2176 Prepare();
2177 }
2178 else
2179 InvalidateRange_( SwCharRange( nPos, nLen ), nNLen );
2180 }
2181 lcl_SetScriptInval( *this, nPos );
2182 bSetFieldsDirty = true;
2183 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator+<sal_Int32, Tag_TextFrameIndex>);
2184 }
2185 lcl_SetWrong( *this, rNode, nNPos, nNLen, true );
2186 }
2187 break;
2188 case RES_DEL_CHR:
2189 {
2190 sal_Int32 const nNPos = static_cast<const SwDelChr*>(pNew)->nPos;
2191 nPos = MapModelToView(&rNode, nNPos);
2192 if (m_pMergedPara)
2193 {
2194 nLen = UpdateMergedParaForDelete(*m_pMergedPara, true, rNode, nNPos, 1);
2195 }
2196 else
2197 {
2198 nLen = TextFrameIndex(1);
2199 }
2200 lcl_SetWrong( *this, rNode, nNPos, -1, true );
2201 if (nLen)
2202 {
2203 InvalidateRange( SwCharRange(nPos, nLen), -1 );
2204 lcl_SetScriptInval( *this, nPos );
2205 bSetFieldsDirty = bRecalcFootnoteFlag = true;
2206 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2207 }
2208 }
2209 break;
2210 case RES_DEL_TXT:
2211 {
2212 sal_Int32 const nNPos = static_cast<const SwDelText*>(pNew)->nStart;
2213 sal_Int32 const nNLen = static_cast<const SwDelText*>(pNew)->nLen;
2214 nPos = MapModelToView(&rNode, nNPos);
2215 if (m_pMergedPara)
2216 { // update merged before doing anything else
2217 nLen = UpdateMergedParaForDelete(*m_pMergedPara, true, rNode, nNPos, nNLen);
2218 }
2219 else
2220 {
2221 nLen = TextFrameIndex(nNLen);
2222 }
2223 const sal_Int32 m = -nNLen;
2224 if ((!m_pMergedPara || nLen) && IsIdxInside(nPos, nLen))
2225 {
2226 if( !nLen )
2228 else
2230 }
2231 lcl_SetWrong( *this, rNode, nNPos, m, true );
2232 if (nLen)
2233 {
2234 lcl_SetScriptInval( *this, nPos );
2235 bSetFieldsDirty = bRecalcFootnoteFlag = true;
2236 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2237 }
2238 }
2239 break;
2240 case RES_UPDATE_ATTR:
2241 {
2242 const SwUpdateAttr* pNewUpdate = static_cast<const SwUpdateAttr*>(pNew);
2243
2244 sal_Int32 const nNPos = pNewUpdate->getStart();
2245 sal_Int32 const nNLen = pNewUpdate->getEnd() - nNPos;
2246 nPos = MapModelToView(&rNode, nNPos);
2247 nLen = MapModelToView(&rNode, nNPos + nNLen) - nPos;
2248 if( IsIdxInside( nPos, nLen ) )
2249 {
2250 // We need to reformat anyways, even if the invalidated
2251 // range is empty.
2252 // E.g.: empty line, set 14 pt!
2253
2254 // FootnoteNumbers need to be formatted
2255 if( !nLen )
2256 nLen = TextFrameIndex(1);
2257
2259 const sal_uInt16 nTmp = pNewUpdate->getWhichAttr();
2260
2261 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_INETFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
2262 RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
2263 {
2264 lcl_SetWrong( *this, rNode, nNPos, nNPos + nNLen, false );
2265 lcl_SetScriptInval( *this, nPos );
2266 }
2267 }
2268
2269#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2270 if( isA11yRelevantAttribute( pNewUpdate->getWhichAttr() ) &&
2271 hasA11yRelevantAttribute( pNewUpdate->getFmtAttrs() ) )
2272 {
2273 SwViewShell* pViewSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2274 if ( pViewSh )
2275 {
2276 pViewSh->InvalidateAccessibleParaAttrs( *this );
2277 }
2278 }
2279#endif
2280 }
2281 break;
2282 case RES_OBJECTDYING:
2283 break;
2284
2286 {
2287 CalcLineSpace();
2290 if( IsInSct() && !GetPrev() )
2291 {
2292 SwSectionFrame *pSect = FindSctFrame();
2293 if( pSect->ContainsAny() == this )
2294 pSect->InvalidatePrt();
2295 }
2296
2297 // i#11859
2298 // (1) Also invalidate next frame on next page/column.
2299 // (2) Skip empty sections and hidden paragraphs
2300 // Thus, use method <InvalidateNextPrtArea()>
2302
2304 }
2305 break;
2306
2307 case RES_TXTATR_FIELD:
2309 {
2310 sal_Int32 const nNPos = static_cast<const SwFormatField*>(pNew)->GetTextField()->GetStart();
2311 nPos = MapModelToView(&rNode, nNPos);
2313 {
2314 if( pNew == pOld )
2315 {
2316 // only repaint
2317 // opt: invalidate window?
2320 }
2321 else
2323 }
2324 bSetFieldsDirty = true;
2325 // ST2
2326 if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
2327 lcl_SetWrong( *this, rNode, nNPos, nNPos + 1, false );
2328 }
2329 break;
2330
2331 case RES_TXTATR_FTN :
2332 {
2333 if (!IsInFootnote())
2334 { // the hint may be sent from the anchor node, or from a
2335 // node in the footnote; the anchor index is only valid in the
2336 // anchor node!
2337 assert(rNode == static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote()->GetTextNode());
2338 nPos = MapModelToView(&rNode,
2339 static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote()->GetStart());
2340 }
2341#ifdef _MSC_VER
2342 else nPos = TextFrameIndex(42); // shut up MSVC 2017 spurious warning C4701
2343#endif
2345 Prepare( PrepareHint::FootnoteInvalidation, static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote() );
2346 break;
2347 }
2348
2349 case RES_ATTRSET_CHG:
2350 {
2352
2353 const SwAttrSet& rNewSet = *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet();
2354 int nClear = 0;
2355 sal_uInt16 nCount = rNewSet.Count();
2356
2357 if( const SwFormatFootnote* pItem = rNewSet.GetItemIfSet( RES_TXTATR_FTN, false ) )
2358 {
2359 nPos = MapModelToView(&rNode, pItem->GetTextFootnote()->GetStart());
2362 nClear = 0x01;
2363 --nCount;
2364 }
2365
2366 if( const SwFormatField* pItem = rNewSet.GetItemIfSet( RES_TXTATR_FIELD, false ) )
2367 {
2368 nPos = MapModelToView(&rNode, pItem->GetTextField()->GetStart());
2370 {
2371 const SfxPoolItem* pOldItem = pOld ?
2372 &(static_cast<const SwAttrSetChg*>(pOld)->GetChgSet()->Get(RES_TXTATR_FIELD)) : nullptr;
2373 if( pItem == pOldItem )
2374 {
2377 }
2378 else
2380 }
2381 nClear |= 0x02;
2382 --nCount;
2383 }
2384 bool bLineSpace = SfxItemState::SET == rNewSet.GetItemState(
2385 RES_PARATR_LINESPACING, false ),
2386 bRegister = SfxItemState::SET == rNewSet.GetItemState(
2387 RES_PARATR_REGISTER, false );
2388 if ( bLineSpace || bRegister )
2389 {
2390 if (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2391 {
2393 CalcLineSpace();
2396
2397 // i#11859
2398 // (1) Also invalidate next frame on next page/column.
2399 // (2) Skip empty sections and hidden paragraphs
2400 // Thus, use method <InvalidateNextPrtArea()>
2402
2404 }
2405 nClear |= 0x04;
2406 if ( bLineSpace )
2407 {
2408 --nCount;
2409 if ((!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2410 && IsInSct() && !GetPrev())
2411 {
2412 SwSectionFrame *pSect = FindSctFrame();
2413 if( pSect->ContainsAny() == this )
2414 pSect->InvalidatePrt();
2415 }
2416 }
2417 if ( bRegister )
2418 --nCount;
2419 }
2420 if ( SfxItemState::SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
2421 false ))
2422 {
2423 if (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2424 {
2425 if (GetPrev())
2426 CheckKeep();
2427 Prepare();
2429 }
2430 nClear |= 0x08;
2431 --nCount;
2432 }
2433
2434 if( SfxItemState::SET == rNewSet.GetItemState( RES_BACKGROUND, false)
2435 && (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2436 && !IsFollow() && GetDrawObjs() )
2437 {
2438 SwSortedObjs *pObjs = GetDrawObjs();
2439 for ( size_t i = 0; GetDrawObjs() && i < pObjs->size(); ++i )
2440 {
2441 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
2442 if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
2443 {
2444 if( !pFly->IsFlyInContentFrame() )
2445 {
2446 const SvxBrushItem &rBack =
2447 pFly->GetAttrSet()->GetBackground();
2448 // #GetTransChg#
2449 // following condition determines, if the fly frame
2450 // "inherites" the background color of text frame.
2451 // This is the case, if fly frame background
2452 // color is "no fill"/"auto fill" and if the fly frame
2453 // has no background graphic.
2454 // Thus, check complete fly frame background
2455 // color and *not* only its transparency value
2456 if ( (rBack.GetColor() == COL_TRANSPARENT) &&
2457 rBack.GetGraphicPos() == GPOS_NONE )
2458 {
2459 pFly->SetCompletePaint();
2460 pFly->InvalidatePage();
2461 }
2462 }
2463 }
2464 }
2465 }
2466
2467 if ( SfxItemState::SET ==
2468 rNewSet.GetItemState( RES_TXTATR_CHARFMT, false ) )
2469 {
2470 lcl_SetWrong( *this, rNode, 0, COMPLETE_STRING, false );
2472 }
2473 else if ( SfxItemState::SET ==
2474 rNewSet.GetItemState( RES_CHRATR_LANGUAGE, false ) ||
2475 SfxItemState::SET ==
2476 rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, false ) ||
2477 SfxItemState::SET ==
2478 rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, false ) )
2479 lcl_SetWrong( *this, rNode, 0, COMPLETE_STRING, false );
2480 else if ( SfxItemState::SET ==
2481 rNewSet.GetItemState( RES_CHRATR_FONT, false ) ||
2482 SfxItemState::SET ==
2483 rNewSet.GetItemState( RES_CHRATR_CJK_FONT, false ) ||
2484 SfxItemState::SET ==
2485 rNewSet.GetItemState( RES_CHRATR_CTL_FONT, false ) )
2487 else if ( SfxItemState::SET ==
2488 rNewSet.GetItemState( RES_FRAMEDIR, false )
2489 && (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify))
2490 {
2491 SetDerivedR2L( false );
2493 // Force complete paint due to existing indents.
2495 }
2496
2497 if( nCount )
2498 {
2499 if( getRootFrame()->GetCurrShell() )
2500 {
2501 Prepare();
2503 }
2504
2505 if (nClear || (m_pMergedPara &&
2506 (m_pMergedPara->pParaPropsNode != &rModify ||
2507 m_pMergedPara->pFirstNode != &rModify)))
2508 {
2509 assert(pOld);
2510 SwAttrSetChg aOldSet( *static_cast<const SwAttrSetChg*>(pOld) );
2511 SwAttrSetChg aNewSet( *static_cast<const SwAttrSetChg*>(pNew) );
2512
2513 if (m_pMergedPara && m_pMergedPara->pParaPropsNode != &rModify)
2514 {
2515 for (sal_uInt16 i = RES_PARATR_BEGIN; i != RES_FRMATR_END; ++i)
2516 {
2517 if (i != RES_BREAK && i != RES_PAGEDESC)
2518 {
2519 aOldSet.ClearItem(i);
2520 aNewSet.ClearItem(i);
2521 }
2522 }
2523 for (sal_uInt16 i = XATTR_FILL_FIRST; i <= XATTR_FILL_LAST; ++i)
2524 {
2525 aOldSet.ClearItem(i);
2526 aNewSet.ClearItem(i);
2527 }
2528 }
2529 if (m_pMergedPara && m_pMergedPara->pFirstNode != &rModify)
2530 {
2531 aOldSet.ClearItem(RES_BREAK);
2532 aNewSet.ClearItem(RES_BREAK);
2533 aOldSet.ClearItem(RES_PAGEDESC);
2534 aNewSet.ClearItem(RES_PAGEDESC);
2535 }
2536
2537 if( 0x01 & nClear )
2538 {
2539 aOldSet.ClearItem( RES_TXTATR_FTN );
2540 aNewSet.ClearItem( RES_TXTATR_FTN );
2541 }
2542 if( 0x02 & nClear )
2543 {
2544 aOldSet.ClearItem( RES_TXTATR_FIELD );
2545 aNewSet.ClearItem( RES_TXTATR_FIELD );
2546 }
2547 if ( 0x04 & nClear )
2548 {
2549 if ( bLineSpace )
2550 {
2553 }
2554 if ( bRegister )
2555 {
2556 aOldSet.ClearItem( RES_PARATR_REGISTER );
2557 aNewSet.ClearItem( RES_PARATR_REGISTER );
2558 }
2559 }
2560 if ( 0x08 & nClear )
2561 {
2562 aOldSet.ClearItem( RES_PARATR_SPLIT );
2563 aNewSet.ClearItem( RES_PARATR_SPLIT );
2564 }
2565 if (aOldSet.Count() || aNewSet.Count())
2566 {
2567 SwContentFrame::SwClientNotify(rModify, sw::LegacyModifyHint(&aOldSet, &aNewSet));
2568 }
2569 }
2570 else
2572 }
2573
2574#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2575 if (isA11yRelevantAttribute(nWhich))
2576 {
2577 SwViewShell* pViewSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2578 if ( pViewSh )
2579 {
2580 pViewSh->InvalidateAccessibleParaAttrs( *this );
2581 }
2582 }
2583#endif
2584 }
2585 break;
2586
2587 // Process SwDocPosUpdate
2588 case RES_DOCPOS_UPDATE:
2589 {
2590 if( pOld && pNew )
2591 {
2592 const SwDocPosUpdate *pDocPos = static_cast<const SwDocPosUpdate*>(pOld);
2593 if( pDocPos->nDocPos <= getFrameArea().Top() )
2594 {
2595 const SwFormatField *pField = static_cast<const SwFormatField *>(pNew);
2597 pField->GetTextField()->GetStart()));
2599 }
2600 }
2601 break;
2602 }
2603 case RES_PARATR_SPLIT:
2604 if ( GetPrev() )
2605 CheckKeep();
2606 Prepare();
2607 bSetFieldsDirty = true;
2608 break;
2609 case RES_FRAMEDIR :
2610 assert(false); // should have been forwarded to SwContentFrame
2611 SetDerivedR2L( false );
2613 break;
2614 default:
2615 {
2616 Prepare();
2618 if ( !nWhich )
2619 {
2620 // is called by e. g. HiddenPara with 0
2621 SwFrame *pNxt = FindNext();
2622 if ( nullptr != pNxt )
2623 pNxt->InvalidatePrt();
2624 }
2625 }
2626 } // switch
2627
2628 if( bSetFieldsDirty )
2630
2631 if ( bRecalcFootnoteFlag )
2633}
2634
2636{
2637 if ( RES_VIRTPAGENUM_INFO == rHint.Which() && IsInDocBody() && ! IsFollow() )
2638 {
2639 SwVirtPageNumInfo &rInfo = static_cast<SwVirtPageNumInfo&>(rHint);
2640 const SwPageFrame *pPage = FindPageFrame();
2641 if ( pPage )
2642 {
2643 if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
2644 {
2645 // this should be the one
2646 // (could only differ temporarily; is that disturbing?)
2647 rInfo.SetInfo( pPage, this );
2648 return false;
2649 }
2650 if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
2651 (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
2652 {
2653 // this could be the one
2654 rInfo.SetInfo( pPage, this );
2655 }
2656 }
2657 }
2658 return true;
2659}
2660
2661void SwTextFrame::PrepWidows( const sal_uInt16 nNeed, bool bNotify )
2662{
2663 OSL_ENSURE(GetFollow() && nNeed, "+SwTextFrame::Prepare: lost all friends");
2664
2665 SwParaPortion *pPara = GetPara();
2666 if ( !pPara )
2667 return;
2668 pPara->SetPrepWidows();
2669
2670 sal_uInt16 nHave = nNeed;
2671
2672 // We yield a few lines and shrink in CalcPreps()
2673 SwSwapIfNotSwapped swap( this );
2674
2675 SwTextSizeInfo aInf( this );
2676 SwTextMargin aLine( this, &aInf );
2677 aLine.Bottom();
2678 TextFrameIndex nTmpLen = aLine.GetCurr()->GetLen();
2679 while( nHave && aLine.PrevLine() )
2680 {
2681 if( nTmpLen )
2682 --nHave;
2683 nTmpLen = aLine.GetCurr()->GetLen();
2684 }
2685
2686 // If it's certain that we can yield lines, the Master needs
2687 // to check the widow rule
2688 if( !nHave )
2689 {
2690 bool bSplit = true;
2691 if( !IsFollow() ) // only a master decides about orphans
2692 {
2693 const WidowsAndOrphans aWidOrp( this );
2694 bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
2695 aLine.GetLineNr() >= aLine.GetDropLines() );
2696 }
2697
2698 if( bSplit )
2699 {
2700 GetFollow()->SetOffset( aLine.GetEnd() );
2701 aLine.TruncLines( true );
2702 if( pPara->IsFollowField() )
2703 GetFollow()->SetFieldFollow( true );
2704 }
2705 }
2706 if ( bNotify )
2707 {
2710 }
2711}
2712
2713static bool lcl_ErgoVadis(SwTextFrame* pFrame, TextFrameIndex & rPos, const PrepareHint ePrep)
2714{
2715 const SwFootnoteInfo &rFootnoteInfo = pFrame->GetDoc().GetFootnoteInfo();
2716 if( ePrep == PrepareHint::ErgoSum )
2717 {
2718 if( rFootnoteInfo.m_aErgoSum.isEmpty() )
2719 return false;
2720 rPos = pFrame->GetOffset();
2721 }
2722 else
2723 {
2724 if( rFootnoteInfo.m_aQuoVadis.isEmpty() )
2725 return false;
2726 if( pFrame->HasFollow() )
2727 rPos = pFrame->GetFollow()->GetOffset();
2728 else
2729 rPos = TextFrameIndex(pFrame->GetText().getLength());
2730 if( rPos )
2731 --rPos; // our last character
2732 }
2733 return true;
2734}
2735
2736// Silence over-eager warning emitted at least by GCC 5.3.1
2737#if defined __GNUC__ && !defined __clang__
2738# pragma GCC diagnostic push
2739# pragma GCC diagnostic ignored "-Wstrict-overflow"
2740#endif
2741bool SwTextFrame::Prepare( const PrepareHint ePrep, const void* pVoid,
2742 bool bNotify )
2743{
2744 bool bParaPossiblyInvalid = false;
2745
2746 SwFrameSwapper aSwapper( this, false );
2747
2748 if ( IsEmpty() )
2749 {
2750 switch ( ePrep )
2751 {
2753 SetInvalidVert( true ); // Test
2754 [[fallthrough]];
2757 case PrepareHint::FootnoteInvalidationGone : return bParaPossiblyInvalid;
2758
2760 {
2761 // We also need an InvalidateSize for Areas (with and without columns),
2762 // so that we format and bUndersized is set (if needed)
2763 if( IsInFly() || IsInSct() )
2764 {
2765 SwTwips nTmpBottom = GetUpper()->getFrameArea().Top() +
2767 if( nTmpBottom < getFrameArea().Bottom() )
2768 break;
2769 }
2770 // Are there any free-flying frames on this page?
2771 SwTextFly aTextFly( this );
2772 if( aTextFly.IsOn() )
2773 {
2774 // Does any free-flying frame overlap?
2775 if ( aTextFly.Relax() || IsUndersized() )
2776 break;
2777 }
2778 if (GetTextNodeForParaProps()->GetSwAttrSet().GetRegister().GetValue())
2779 break;
2780
2781 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrame()));
2782 if (pGrid && GetTextNodeForParaProps()->GetSwAttrSet().GetParaGrid().GetValue())
2783 break;
2784
2785 // i#28701 - consider anchored objects
2786 if ( GetDrawObjs() )
2787 break;
2788
2789 return bParaPossiblyInvalid;
2790 }
2791 default:
2792 break;
2793 }
2794 }
2795
2796 if( !HasPara() && PrepareHint::MustFit != ePrep )
2797 {
2798 SetInvalidVert( true ); // Test
2799 OSL_ENSURE( !IsLocked(), "SwTextFrame::Prepare: three of a perfect pair" );
2800 if ( bNotify )
2802 else
2804 return bParaPossiblyInvalid;
2805 }
2806
2807 // Get object from cache while locking
2808 SwTextLineAccess aAccess( this );
2809 SwParaPortion *pPara = aAccess.GetPara();
2810
2811 switch( ePrep )
2812 {
2814 {
2816 aFrm.Height(0);
2817 }
2818
2819 {
2821 aPrt.Height(0);
2822 }
2823
2826 [[fallthrough]];
2828 pPara->SetPrepAdjust();
2829 if( IsFootnoteNumFrame() != pPara->IsFootnoteNum() ||
2830 IsUndersized() )
2831 {
2833 if( GetOffset() && !IsFollow() )
2835 }
2836 break;
2838 pPara->SetPrepMustFit(true);
2839 [[fallthrough]];
2841 pPara->SetPrepAdjust();
2842 break;
2843 case PrepareHint::Widows :
2844 // MustFit is stronger than anything else
2845 if( pPara->IsPrepMustFit() )
2846 return bParaPossiblyInvalid;
2847 // see comment in WidowsAndOrphans::FindOrphans and CalcPreps()
2848 PrepWidows( *static_cast<const sal_uInt16 *>(pVoid), bNotify );
2849 break;
2850
2852 {
2853 SwTextFootnote const *pFootnote = static_cast<SwTextFootnote const *>(pVoid);
2854 if( IsInFootnote() )
2855 {
2856 // Am I the first TextFrame of a footnote?
2857 if( !GetPrev() )
2858 // So we're a TextFrame of the footnote, which has
2859 // to display the footnote number or the ErgoSum text
2861
2862 if( !GetNext() )
2863 {
2864 // We're the last Footnote; we need to update the
2865 // QuoVadis texts now
2866 const SwFootnoteInfo &rFootnoteInfo = GetDoc().GetFootnoteInfo();
2867 if( !pPara->UpdateQuoVadis( rFootnoteInfo.m_aQuoVadis ) )
2868 {
2869 TextFrameIndex nPos = pPara->GetParLen();
2870 if( nPos )
2871 --nPos;
2873 }
2874 }
2875 }
2876 else
2877 {
2878 // We are the TextFrame _with_ the footnote
2880 &pFootnote->GetTextNode(), pFootnote->GetStart());
2882 }
2883 break;
2884 }
2886 {
2887 // Test
2888 {
2889 SetInvalidVert( false );
2890 bool bOld = IsVertical();
2891 SetInvalidVert( true );
2892 if( bOld != IsVertical() )
2894 }
2895
2896 if( HasFollow() )
2897 {
2898 TextFrameIndex nNxtOfst = GetFollow()->GetOffset();
2899 if( nNxtOfst )
2900 --nNxtOfst;
2901 InvalidateRange(SwCharRange( nNxtOfst, TextFrameIndex(1)), 1);
2902 }
2903 if( IsInFootnote() )
2904 {
2910 }
2911 // If we have a page number field, we must invalidate those spots
2912 SwTextNode const* pNode(nullptr);
2913 sw::MergedAttrIter iter(*this);
2914 TextFrameIndex const nEnd = GetFollow()
2916 for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
2917 {
2918 TextFrameIndex const nStart(MapModelToView(pNode, pHt->GetStart()));
2919 if (nStart >= GetOffset())
2920 {
2921 if (nStart >= nEnd)
2922 break;
2923
2924 // If we're flowing back and own a Footnote, the Footnote also flows
2925 // with us. So that it doesn't obstruct us, we send ourselves
2926 // an ADJUST_FRM.
2927 // pVoid != 0 means MoveBwd()
2928 const sal_uInt16 nWhich = pHt->Which();
2929 if (RES_TXTATR_FIELD == nWhich ||
2930 (HasFootnote() && pVoid && RES_TXTATR_FTN == nWhich))
2932 }
2933 }
2934 // A new boss, a new chance for growing
2935 if( IsUndersized() )
2936 {
2939 }
2940 break;
2941 }
2942
2944 {
2945 if ( isFramePrintAreaValid() )
2946 {
2947 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrame()));
2948 if (pGrid && GetTextNodeForParaProps()->GetSwAttrSet().GetParaGrid().GetValue())
2949 InvalidatePrt();
2950 }
2951
2952 // If we don't overlap with anybody:
2953 // did any free-flying frame overlapped _before_ the position change?
2954 bool bFormat = pPara->HasFly();
2955 if( !bFormat )
2956 {
2957 if( IsInFly() )
2958 {
2959 SwTwips nTmpBottom = GetUpper()->getFrameArea().Top() +
2961 if( nTmpBottom < getFrameArea().Bottom() )
2962 bFormat = true;
2963 }
2964 if( !bFormat )
2965 {
2966 if ( GetDrawObjs() )
2967 {
2968 const size_t nCnt = GetDrawObjs()->size();
2969 for ( size_t i = 0; i < nCnt; ++i )
2970 {
2971 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2972 // i#28701 - consider all
2973 // to-character anchored objects
2974 if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId()
2975 == RndStdIds::FLY_AT_CHAR )
2976 {
2977 bFormat = true;
2978 break;
2979 }
2980 }
2981 }
2982 if( !bFormat )
2983 {
2984 // Are there any free-flying frames on this page?
2985 SwTextFly aTextFly( this );
2986 if( aTextFly.IsOn() )
2987 {
2988 // Does any free-flying frame overlap?
2989 const bool bRelaxed = aTextFly.Relax();
2990 bFormat = bRelaxed || IsUndersized();
2991 if (bRelaxed)
2992 {
2993 // It's possible that pPara was deleted above; retrieve it again
2994 pPara = aAccess.GetPara();
2995 }
2996 }
2997 }
2998 }
2999 }
3000
3001 if( bFormat )
3002 {
3003 if( !IsLocked() )
3004 {
3005 if( pPara->GetRepaint().HasArea() )
3007 Init();
3008 pPara = nullptr;
3010 }
3011 }
3012 else
3013 {
3014 if (GetTextNodeForParaProps()->GetSwAttrSet().GetRegister().GetValue())
3015 bParaPossiblyInvalid = Prepare( PrepareHint::Register, nullptr, bNotify );
3016 // The Frames need to be readjusted, which caused by changes
3017 // in position
3018 else if( HasFootnote() )
3019 {
3020 bParaPossiblyInvalid = Prepare( PrepareHint::AdjustSizeWithoutFormatting, nullptr, bNotify );
3022 }
3023 else
3024 return bParaPossiblyInvalid; // So that there's no SetPrep()
3025
3026 if (bParaPossiblyInvalid)
3027 {
3028 // It's possible that pPara was deleted above; retrieve it again
3029 pPara = aAccess.GetPara();
3030 }
3031
3032 }
3033 break;
3034 }
3036 if (GetTextNodeForParaProps()->GetSwAttrSet().GetRegister().GetValue())
3037 {
3038 pPara->SetPrepAdjust();
3039 CalcLineSpace();
3040
3041 // It's possible that pPara was deleted above; retrieve it again
3042 bParaPossiblyInvalid = true;
3043 pPara = aAccess.GetPara();
3044
3047 SwFrame* pNxt = GetIndNext();
3048 if ( nullptr != pNxt )
3049 {
3050 pNxt->InvalidatePrt_();
3051 if ( pNxt->IsLayoutFrame() )
3052 pNxt->InvalidatePage();
3053 }
3055 }
3056 break;
3058 {
3059 // If a Follow is calling us, because a footnote is being deleted, our last
3060 // line has to be formatted, so that the first line of the Follow can flow up.
3061 // Which had flowed to the next page to be together with the footnote (this is
3062 // especially true for areas with columns)
3063 OSL_ENSURE( GetFollow(), "PrepareHint::FootnoteInvalidationGone may only be called by Follow" );
3065 if( IsFollow() && GetOffset() == nPos ) // If we don't have a mass of text, we call our
3067 if( nPos )
3068 --nPos; // The char preceding our Follow
3070 return bParaPossiblyInvalid;
3071 }
3074 {
3076 if( lcl_ErgoVadis( this, nPos, ePrep ) )
3078 }
3079 break;
3081 {
3082 if( pVoid )
3083 {
3084 TextFrameIndex const nWhere = CalcFlyPos( static_cast<SwFrameFormat const *>(pVoid) );
3085 OSL_ENSURE( TextFrameIndex(COMPLETE_STRING) != nWhere, "Prepare: Why me?" );
3087 return bParaPossiblyInvalid;
3088 }
3089 [[fallthrough]]; // else: continue with default case block
3090 }
3091 case PrepareHint::Clear:
3092 default:
3093 {
3094 if( IsLocked() )
3095 {
3097 {
3098 TextFrameIndex const nLen = (GetFollow()
3099 ? GetFollow()->GetOffset()
3101 - GetOffset();
3103 }
3104 }
3105 else
3106 {
3107 if( pPara->GetRepaint().HasArea() )
3109 Init();
3110 pPara = nullptr;
3111 if( GetOffset() && !IsFollow() )
3113 if ( bNotify )
3115 else
3117 }
3118 return bParaPossiblyInvalid; // no SetPrep() happened
3119 }
3120 }
3121 if( pPara )
3122 {
3123 pPara->SetPrep();
3124 }
3125
3126 return bParaPossiblyInvalid;
3127}
3128#if defined __GNUC__ && !defined __clang__
3129# pragma GCC diagnostic pop
3130#endif
3131
3141{
3145public:
3146 SwTestFormat( SwTextFrame* pTextFrame, const SwFrame* pPrv, SwTwips nMaxHeight );
3147 ~SwTestFormat();
3148};
3149
3150SwTestFormat::SwTestFormat( SwTextFrame* pTextFrame, const SwFrame* pPre, SwTwips nMaxHeight )
3151 : pFrame( pTextFrame )
3152{
3155
3156 SwRectFnSet aRectFnSet(pFrame);
3157 SwTwips nLower = aRectFnSet.GetBottomMargin(*pFrame);
3158
3159 {
3160 // indeed, here the GetUpper()->getFramePrintArea() gets copied and manipulated
3163 aFrm += pFrame->GetUpper()->getFrameArea().Pos();
3164 aRectFnSet.SetHeight( aFrm, nMaxHeight );
3165
3166 if( pFrame->GetPrev() )
3167 {
3168 aRectFnSet.SetPosY(
3169 aFrm,
3170 aRectFnSet.GetBottom(pFrame->GetPrev()->getFrameArea()) - ( aRectFnSet.IsVert() ? nMaxHeight + 1 : 0 ) );
3171 }
3172 }
3173
3175 const SwBorderAttrs &rAttrs = *aAccess.Get();
3176
3177 {
3179 aRectFnSet.SetPosX(aPrt, rAttrs.CalcLeft( pFrame ) );
3180 }
3181
3182 if( pPre )
3183 {
3184 SwTwips nUpper = pFrame->CalcUpperSpace( &rAttrs, pPre );
3186 aRectFnSet.SetPosY(aPrt, nUpper );
3187 }
3188
3189 {
3191 aRectFnSet.SetHeight( aPrt, std::max( tools::Long(0) , aRectFnSet.GetHeight(pFrame->getFrameArea()) - aRectFnSet.GetTop(aPrt) - nLower ) );
3192 aRectFnSet.SetWidth( aPrt, aRectFnSet.GetWidth(pFrame->getFrameArea()) - ( rAttrs.CalcLeft( pFrame ) + rAttrs.CalcRight( pFrame ) ) );
3193 }
3194
3195 pOldPara = pFrame->HasPara() ? pFrame->GetPara() : nullptr;
3196 pFrame->SetPara( new SwParaPortion(), false );
3197 OSL_ENSURE( ! pFrame->IsSwapped(), "A frame is swapped before Format_" );
3198
3199 if ( pFrame->IsVertical() )
3201
3202 SwTextFormatInfo aInf( pFrame->getRootFrame()->GetCurrShell()->GetOut(), pFrame, false, true, true );
3203 SwTextFormatter aLine( pFrame, &aInf );
3204
3205 pFrame->Format_( aLine, aInf );
3206
3207 if ( pFrame->IsVertical() )
3209
3210 OSL_ENSURE( ! pFrame->IsSwapped(), "A frame is swapped after Format_" );
3211}
3212
3214{
3215 {
3217 aFrm.setSwRect(aOldFrame);
3218 }
3219
3220 {
3222 aPrt.setSwRect(aOldPrt);
3223 }
3224
3226}
3227
3228bool SwTextFrame::TestFormat( const SwFrame* pPrv, SwTwips &rMaxHeight, bool &bSplit )
3229{
3231
3232 if( IsLocked() && GetUpper()->getFramePrintArea().Width() <= 0 )
3233 return false;
3234
3235 SwTestFormat aSave( this, pPrv, rMaxHeight );
3236
3237 return SwTextFrame::WouldFit( rMaxHeight, bSplit, true );
3238}
3239
3252bool SwTextFrame::WouldFit( SwTwips &rMaxHeight, bool &bSplit, bool bTst )
3253{
3254 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
3255 "SwTextFrame::WouldFit with swapped frame" );
3256 SwRectFnSet aRectFnSet(this);
3257
3258 if( IsLocked() )
3259 return false;
3260
3261 // it can happen that the IdleCollector removed the cached information
3262 if( !IsEmpty() )
3263 GetFormatted();
3264
3265 // i#27801 - correction: 'short cut' for empty paragraph
3266 // can *not* be applied, if test format is in progress. The test format doesn't
3267 // adjust the frame and the printing area - see method <SwTextFrame::Format_(..)>,
3268 // which is called in <SwTextFrame::TestFormat(..)>
3269 if ( IsEmpty() && !bTst )
3270 {
3271 bSplit = false;
3272 SwTwips nHeight = aRectFnSet.IsVert() ? getFramePrintArea().SSize().Width() : getFramePrintArea().SSize().Height();
3273 if( rMaxHeight < nHeight )
3274 return false;
3275 else
3276 {
3277 rMaxHeight -= nHeight;
3278 return true;
3279 }
3280 }
3281
3282 // GetPara can still be 0 in edge cases
3283 // We return true in order to be reformatted on the new Page
3284 OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
3285 if( !HasPara() || ( !aRectFnSet.GetHeight(getFrameArea()) && IsHiddenNow() ) )
3286 return true;
3287
3288 // Because the Orphan flag only exists for a short moment, we also check
3289 // whether the Framesize is set to very huge by CalcPreps, in order to
3290 // force a MoveFwd
3291 if (IsWidow() || (aRectFnSet.IsVert()
3292 ? (0 == getFrameArea().Left())
3293 : (sw::WIDOW_MAGIC - 20000 < getFrameArea().Bottom())))
3294 {
3295 SetWidow(false);
3296 if ( GetFollow() )
3297 {
3298 // If we've ended up here due to a Widow request by our Follow, we check
3299 // whether there's a Follow with a real height at all.
3300 // Else (e.g. for newly created SctFrames) we ignore the IsWidow() and
3301 // still check if we can find enough room
3302 if (((!aRectFnSet.IsVert() && getFrameArea().Bottom() <= sw::WIDOW_MAGIC - 20000) ||
3303 ( aRectFnSet.IsVert() && 0 < getFrameArea().Left() ) ) &&
3304 ( GetFollow()->IsVertical() ?
3305 !GetFollow()->getFrameArea().Width() :
3306 !GetFollow()->getFrameArea().Height() ) )
3307 {
3308 SwTextFrame* pFoll = GetFollow()->GetFollow();
3309 while( pFoll &&
3310 ( pFoll->IsVertical() ?
3311 !pFoll->getFrameArea().Width() :
3312 !pFoll->getFrameArea().Height() ) )
3313 pFoll = pFoll->GetFollow();
3314 if( pFoll )
3315 return false;
3316 }
3317 else
3318 return false;
3319 }
3320 }
3321
3322 SwSwapIfNotSwapped swap( this );
3323
3324 SwTextSizeInfo aInf( this );
3325 SwTextMargin aLine( this, &aInf );
3326
3327 WidowsAndOrphans aFrameBreak( this, rMaxHeight, bSplit );
3328
3329 bool bRet = true;
3330
3331 aLine.Bottom();
3332 // is breaking necessary?
3333 bSplit = !aFrameBreak.IsInside( aLine );
3334 if ( bSplit )
3335 bRet = !aFrameBreak.IsKeepAlways() && aFrameBreak.WouldFit( aLine, rMaxHeight, bTst );
3336 else
3337 {
3338 // we need the total height including the current line
3339 aLine.Top();
3340 do
3341 {
3342 rMaxHeight -= aLine.GetLineHeight();
3343 } while ( aLine.Next() );
3344 }
3345
3346 return bRet;
3347}
3348
3350{
3351 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
3352 "SwTextFrame::GetParHeight with swapped frame" );
3353
3354 if( !HasPara() )
3355 { // For non-empty paragraphs this is a special case
3356 // For UnderSized we can simply just ask 1 Twip more
3357 sal_uInt16 nRet = o3tl::narrowing<sal_uInt16>(getFramePrintArea().SSize().Height());
3358 if( IsUndersized() )
3359 {
3360 if( IsEmpty() || GetText().isEmpty() )
3361 nRet = o3tl::narrowing<sal_uInt16>(EmptyHeight());
3362 else
3363 ++nRet;
3364 }
3365 return nRet;
3366 }
3367
3368 // TODO: Refactor and improve code
3369 const SwLineLayout* pLineLayout = GetPara();
3370 SwTwips nHeight = pLineLayout ? pLineLayout->GetRealHeight() : 0;
3371
3372 // Is this paragraph scrolled? Our height until now is at least
3373 // one line height too low then
3374 if( GetOffset() && !IsFollow() )
3375 nHeight *= 2;
3376
3377 while ( pLineLayout && pLineLayout->GetNext() )
3378 {
3379 pLineLayout = pLineLayout->GetNext();
3380 nHeight = nHeight + pLineLayout->GetRealHeight();
3381 }
3382
3383 return nHeight;
3384}
3385
3389SwTextFrame* SwTextFrame::GetFormatted( bool bForceQuickFormat )
3390{
3391 vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
3392 SwSwapIfSwapped swap( this );
3393
3394 // In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
3395 // Not for empty paragraphs
3396 if( !HasPara() && !(isFrameAreaDefinitionValid() && IsEmpty()) )
3397 {
3398 // Calc() must be called, because frame position can be wrong
3399 const bool bFormat = isFrameAreaSizeValid();
3400 Calc(pRenderContext); // calls Format() if invalid
3401
3402 // If the flags were valid (hence bFormat=true), Calc did nothing,
3403 // so Format() must be called manually in order to recreate
3404 // the SwLineLayout that has been deleted from the
3405 // SwTextFrame::s_pTextCache (hence !HasPara() above).
3406 // Optimization with FormatQuick()
3407 if( bFormat && !FormatQuick( bForceQuickFormat ) )
3408 Format(getRootFrame()->GetCurrShell()->GetOut());
3409 }
3410
3411 return this;
3412}
3413
3415{
3416 // i#31490
3417 // If we are currently locked, we better return with a
3418 // fairly reasonable value:
3419 if ( IsLocked() )
3420 return getFramePrintArea().Width();
3421
3422 SwParaPortion* pOldPara = GetPara();
3423 SwParaPortion *pDummy = new SwParaPortion();
3424 SetPara( pDummy, false );
3425 const SwPageFrame* pPage = FindPageFrame();
3426
3427 const Point aOldFramePos = getFrameArea().Pos();
3428 const SwTwips nOldFrameWidth = getFrameArea().Width();
3429 const SwTwips nOldPrtWidth = getFramePrintArea().Width();
3430 const SwTwips nPageWidth = GetUpper()->IsVertical() ?
3431 pPage->getFramePrintArea().Height() :
3432 pPage->getFramePrintArea().Width();
3433
3434 {
3436 aFrm.Width( nPageWidth );
3437 }
3438
3439 {
3441 aPrt.Width( nPageWidth );
3442 }
3443
3444 // i#25422 objects anchored as character in RTL
3445 if ( IsRightToLeft() )
3446 {
3448 aFrm.Pos().AdjustX(nOldFrameWidth - nPageWidth );
3449 }
3450
3451 TextFrameLockGuard aLock( this );
3452
3453 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this, false, true, true );
3454 aInf.SetIgnoreFly( true );
3455 SwTextFormatter aLine( this, &aInf );
3456 SwHookOut aHook( aInf );
3457
3458 // i#54031 - assure minimum of MINLAY twips.
3459 const SwTwips nMax = std::max( SwTwips(MINLAY), aLine.CalcFitToContent_() + 1 );
3460
3461 {
3463 aFrm.Width( nOldFrameWidth );
3464
3465 // i#25422 objects anchored as character in RTL
3466 if ( IsRightToLeft() )
3467 {
3468 aFrm.Pos() = aOldFramePos;
3469 }
3470 }
3471
3472 {
3474 aPrt.Width( nOldPrtWidth );
3475 }
3476
3477 SetPara( pOldPara );
3478
3479 return nMax;
3480}
3481
3489{
3490 if ( IsLocked() )
3491 return;
3492
3493 // reset additional first line offset
3495
3496 const SwTextNode* pTextNode( GetTextNodeForParaProps() );
3497 // sw_redlinehide: check that pParaPropsNode is the correct one
3498 assert(pTextNode->IsNumbered(getRootFrame()) == pTextNode->IsNumbered(nullptr));
3499 if (!(pTextNode->IsNumbered(getRootFrame()) &&
3500 pTextNode->IsCountedInList() && pTextNode->GetNumRule()))
3501 return;
3502
3503 int nListLevel = pTextNode->GetActualListLevel();
3504
3505 if (nListLevel < 0)
3506 nListLevel = 0;
3507
3508 if (nListLevel >= MAXLEVEL)
3509 nListLevel = MAXLEVEL - 1;
3510
3511 const SwNumFormat& rNumFormat =
3512 pTextNode->GetNumRule()->Get( o3tl::narrowing<sal_uInt16>(nListLevel) );
3514 return;
3515
3516 // keep current paragraph portion and apply dummy paragraph portion
3517 SwParaPortion* pOldPara = GetPara();
3518 SwParaPortion *pDummy = new SwParaPortion();
3519 SetPara( pDummy, false );
3520
3521 // lock paragraph
3522 TextFrameLockGuard aLock( this );
3523
3524 // simulate text formatting
3525 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this, false, true, true );
3526 aInf.SetIgnoreFly( true );
3527 SwTextFormatter aLine( this, &aInf );
3528 SwHookOut aHook( aInf );
3529 aLine.CalcFitToContent_();
3530
3531 // determine additional first line offset
3532 const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
3533 if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFootnoteNumPortion() )
3534 {
3535 SwTwips nNumberPortionWidth( pFirstPortion->Width() );
3536
3537 const SwLinePortion* pPortion = pFirstPortion->GetNextPortion();
3538 while ( pPortion &&
3539 pPortion->InNumberGrp() && !pPortion->IsFootnoteNumPortion())
3540 {
3541 nNumberPortionWidth += pPortion->Width();
3542 pPortion = pPortion->GetNextPortion();
3543 }
3544
3545 if ( ( IsRightToLeft() &&
3546 rNumFormat.GetNumAdjust() == SvxAdjust::Left ) ||
3547 ( !IsRightToLeft() &&
3548 rNumFormat.GetNumAdjust() == SvxAdjust::Right ) )
3549 {
3550 mnAdditionalFirstLineOffset = -nNumberPortionWidth;
3551 }
3552 else if ( rNumFormat.GetNumAdjust() == SvxAdjust::Center )
3553 {
3554 mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
3555 }
3556 }
3557
3558 // restore paragraph portion
3559 SetPara( pOldPara );
3560}
3561
3574void SwTextFrame::CalcHeightOfLastLine( const bool _bUseFont )
3575{
3576 // i#71281
3577 // Invalidate printing area, if height of last line changes
3578 const SwTwips nOldHeightOfLastLine( mnHeightOfLastLine );
3579
3580 // determine output device
3582 OSL_ENSURE( pVsh, "<SwTextFrame::_GetHeightOfLastLineForPropLineSpacing()> - no SwViewShell" );
3583
3584 // i#78921
3585 // There could be no <SwViewShell> instance in the case of loading a binary
3586 // StarOffice file format containing an embedded Writer document.
3587 if ( !pVsh )
3588 {
3589 return;
3590 }
3591 OutputDevice* pOut = pVsh->GetOut();
3593 if ( !pVsh->GetViewOptions()->getBrowseMode() ||
3594 pVsh->GetViewOptions()->IsPrtFormat() )
3595 {
3597 }
3598 OSL_ENSURE( pOut, "<SwTextFrame::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
3599
3600 if ( !pOut )
3601 {
3602 return;
3603 }
3604
3605 // determine height of last line
3606 if ( _bUseFont || pIDSA->get(DocumentSettingId::OLD_LINE_SPACING ) )
3607 {
3608 // former determination of last line height for proportional line
3609 // spacing - take height of font set at the paragraph
3610 // FIXME actually... must the font match across all nodes?
3611 SwFont aFont( &GetTextNodeForParaProps()->GetSwAttrSet(), pIDSA );
3612
3613 // we must ensure that the font is restored correctly on the OutputDevice
3614 // otherwise Last!=Owner could occur
3615 if ( pLastFont )
3616 {
3617 SwFntObj *pOldFont = pLastFont;
3618 pLastFont = nullptr;
3619 aFont.SetFntChg( true );
3620 aFont.ChgPhysFnt( pVsh, *pOut );
3621 mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
3622 assert(pLastFont && "coverity[var_deref_model] - pLastFont should be set in SwSubFont::ChgFnt");
3623 pLastFont->Unlock();
3624 pLastFont = pOldFont;
3625 pLastFont->SetDevFont( pVsh, *pOut );
3626 }
3627 else
3628 {
3629 vcl::Font aOldFont = pOut->GetFont();
3630 aFont.SetFntChg( true );
3631 aFont.ChgPhysFnt( pVsh, *pOut );
3632 mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
3633 assert(pLastFont && "coverity[var_deref_model] - pLastFont should be set in SwSubFont::ChgFnt");
3634 pLastFont->Unlock();
3635 pLastFont = nullptr;
3636 pOut->SetFont( aOldFont );
3637 }
3638 }
3639 else
3640 {
3641 // new determination of last line height - take actually height of last line
3642 // i#89000
3643 // assure same results, if paragraph is undersized
3644 if ( IsUndersized() )
3645 {
3647 }
3648 else
3649 {
3650 bool bCalcHeightOfLastLine = true;
3651 if ( ( !HasPara() && IsEmpty( ) ) || GetText().isEmpty() )
3652 {
3654 bCalcHeightOfLastLine = false;
3655 }
3656
3657 if ( bCalcHeightOfLastLine )
3658 {
3659 OSL_ENSURE( HasPara(),
3660 "<SwTextFrame::CalcHeightOfLastLine()> - missing paragraph portions." );
3661 const SwLineLayout* pLineLayout = GetPara();
3662 while ( pLineLayout && pLineLayout->GetNext() )
3663 {
3664 // iteration to last line
3665 pLineLayout = pLineLayout->GetNext();
3666 }
3667 if ( pLineLayout )
3668 {
3669 SwTwips nAscent, nDescent, nDummy1, nDummy2;
3670 // i#47162 - suppress consideration of
3671 // fly content portions and the line portion.
3672 pLineLayout->MaxAscentDescent( nAscent, nDescent,
3673 nDummy1, nDummy2,
3674 nullptr, true );
3675 // i#71281
3676 // Suppress wrong invalidation of printing area, if method is
3677 // called recursive.
3678 // Thus, member <mnHeightOfLastLine> is only set directly, if
3679 // no recursive call is needed.
3680 const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
3681 // i#47162 - if last line only contains
3682 // fly content portions, <mnHeightOfLastLine> is zero.
3683 // In this case determine height of last line by the font
3684 if ( nNewHeightOfLastLine == 0 )
3685 {
3686 CalcHeightOfLastLine( true );
3687 }
3688 else
3689 {
3690 mnHeightOfLastLine = nNewHeightOfLastLine;
3691 }
3692 }
3693 }
3694 }
3695 }
3696 // i#71281
3697 // invalidate printing area, if height of last line changes
3698 if ( mnHeightOfLastLine != nOldHeightOfLastLine )
3699 {
3700 InvalidatePrt();
3701 }
3702}
3703
3713tools::Long SwTextFrame::GetLineSpace( const bool _bNoPropLineSpace ) const
3714{
3715 tools::Long nRet = 0;
3716
3718
3719 switch( rSpace.GetInterLineSpaceRule() )
3720 {
3721 case SvxInterLineSpaceRule::Prop:
3722 {
3723 if ( _bNoPropLineSpace )
3724 {
3725 break;
3726 }
3727
3728 // i#11860 - adjust spacing implementation for object positioning
3729 // - compatibility to MS Word
3730 nRet = GetHeightOfLastLine();
3731
3732 tools::Long nTmp = nRet;
3733 nTmp *= rSpace.GetPropLineSpace();
3734 nTmp /= 100;
3735 nTmp -= nRet;
3736 if ( nTmp > 0 )
3737 nRet = nTmp;
3738 else
3739 nRet = 0;
3740 }
3741 break;
3742 case SvxInterLineSpaceRule::Fix:
3743 {
3744 if ( rSpace.GetInterLineSpace() > 0 )
3745 nRet = rSpace.GetInterLineSpace();
3746 }
3747 break;
3748 default:
3749 break;
3750 }
3751 return nRet;
3752}
3753
3755{
3756 if ( !HasPara() )
3757 {
3759 return IsVertical() ? o3tl::narrowing<sal_uInt16>(getFramePrintArea().Width()) : o3tl::narrowing<sal_uInt16>(getFramePrintArea().Height());
3760 return USHRT_MAX;
3761 }
3762 const SwParaPortion *pPara = GetPara();
3763 if ( !pPara )
3764 return USHRT_MAX;
3765
3766 return pPara->Height();
3767}
3768
3770{
3771 sal_uInt16 nRet = 0;
3772 SwTextFrame *pFrame = this;
3773 do
3774 {
3775 pFrame->GetFormatted();
3776 if( !pFrame->HasPara() )
3777 break;
3778 SwTextSizeInfo aInf( pFrame );
3779 SwTextMargin aLine( pFrame, &aInf );
3781 aLine.Bottom();
3782 else
3783 aLine.CharToLine( nPos );
3784 nRet = nRet + aLine.GetLineNr();
3785 pFrame = pFrame->GetFollow();
3786 } while ( pFrame && pFrame->GetOffset() <= nPos );
3787 return nRet;
3788}
3789
3791{
3792 // not necessary to format here (GetFormatted etc.), because we have to come from there!
3793 sal_uInt32 nNew = 0;
3794 const SwLineNumberInfo &rInf = GetDoc().GetLineNumberInfo();
3795 if ( !GetText().isEmpty() && HasPara() )
3796 {
3797 SwTextSizeInfo aInf( this );
3798 SwTextMargin aLine( this, &aInf );
3799 if ( rInf.IsCountBlankLines() )
3800 {
3801 aLine.Bottom();
3802 nNew = aLine.GetLineNr();
3803 }
3804 else
3805 {
3806 do
3807 {
3808 if( aLine.GetCurr()->HasContent() )
3809 ++nNew;
3810 } while ( aLine.NextLine() );
3811 }
3812 }
3813 else if ( rInf.IsCountBlankLines() )
3814 nNew = 1;
3815
3816 if ( nNew == mnThisLines )
3817 return;
3818
3819 if (!IsInTab() && GetTextNodeForParaProps()->GetSwAttrSet().GetLineNumber().IsCount())
3820 {
3822 mnThisLines = nNew;
3824 SwFrame *pNxt = GetNextContentFrame();
3825 while( pNxt && pNxt->IsInTab() )
3826 {
3827 pNxt = pNxt->FindTabFrame();
3828 if( nullptr != pNxt )
3829 pNxt = pNxt->FindNextCnt();
3830 }
3831 if( pNxt )
3832 pNxt->InvalidateLineNum();
3833
3834 // Extend repaint to the bottom.
3835 if ( HasPara() )
3836 {
3837 SwRepaint& rRepaint = GetPara()->GetRepaint();
3838 rRepaint.Bottom( std::max( rRepaint.Bottom(),
3840 }
3841 }
3842 else // Paragraphs which are not counted should not manipulate the AllLines.
3843 mnThisLines = nNew;
3844}
3845
3847{
3849
3850 if ( IsInTab() )
3851 return;
3852
3853 const sal_uLong nOld = GetAllLines();
3855 sal_uLong nNewNum;
3856 const bool bRestart = GetDoc().GetLineNumberInfo().IsRestartEachPage();
3857
3858 if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
3859 nNewNum = rLineNum.GetStartValue() - 1;
3860 // If it is a follow or not has not be considered if it is a restart at each page; the
3861 // restart should also take effect at follows.
3862 else if ( bRestart && FindPageFrame()->FindFirstBodyContent() == this )
3863 {
3864 nNewNum = 0;
3865 }
3866 else
3867 {
3869 while ( pPrv &&
3870 (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
3871 pPrv = pPrv->GetPrevContentFrame();
3872
3873 // i#78254 Restart line numbering at page change
3874 // First body content may be in table!
3875 if ( bRestart && pPrv && pPrv->FindPageFrame() != FindPageFrame() )
3876 pPrv = nullptr;
3877
3878 nNewNum = pPrv ? static_cast<SwTextFrame*>(pPrv)->GetAllLines() : 0;
3879 }
3880 if ( rLineNum.IsCount() )
3881 nNewNum += GetThisLines();
3882
3883 if ( nOld == nNewNum )
3884 return;
3885
3886 mnAllLines = nNewNum;
3888 while ( pNxt &&
3889 (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
3890 pNxt = pNxt->GetNextContentFrame();
3891 if ( pNxt )
3892 {
3893 if ( pNxt->GetUpper() != GetUpper() )
3894 pNxt->InvalidateLineNum();
3895 else
3896 pNxt->InvalidateLineNum_();
3897 }
3898}
3899
3901{
3902 const SwParaPortion* pPara = isFrameAreaDefinitionValid() ? GetPara() : nullptr;
3903
3904 if (pPara)
3905 {
3906 if ( IsFollow() )
3907 rPH.Skip( GetOffset() );
3908
3909 const SwLineLayout* pLine = pPara;
3910 while ( pLine )
3911 {
3912 const SwLinePortion* pPor = pLine->GetFirstPortion();
3913 while ( pPor )
3914 {
3915 pPor->HandlePortion( rPH );
3916 pPor = pPor->GetNextPortion();
3917 }
3918
3919 rPH.LineBreak(pLine->Width());
3920 pLine = pLine->GetNext();
3921 }
3922 }
3923
3924 rPH.Finish();
3925}
3926
3928{
3929 const SwParaPortion* pPara = GetPara();
3930 return pPara ? &pPara->GetScriptInfo() : nullptr;
3931}
3932
3936static SwTwips lcl_CalcFlyBasePos( const SwTextFrame& rFrame, SwRect aFlyRect,
3937 SwTextFly const & rTextFly )
3938{
3939 SwRectFnSet aRectFnSet(&rFrame);
3940 SwTwips nRet = rFrame.IsRightToLeft() ?
3941 aRectFnSet.GetRight(rFrame.getFrameArea()) :
3942 aRectFnSet.GetLeft(rFrame.getFrameArea());
3943
3944 do
3945 {
3946 SwRect aRect = rTextFly.GetFrame( aFlyRect );
3947 if ( 0 != aRectFnSet.GetWidth(aRect) )
3948 {
3949 if ( rFrame.IsRightToLeft() )
3950 {
3951 if ( aRectFnSet.GetRight(aRect) -
3952 aRectFnSet.GetRight(aFlyRect) >= 0 )
3953 {
3954 aRectFnSet.SetRight(
3955aFlyRect, aRectFnSet.GetLeft(aRect) );
3956 nRet = aRectFnSet.GetLeft(aRect);
3957 }
3958 else
3959 break;
3960 }
3961 else
3962 {
3963 if ( aRectFnSet.GetLeft(aFlyRect) -
3964 aRectFnSet.GetLeft(aRect) >= 0 )
3965 {
3966 aRectFnSet.SetLeft(
3967aFlyRect, aRectFnSet.GetRight(aRect) + 1 );
3968 nRet = aRectFnSet.GetRight(aRect);
3969 }
3970 else
3971 break;
3972 }
3973 }
3974 else
3975 break;
3976 }
3977 while ( aRectFnSet.GetWidth(aFlyRect) > 0 );
3978
3979 return nRet;
3980}
3981
3983{
3984 OSL_ENSURE( !IsVertical() || !IsSwapped(),
3985 "SwTextFrame::CalcBasePosForFly with swapped frame!" );
3986
3987 if (!GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::ADD_FLY_OFFSETS))
3988 return;
3989
3990 SwRectFnSet aRectFnSet(this);
3991
3993
3994 // Get first 'real' line and adjust position and height of line rectangle.
3995 // Correct behaviour if no 'real' line exists
3996 // (empty paragraph with and without a dummy portion)
3997 SwTwips nFlyAnchorVertOfstNoWrap = 0;
3998 {
3999 SwTwips nTop = aRectFnSet.GetTop(aFlyRect);
4000 const SwLineLayout* pLay = GetPara();
4001 SwTwips nLineHeight = 200;
4002 while( pLay && pLay->IsDummy() && pLay->GetNext() )
4003 {
4004 nTop += pLay->Height();
4005 nFlyAnchorVertOfstNoWrap += pLay->Height();
4006 pLay = pLay->GetNext();
4007 }
4008 if ( pLay )
4009 {
4010 nLineHeight = pLay->Height();
4011 }
4012 aRectFnSet.SetTopAndHeight( aFlyRect, nTop, nLineHeight );
4013 }
4014
4015 SwTextFly aTextFly( this );
4016 aTextFly.SetIgnoreCurrentFrame( true );
4017 aTextFly.SetIgnoreContour( true );
4018 // ignore objects in page header|footer for
4019 // text frames not in page header|footer
4020 aTextFly.SetIgnoreObjsInHeaderFooter( true );
4021 SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTextFly );
4022 aTextFly.SetIgnoreCurrentFrame( false );
4023 SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTextFly );
4024
4025 // make values relative to frame start position
4026 SwTwips nLeft = IsRightToLeft() ?
4027 aRectFnSet.GetRight(getFrameArea()) :
4028 aRectFnSet.GetLeft(getFrameArea());
4029
4030 mnFlyAnchorOfst = nRet1 - nLeft;
4031 mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
4032
4033 if (!GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS))
4034 return;
4035
4036 if (mnFlyAnchorOfstNoWrap > 0)
4037 mnFlyAnchorVertOfstNoWrap = nFlyAnchorVertOfstNoWrap;
4038}
4039
4040SwTwips SwTextFrame::GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const
4041{
4042 return bIgnoreFlysAnchoredAtThisFrame ? 0 : mnFlyAnchorVertOfstNoWrap;
4043}
4044
4049{
4051 for( const SwTextFrame *pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
4052 {
4053 SwRect aRec( pFrame->GetPaintArea() );
4054 const SwRootFrame *pRootFrame = pFrame->getRootFrame();
4055 SwViewShell *pCurShell = pRootFrame ? pRootFrame->GetCurrShell() : nullptr;
4056 if( pCurShell )
4057 pCurShell->InvalidateWindows( aRec );
4058 }
4059}
4060
4062{
4063 if (pWrtSh && pWrtSh->GetViewOptions()->IsShowOutlineContentVisibilityButton() &&
4064 GetTextNodeFirst()->IsOutline())
4065 {
4066 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
4069 }
4070}
4071
4072/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ CONSIDER_WRAP_ON_OBJECT_POSITION
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...
GPOS_NONE
virtual OutputDevice * getReferenceDevice(bool bCreate) const =0
Returns the current reference device.
virtual bool SetFieldsDirty(bool b, const SwNode *pChk, SwNodeOffset nLen)=0
Provides access to settings of a document.
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
Organizer of the contact between SwTextNodes and grammar checker.
virtual SwGrammarMarkUp * getGrammarCheck(SwTextNode &rTextNode, bool bCreate)=0
getGrammarCheck checks if the given text node is blocked by the current cursor if not,...
SdrObjUserCall * GetUserCall() const
void Broadcast(const SfxHint &rHint)
SfxHintId GetId() const
SfxItemPool * GetPool() const
sal_uInt16 Count() const
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_uInt16 Which() const
constexpr tools::Long Height() const
void setHeight(tools::Long nHeight)
const Color & GetColor() const
SvxGraphicPosition GetGraphicPos() const
sal_uInt16 GetPropLineSpace() const
SvxInterLineSpaceRule GetInterLineSpaceRule() const
short GetInterLineSpace() const
SvxAdjust GetNumAdjust() const
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
wrapper class for the positioning of Writer fly frames and drawing objects
virtual SwFrameFormat & GetFrameFormat()=0
virtual const SwFlyFrame * DynCastFlyFrame() const
sal_uInt16 Count() const
Definition: hints.hxx:308
void ClearItem(sal_uInt16 nWhichL)
Definition: hints.cxx:132
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:64
const SvxLineSpacingItem & GetLineSpacing(bool=true) const
Definition: paratr.hxx:192
SwBorderAttrs * Get()
Definition: frmtool.cxx:2677
tools::Long CalcLeft(const SwFrame *pCaller) const
Definition: frmtool.cxx:2367
tools::Long CalcRight(const SwFrame *pCaller) const
Definition: frmtool.cxx:2305
void Unlock()
Definition: swcache.cxx:477
TextFrameIndex & Len()
Definition: porlay.hxx:49
TextFrameIndex & Start()
Definition: porlay.hxx:45
Base class for the following contact objects (frame + draw objects).
Definition: dcontact.hxx:67
virtual void MoveObjToVisibleLayer(SdrObject *_pDrawObj)
method to move drawing object to corresponding visible layer
Definition: dcontact.cxx:210
const SwPosition & GetContentAnchor() const
Definition: dcontact.hxx:152
virtual void MoveObjToInvisibleLayer(SdrObject *_pDrawObj)
method to move drawing object to corresponding invisible layer
Definition: dcontact.cxx:237
RndStdIds GetAnchorId() const
Definition: dcontact.hxx:145
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:58
SwContentFrame * GetPrevContentFrame() const
Definition: cntfrm.hxx:127
virtual void DestroyImpl() override
Definition: ssfrm.cxx:426
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:119
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:737
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: wsfrm.cxx:2347
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1224
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:742
LanguageType nOldLanguageType
Definition: txtfrm.hxx:950
SwDigitModeModifier(const OutputDevice &rOutp, LanguageType eCurLang)
Definition: txtfrm.cxx:724
const OutputDevice & rOut
Definition: txtfrm.hxx:949
SwDocPosUpdate is sent to signal that only the frames from or to a specified document-global position...
Definition: hints.hxx:247
const SwTwips nDocPos
Definition: hints.hxx:249
Definition: doc.hxx:192
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:634
bool FieldHidesPara(const SwField &rField) const
Definition: doc.cxx:1349
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:239
const SwLineNumberInfo & GetLineNumberInfo() const
Definition: lineinfo.cxx:49
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:358
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:638
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:177
int FieldCanHideParaWeight(SwFieldIds eFieldId) const
Definition: doc.cxx:1334
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:61
SwFrameControlsManager & GetFrameControlsManager()
Definition: edtwin.cxx:6799
SwFieldIds Which() const
Definition: fldbas.hxx:273
SwFieldType * GetTyp() const
Definition: fldbas.hxx:398
SwTwips CalcUpperSpace(const SwBorderAttrs *pAttrs=nullptr, const SwFrame *pPr=nullptr, const bool _bConsiderGrid=true) const
method to determine the upper space hold by the frame
Definition: flowfrm.cxx:1457
void CheckKeep()
Definition: flowfrm.cxx:146
bool HasFollow() const
Definition: flowfrm.hxx:166
bool IsFollow() const
Definition: flowfrm.hxx:167
bool IsUndersized() const
Definition: flowfrm.hxx:159
void SetDevFont(const SwViewShell *pSh, OutputDevice &rOut)
Definition: fntcache.cxx:557
void SetFntChg(const bool bNew)
Definition: swfont.hxx:209
void ChgPhysFnt(SwViewShell const *pSh, OutputDevice &rOut)
Definition: swfont.cxx:893
tools::Long GetHeight() const
Definition: swfont.hxx:284
bool RemoveFootnote(const SwContentFrame *, const SwTextFootnote *, bool bPrep=true)
Definition: ftnfrm.cxx:1734
SwTextFootnote * SeekEntry(const SwNode &rNd, size_t *pPos=nullptr) const
Definition: ftnidx.cxx:408
OUString m_aErgoSum
Definition: ftninfo.hxx:96
OUString m_aQuoVadis
Definition: ftninfo.hxx:95
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const SwField * GetField() const
Definition: fmtfld.hxx:130
const SwTextField * GetTextField() const
Definition: fmtfld.hxx:148
bool IsCount() const
Definition: fmtline.hxx:58
sal_uLong GetStartValue() const
Definition: fmtline.hxx:57
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:83
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
void setSwRect(const SwRect &rNew)
Definition: frame.hxx:198
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
A container for the Header/Footer, PageBreak, and Outline Content Visibility controls.
void SetOutlineContentVisibilityButton(const SwContentFrame *pContentFrame)
Style of a layout element.
Definition: frmfmt.hxx:62
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:928
SwFrameSwapper(const SwTextFrame *pFrame, bool bSwapIfNotSwapped)
Definition: txtfrm.cxx:667
const SwTextFrame * pFrame
Definition: txtfrm.hxx:929
Base class of the Writer layout elements.
Definition: frame.hxx:315
void InvalidateLineNum_()
Definition: frame.hxx:795
bool IsTextFrame() const
Definition: frame.hxx:1234
void SetDerivedR2L(bool bNew)
Definition: frame.hxx:632
bool IsInDtor() const
Definition: frame.hxx:892
void InvalidateLineNum()
Definition: frame.hxx:1050
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:194
bool IsInDocBody() const
Definition: frame.hxx:943
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
SwFrame * FindNext()
Definition: frame.hxx:1141
SwFrame * GetNext()
Definition: frame.hxx:676
SwFrameType mnFrameType
Definition: frame.hxx:414
bool IsVertLRBT() const
Definition: frame.hxx:983
bool IsInFootnote() const
Definition: frame.hxx:949
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1798
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
bool IsInTab() const
Definition: frame.hxx:955
static SwCache & GetCache()
Definition: frame.hxx:521
bool IsRightToLeft() const
Definition: frame.hxx:987
bool IsInFly() const
Definition: frame.hxx:961
void InvalidateNextPrtArea()
method to invalidate printing area of next frame #i11859#
Definition: findfrm.cxx:1336
void InvalidatePrt()
Definition: frame.hxx:1036
void ValidateLineNum()
Definition: frame.hxx:760
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
bool IsVertical() const
Definition: frame.hxx:973
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:613
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
bool IsNoTextFrame() const
Definition: frame.hxx:1238
void SetCompletePaint() const
Definition: frame.hxx:994
void InvalidatePrt_()
Definition: frame.hxx:779
SwFrame * GetPrev()
Definition: frame.hxx:677
void InvalidateSize_()
Definition: frame.hxx:771
bool IsVertLR() const
Definition: frame.hxx:979
void InvalidateSize()
Definition: frame.hxx:1029
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:215
void SetInvalidVert(bool bNew)
Definition: frame.hxx:630
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
sw::BroadcastingModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:476
SwFrame * GetIndNext()
Definition: frame.hxx:727
bool IsLayoutFrame() const
Definition: frame.hxx:1170
bool IsInSct() const
Definition: frame.hxx:967
void MoveGrammar(sal_Int32 nPos, sal_Int32 nDiff)
TElementType * Next()
Definition: calbck.hxx:364
TElementType * First()
Definition: calbck.hxx:356
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method <ContainsAny()> doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:129
const OutputDevice & m_rOut
Definition: txtfrm.hxx:938
SwLayoutModeModifier(const OutputDevice &rOutp)
Definition: txtfrm.cxx:701
void Modify(bool bChgToRTL)
Definition: txtfrm.cxx:711
vcl::text::ComplexTextLayoutFlags m_nOldLayoutMode
Definition: txtfrm.hxx:939
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:79
SwLineLayout * GetNext()
Definition: porlay.hxx:159
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:841
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:238
bool HasContent() const
Definition: porlay.hxx:133
void MaxAscentDescent(SwTwips &_orAscent, SwTwips &_orDescent, SwTwips &_orObjAscent, SwTwips &_orObjDescent, const SwLinePortion *_pDontConsiderPortion=nullptr, const bool _bNoFlyCntPorAndLinePor=false) const
determine ascent and descent for positioning of as-character anchored object
Definition: porlay.cxx:763
bool IsDummy() const
Definition: porlay.hxx:151
SwTwips GetRealHeight() const
Definition: porlay.hxx:169
< purpose of derivation from SwClient: character style for displaying the numbers.
Definition: lineinfo.hxx:39
bool IsRestartEachPage() const
Definition: lineinfo.hxx:89
bool IsCountBlankLines() const
Definition: lineinfo.hxx:83
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:52
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:75
bool InNumberGrp() const
Definition: porlin.hxx:109
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
virtual void HandlePortion(SwPortionHandler &rPH) const
Definition: porlin.cxx:316
bool IsFootnoteNumPortion() const
Definition: porlin.hxx:128
void Add(SwClient *pDepend)
Definition: calbck.cxx:172
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
Base class of the Writer document model elements.
Definition: node.hxx:84
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:876
SwNodeOffset GetIndex() const
Definition: node.hxx:296
bool IsNoTextNode() const
Definition: node.hxx:676
SwDoc & GetDoc()
Definition: node.hxx:217
Merge GetRedlineMergeFlag() const
Definition: node.hxx:100
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:87
A page of the document layout.
Definition: pagefrm.hxx:58
void InvalidateWordCount() const
Definition: pagefrm.hxx:397
void InvalidateAutoCompleteWords() const
Definition: pagefrm.hxx:393
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
void InvalidateSmartTags() const
Definition: pagefrm.hxx:389
void InvalidateSpelling() const
Definition: pagefrm.hxx:384
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:251
bool IsPrepMustFit() const
Definition: porlay.hxx:310
TextFrameIndex GetParLen() const
Definition: porlay.cxx:2654
SwCharRange & GetReformat()
Definition: porlay.hxx:287
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
bool HasFly() const
Definition: porlay.hxx:302
void SetPrepWidows()
Definition: porlay.hxx:307
bool IsFootnoteNum() const
Definition: porlay.hxx:319
bool IsFixLineHeight() const
Definition: porlay.hxx:316
bool UpdateQuoVadis(std::u16string_view rQuo)
Is called in SwTextFrame::Prepare()
Definition: txtftn.cxx:1569
SwRepaint & GetRepaint()
Definition: porlay.hxx:285
tools::Long GetDelta() const
Definition: porlay.hxx:290
SwScriptInfo & GetScriptInfo()
Definition: porlay.hxx:291
The SwPortionHandler interface implements a visitor for the layout engine's text portions.
virtual void LineBreak(sal_Int32 nWidth)=0
line break.
virtual void Skip(TextFrameIndex nLength)=0
skip characters.
virtual void Finish()=0
end of paragraph.
SwTwips Width() const
Definition: possiz.hxx:51
bool IsVert() const
Definition: frame.hxx:1366
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1389
void SetPosX(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1399
void SetRight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1388
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1380
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1390
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
void SetPosY(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1400
void SetTopAndHeight(SwRect &rRect, tools::Long nTop, tools::Long nHeight) const
Definition: frame.hxx:1427
tools::Long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1403
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1378
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1379
void SetLeft(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1387
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool HasArea() const
Definition: swrect.hxx:300
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
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 Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
bool HasMergedParas() const
Definition: rootfrm.hxx:425
void SetNeedGrammarCheck(bool bVal)
Definition: rootfrm.hxx:262
static bool GetBoundsOfHiddenRange(const SwTextNode &rNode, sal_Int32 nPos, sal_Int32 &rnStartPos, sal_Int32 &rnEndPos, std::vector< sal_Int32 > *pList=nullptr)
Hidden text range information - static and non-version.
Definition: porlay.cxx:2035
void InitScriptInfo(const SwTextNode &rNode, sw::MergedPara const *pMerged, bool bRTL)
Definition: porlay.cxx:1127
void SetInvalidityA(const TextFrameIndex nPos)
Definition: scriptinfo.hxx:114
static SwSmartTagMgr & Get()
class for collecting anchored objects
Definition: sortedobjs.hxx:49
size_t size() const
Definition: sortedobjs.cxx:43
Small Helper class: Prepares a test format.
Definition: txtfrm.cxx:3141
SwTestFormat(SwTextFrame *pTextFrame, const SwFrame *pPrv, SwTwips nMaxHeight)
Definition: txtfrm.cxx:3150
SwParaPortion * pOldPara
Definition: txtfrm.cxx:3143
SwRect aOldPrt
Definition: txtfrm.cxx:3144
SwTextFrame * pFrame
Definition: txtfrm.cxx:3142
SwRect aOldFrame
Definition: txtfrm.cxx:3144
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:161
virtual const sal_Int32 * GetEnd() const
end position
Definition: txatbase.cxx:48
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
The purpose of this class is to be the universal interface between formatting/text output and the pos...
Definition: txtfly.hxx:122
void SetIgnoreObjsInHeaderFooter(const bool bNew)
Definition: txtfly.hxx:377
void SetIgnoreContour(bool bNew)
Definition: txtfly.hxx:372
void SetIgnoreCurrentFrame(bool bNew)
Definition: txtfly.hxx:367
bool Relax(const SwRect &rRect)
If there is no flying object frame standing in rRect (usually the current row), then we are turning o...
Definition: txtfly.hxx:324
SwRect GetFrame(const SwRect &rPortion) const
Definition: txtfly.hxx:362
bool IsOn() const
Definition: txtfly.hxx:319
void DelFrames(const SwRootFrame *)
Definition: atrftn.cxx:465
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:70
void SetIgnoreFly(const bool bNew)
Definition: inftxt.hxx:574
SwTwips CalcFitToContent_()
Definition: itrform2.cxx:2224
void RecalcRealHeight()
Definition: itrform2.cxx:1985
bool IsBreakNow(SwTextMargin &rLine)
Definition: widorp.cxx:218
bool IsKeepAlways() const
Definition: widorp.hxx:38
bool IsInside(SwTextMargin const &rLine) const
BP 18.6.93: Widows.
Definition: widorp.cxx:102
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
void Init()
This is public, as it needs to be called by some methods in order to save the Prepare USE WITH CAUTIO...
Definition: txtfrm.cxx:750
void Format_(vcl::RenderContext *pRenderContext, SwParaPortion *pPara)
Definition: frmform.cxx:1732
TextFrameIndex CalcFlyPos(SwFrameFormat const *pSearch)
Calculates the position of FlyInContentFrames.
Definition: porfly.cxx:184
SwTextFrame * GetFormatted(bool bForceQuickFormat=false)
In case the SwLineLayout was cleared out of the s_pTextCache, recreate it.
Definition: txtfrm.cxx:3389
bool IsFootnoteNumFrame() const
Am I a FootnoteFrame, with a number at the start of the paragraph?
Definition: txtfrm.hxx:628
sal_uLong GetThisLines() const
Definition: txtfrm.hxx:674
SwDoc & GetDoc()
Definition: txtfrm.hxx:466
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout.
Definition: txtfrm.cxx:580
bool TestFormat(const SwFrame *pPrv, SwTwips &nMaxHeight, bool &bSplit)
The WouldFit equivalent for temporarily rewired TextFrames nMaxHeight returns the required size here ...
Definition: txtfrm.cxx:3228
void SetOffset(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:871
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:861
void CalcFootnoteFlag(TextFrameIndex nStop=TextFrameIndex(COMPLETE_STRING))
Does the Frame have a local footnote (in this Frame or Follow)?
Definition: txtftn.cxx:104
void HideAndShowObjects()
Hides respectively shows objects, which are anchored at paragraph, at/as a character of the paragraph...
Definition: txtfrm.cxx:1549
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1246
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1343
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:444
bool HasPara() const
Definition: txtfrm.hxx:825
void UpdateOutlineContentVisibilityButton(SwWrtShell *pWrtSh) const
Definition: txtfrm.cxx:4061
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1231
void InvalidateRange(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1687
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:683
void SetMergedPara(std::unique_ptr< sw::MergedPara > p)
Definition: txtfrm.cxx:1274
bool FormatQuick(bool bForceQuickFormat)
Definition: frmform.cxx:2020
SwTwips GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const
Definition: txtfrm.cxx:4040
bool IsWidow() const
Definition: txtfrm.hxx:525
bool IsSwapped() const
Definition: txtfrm.hxx:541
SwTwips mnFlyAnchorOfst
Definition: txtfrm.hxx:186
void HideHidden()
Removes Textfrm's attachments, when it's hidden.
Definition: txtfrm.cxx:1443
void CalcBaseOfstForFly()
Definition: txtfrm.cxx:3982
SwTextNode const * GetTextNodeForFirstText() const
Definition: txtfrm.cxx:1317
SwTwips mnHeightOfLastLine
Definition: txtfrm.hxx:194
bool IsIdxInside(TextFrameIndex nPos, TextFrameIndex nLen) const
Definition: txtfrm.cxx:1658
sal_uLong GetAllLines() const
For displaying the line numbers.
Definition: txtfrm.hxx:673
void ClearPara()
Removes the Line information from the Cache but retains the entry itself.
Definition: txtcache.cxx:104
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
Definition: frmform.cxx:1791
void CalcLineSpace()
Definition: txtfrm.cxx:1727
void PrepWidows(const sal_uInt16 nNeed, bool bNotify)
Definition: txtfrm.cxx:2661
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:456
virtual bool WouldFit(SwTwips &nMaxHeight, bool &bSplit, bool bTst) override
nMaxHeight is the required height bSplit indicates, that the paragraph has to be split bTst indicates...
Definition: txtfrm.cxx:3252
bool HasFootnote() const
Definition: txtfrm.hxx:528
void SetWidow(const bool bNew)
Definition: txtfrm.hxx:251
void ResetPreps()
Definition: txtfrm.cxx:1351
void SetPara(SwParaPortion *pNew, bool bDelete=true)
Definition: txtcache.cxx:129
void CalcHeightOfLastLine(const bool _bUseFont=false)
method to determine height of last line, needed for proportional line spacing
Definition: txtfrm.cxx:3574
static void repaintTextFrames(const SwTextNode &rNode)
Repaint all text frames of the given text node.
Definition: txtfrm.cxx:4048
SwTwips EmptyHeight() const
Definition: porrst.cxx:333
void CalcAdditionalFirstLineOffset()
Simulate format for a list item paragraph, whose list level attributes are in LABEL_ALIGNMENT mode,...
Definition: txtfrm.cxx:3488
SwTwips GetParHeight() const
Returns the sum of line height in pLine.
Definition: txtfrm.cxx:3349
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1252
virtual bool GetInfo(SfxPoolItem &) const override
Definition: txtfrm.cxx:2635
void SetHasRotatedPortions(bool bHasRotatedPortions)
Definition: txtftn.cxx:98
sal_uInt32 mnAllLines
Definition: txtfrm.hxx:181
static TextFrameIndex FindBrk(const OUString &rText, TextFrameIndex nStart, TextFrameIndex nEnd)
Returns the first possible break point in the current line.
Definition: txtfrm.cxx:1633
bool IsLocked() const
Definition: txtfrm.hxx:523
SwTwips mnFlyAnchorOfstNoWrap
Definition: txtfrm.hxx:188
SwTwips CalcFitToContent()
Simulates a formatting as if there were not right margin or Flys or other obstacles and returns the w...
Definition: txtfrm.cxx:3414
void InvalidateRange_(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1693
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout.
Definition: txtfrm.cxx:473
void VisitPortions(SwPortionHandler &rPH) const
Visit all portions for Accessibility.
Definition: txtfrm.cxx:3900
std::unique_ptr< sw::MergedPara > m_pMergedPara
redline merge data
Definition: txtfrm.hxx:202
tools::Long GetLineSpace(const bool _bNoPropLineSpacing=false) const
Returns the additional line spacing for the next paragraph.
Definition: txtfrm.cxx:3713
void SetFieldFollow(const bool bNew)
Definition: txtfrm.hxx:254
void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd)
Definition: txtfrm.cxx:1455
SwTextFrame(SwTextNode *const, SwFrame *, sw::FrameMode eMode)
Definition: txtfrm.cxx:764
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1267
SwTwips mnFlyAnchorVertOfstNoWrap
The y position for wrap-through flys anchored at this paragraph.
Definition: txtfrm.hxx:190
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1360
void ChgThisLines()
Definition: txtfrm.cxx:3790
sal_uInt32 mnThisLines
Definition: txtfrm.hxx:182
sal_uInt16 GetLineCount(TextFrameIndex nPos)
Determines the line count.
Definition: txtfrm.cxx:3769
const SwScriptInfo * GetScriptInfo() const
Returns the script info stored at the paraportion.
Definition: txtfrm.cxx:3927
sal_uInt16 GetCacheIdx() const
Definition: txtfrm.hxx:619
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:463
void RemoveFromCache()
Removes this frame completely from the Cache.
Definition: txtcache.cxx:120
void SetOffset_(TextFrameIndex nNewOfst)
Definition: frmform.cxx:766
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true) override
SwContentFrame: the shortcut for the Frames If the void* casts wrongly, it's its own fault!...
Definition: txtfrm.cxx:2741
virtual ~SwTextFrame() override
Definition: txtfrm.cxx:892
SwTwips GetHeightOfLastLine() const
Definition: txtfrm.hxx:773
void ManipOfst(TextFrameIndex const nNewOfst)
Definition: txtfrm.hxx:447
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:420
void RecalcAllLines()
Definition: txtfrm.cxx:3846
sal_uInt16 FirstLineHeight() const
Returns the first line height.
Definition: txtfrm.cxx:3754
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1293
SwTwips mnAdditionalFirstLineOffset
Definition: txtfrm.hxx:199
bool mbIsSwapped
Definition: txtfrm.hxx:240
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1303
virtual void SwClientNotify(SwModify const &rModify, SfxHint const &rHint) override
Definition: txtfrm.cxx:1973
bool IsEmpty() const
Definition: txtfrm.hxx:527
virtual void DestroyImpl() override
Definition: txtfrm.cxx:850
const SwLineLayout * NextLine()
Definition: itrtxt.cxx:125
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
SwTwips Y() const
Definition: itrtxt.hxx:90
void TruncLines(bool bNoteFollow=false)
Definition: itrtxt.cxx:365
void Bottom()
Definition: itrtxt.cxx:186
const SwLineLayout * PrevLine()
Definition: itrtxt.cxx:171
void Top()
Definition: itrtxt.hxx:99
SwTwips GetLineHeight() const
Definition: itrtxt.hxx:116
const SwLineLayout * Next()
Definition: itrtxt.cxx:108
void CharToLine(TextFrameIndex)
Definition: itrtxt.cxx:194
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:87
SwParaPortion * GetPara()
Definition: txtcache.cxx:50
sal_uInt16 GetDropLines() const
Definition: itrtxt.hxx:202
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:275
bool IsSmartTagDirty() const
Definition: txtedt.cxx:2346
SwWrongList * GetSmartTags()
Definition: txtedt.cxx:2284
SwWrongList * GetWrong()
Definition: txtedt.cxx:2226
void SetWordCountDirty(bool bNew) const
Definition: txtedt.cxx:2294
void SetGrammarCheckDirty(bool bNew) const
Definition: txtedt.cxx:2325
void SetSmartTags(std::unique_ptr< SwWrongList > pNew)
Definition: txtedt.cxx:2264
void SetSmartTagDirty(bool bNew) const
Definition: txtedt.cxx:2338
void SetAutoCompleteWordDirty(bool bNew) const
Definition: txtedt.cxx:2351
bool IsCountedInList() const
Definition: ndtxt.cxx:4331
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2870
int GetActualListLevel(SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4186
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2938
SwGrammarMarkUp * GetGrammarCheck()
Definition: txtedt.cxx:2254
void SetWrongDirty(WrongState eNew) const
Definition: txtedt.cxx:2307
bool IsWrongDirty() const
Definition: txtedt.cxx:2320
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:230
void SetWrong(std::unique_ptr< SwWrongList > pNew)
Definition: txtedt.cxx:2209
const OUString & GetText() const
Definition: ndtxt.hxx:222
void AddToListRLHidden()
Definition: ndtxt.cxx:4418
void RemoveFromListRLHidden()
Definition: ndtxt.cxx:4460
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3105
SwTextFly & GetTextFly()
Definition: inftxt.hxx:387
const std::vector< sal_uInt16 > & getFmtAttrs() const
Definition: hints.hxx:223
sal_uInt16 getWhichAttr() const
Definition: hints.hxx:218
sal_Int32 getStart() const
Definition: hints.hxx:208
sal_Int32 getEnd() const
Definition: hints.hxx:213
bool IsShowOutlineContentVisibilityButton() const
Definition: viewopt.cxx:99
bool IsShowHiddenPara() const
Definition: viewopt.hxx:397
bool IsPrtFormat() const
Definition: viewopt.hxx:541
bool getBrowseMode() const
Definition: viewopt.hxx:472
bool IsShowHiddenChar(bool bHard=false) const
Definition: viewopt.hxx:321
bool IsFieldName() const
Definition: viewopt.hxx:269
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:347
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:436
void InvalidateAccessibleParaAttrs(const SwTextFrame &rTextFrame)
invalidate attributes for paragraphs and paragraph's characters
Definition: viewsh.cxx:2623
vcl::Window * GetWin() const
Definition: viewsh.hxx:346
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:556
Definition: view.hxx:146
SwEditWin & GetEditWin()
Definition: view.hxx:416
void SetInfo(const SwPageFrame *pPg, const SwFrame *pF)
Definition: hints.hxx:330
const SwPageFrame * GetOrigPage() const
Definition: hints.hxx:328
const SwPageFrame * GetPage() const
Definition: hints.hxx:327
void Invalidate(sal_Int32 nBegin, sal_Int32 nEnd)
Definition: wrong.cxx:426
void SetInvalid(sal_Int32 nBegin, sal_Int32 nEnd)
Definition: wrong.cxx:254
void Move(sal_Int32 nPos, sal_Int32 nDiff)
Change all values after the given position.
Definition: wrong.cxx:267
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
const SwView & GetView() const
Definition: wrtsh.hxx:438
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:68
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
void SortIfNeedBe() const
Trigger the sorting if necessary.
Definition: ndhints.hxx:176
size_t Count() const
Definition: ndhints.hxx:142
SwTextAttr * GetSortedByEnd(size_t nPos) const
Definition: ndhints.hxx:158
sal_uInt16 GetOrphansLines() const
Definition: widorp.hxx:61
bool WouldFit(SwTextMargin &rLine, SwTwips &rMaxHeight, bool bTest)
Definition: widorp.cxx:528
size_type size() const
iterate SwTextAttr in potentially merged text frame
Definition: txtfrm.hxx:990
sw::MergedPara const *const m_pMerged
Definition: txtfrm.hxx:992
MergedAttrIterBase(SwTextFrame const &rFrame)
Definition: txtfrm.cxx:83
SwTextNode const *const m_pNode
Definition: txtfrm.hxx:993
SwTextAttr const * NextAttr(SwTextNode const *&rpNode)
Definition: txtfrm.cxx:166
SwTextNode const *const m_pNode
Definition: txtfrm.hxx:1011
MergedAttrIterByEnd(SwTextFrame const &rFrame)
Definition: txtfrm.cxx:151
std::vector< std::pair< SwTextNode const *, SwTextAttr const * > > m_Hints
Definition: txtfrm.hxx:1010
SwTextAttr const * PrevAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:228
MergedAttrIterReverse(SwTextFrame const &rFrame)
Definition: txtfrm.cxx:203
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:91
text is moved into pDestNode
Definition: hints.hxx:111
sal_Int32 nDestStart
Definition: hints.hxx:114
SwTextNode * pDestNode
Definition: hints.hxx:113
sal_Int32 nSourceStart
Definition: hints.hxx:115
sal_Int32 nLen
Definition: hints.hxx:116
new delete redline is created
Definition: hints.hxx:123
sal_Int32 nStart
Definition: hints.hxx:125
sal_Int32 nLen
Definition: hints.hxx:126
delete redline is removed
Definition: hints.hxx:133
sal_Int32 nLen
Definition: hints.hxx:136
sal_Int32 nStart
Definition: hints.hxx:135
static bool IsFuzzing()
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
int nCount
@ TestFormat
#define PROTOCOL_ENTER(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:92
IGrammarContact * getGrammarContact(const SwTextNode &rTextNode)
getGrammarContact() delivers the grammar contact of the document (for a given textnode)
Definition: docnew.cxx:811
Mutex aLock
SwFntObj * pLastFont
Definition: fntcache.cxx:67
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
constexpr TypedWhichId< SwVirtPageNumInfo > RES_VIRTPAGENUM_INFO(180)
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CJK_FONT(22)
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
constexpr sal_uInt16 RES_FRMATR_END(133)
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
constexpr TypedWhichId< SwDelChr > RES_DEL_CHR(165)
bool isPARATR_LIST(const sal_uInt16 nWhich)