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 <GrammarContact.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
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 {
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
797{
798 (void)xmlTextWriterStartElement(writer, reinterpret_cast<const xmlChar*>("txt"));
799 dumpAsXmlAttributes(writer);
800 sw::MergedPara const*const pMerged(GetMergedPara());
801 if (pMerged)
802 {
803 (void)xmlTextWriterStartElement( writer, BAD_CAST( "merged" ) );
804 (void)xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "paraPropsNodeIndex" ), "%" SAL_PRIdINT32, sal_Int32(pMerged->pParaPropsNode->GetIndex()) );
805 for (auto const& e : pMerged->extents)
806 {
807 (void)xmlTextWriterStartElement( writer, BAD_CAST( "extent" ) );
808 (void)xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "txtNodeIndex" ), "%" SAL_PRIdINT32, sal_Int32(e.pNode->GetIndex()) );
809 (void)xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "start" ), "%" SAL_PRIdINT32, e.nStart );
810 (void)xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "end" ), "%" SAL_PRIdINT32, e.nEnd );
811 (void)xmlTextWriterEndElement( writer );
812 }
813 (void)xmlTextWriterEndElement( writer );
814 }
815
816 (void)xmlTextWriterStartElement(writer, BAD_CAST("infos"));
817 dumpInfosAsXml(writer);
818 (void)xmlTextWriterEndElement(writer);
819
820 // Dump Anchored objects if any
821 const SwSortedObjs* pAnchored = GetDrawObjs();
822 if ( pAnchored && pAnchored->size() > 0 )
823 {
824 (void)xmlTextWriterStartElement( writer, BAD_CAST( "anchored" ) );
825
826 for (SwAnchoredObject* pObject : *pAnchored)
827 {
828 pObject->dumpAsXml( writer );
829 }
830
831 (void)xmlTextWriterEndElement( writer );
832 }
833
834 // Dump the children
835 OUString aText = GetText( );
836 for ( int i = 0; i < 32; i++ )
837 {
838 aText = aText.replace( i, '*' );
839 }
840 auto nTextOffset = static_cast<sal_Int32>(GetOffset());
841 sal_Int32 nTextLength = aText.getLength() - nTextOffset;
842 if (const SwTextFrame* pTextFrameFollow = GetFollow())
843 {
844 nTextLength = static_cast<sal_Int32>(pTextFrameFollow->GetOffset() - GetOffset());
845 }
846 if (nTextLength > 0)
847 {
848 OString aText8
849 = OUStringToOString(aText.subView(nTextOffset, nTextLength), RTL_TEXTENCODING_UTF8);
850 (void)xmlTextWriterWriteString( writer,
851 reinterpret_cast<const xmlChar *>(aText8.getStr( )) );
852 }
853 if (const SwParaPortion* pPara = GetPara())
854 {
855 (void)xmlTextWriterStartElement(writer, BAD_CAST("SwParaPortion"));
856 TextFrameIndex nOffset(0);
857 const OUString& rText = GetText();
858 (void)xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("ptr"), "%p", pPara);
859 const SwLineLayout* pLine = pPara;
860 if (IsFollow())
861 {
862 nOffset += GetOffset();
863 }
864 while (pLine)
865 {
866 (void)xmlTextWriterStartElement(writer, BAD_CAST("SwLineLayout"));
867 pLine->dumpAsXmlAttributes(writer, rText, nOffset);
868 const SwLinePortion* pPor = pLine->GetFirstPortion();
869 while (pPor)
870 {
871 pPor->dumpAsXml(writer, rText, nOffset);
872 pPor = pPor->GetNextPortion();
873 }
874 (void)xmlTextWriterEndElement(writer);
875 pLine = pLine->GetNext();
876 }
877 (void)xmlTextWriterEndElement(writer);
878 }
879
880 (void)xmlTextWriterEndElement(writer);
881}
882
883namespace sw {
884
885SwTextFrame * MakeTextFrame(SwTextNode & rNode, SwFrame *const pSibling,
886 sw::FrameMode const eMode)
887{
888 return new SwTextFrame(&rNode, pSibling, eMode);
889}
890
892 SwRootFrame const& rLayout, SwTextNode const& rTextNode,
893 std::vector<std::pair<sal_Int32, sal_Int32>> const*const pExtents)
894{
895 if (pExtents && pExtents->empty())
896 {
897 return; // nothing to do
898 }
899 const SwFootnoteIdxs &rFootnoteIdxs = rTextNode.GetDoc().GetFootnoteIdxs();
900 size_t nPos = 0;
901 SwNodeOffset const nIndex = rTextNode.GetIndex();
902 rFootnoteIdxs.SeekEntry( rTextNode, &nPos );
903 if (nPos < rFootnoteIdxs.size())
904 {
905 while (nPos && rTextNode == (rFootnoteIdxs[ nPos ]->GetTextNode()))
906 --nPos;
907 if (nPos || rTextNode != (rFootnoteIdxs[ nPos ]->GetTextNode()))
908 ++nPos;
909 }
910 size_t iter(0);
911 for ( ; nPos < rFootnoteIdxs.size(); ++nPos)
912 {
913 SwTextFootnote* pTextFootnote = rFootnoteIdxs[ nPos ];
914 if (pTextFootnote->GetTextNode().GetIndex() > nIndex)
915 break;
916 if (pExtents)
917 {
918 while ((*pExtents)[iter].second <= pTextFootnote->GetStart())
919 {
920 ++iter;
921 if (iter == pExtents->size())
922 {
923 return;
924 }
925 }
926 if (pTextFootnote->GetStart() < (*pExtents)[iter].first)
927 {
928 continue;
929 }
930 }
931 pTextFootnote->DelFrames(&rLayout);
932 }
933}
934
935} // namespace sw
936
938{
939 // Remove associated SwParaPortion from s_pTextCache
940 ClearPara();
941
942 assert(!GetDoc().IsInDtor()); // this shouldn't be happening with ViewShell owning layout
943 if (!GetDoc().IsInDtor() && HasFootnote())
944 {
945 if (m_pMergedPara)
946 {
947 SwTextNode const* pNode(nullptr);
948 for (auto const& e : m_pMergedPara->extents)
949 {
950 if (e.pNode != pNode)
951 {
952 pNode = e.pNode;
953 // sw_redlinehide: not sure if it's necessary to check
954 // if the nodes are still alive here, which would require
955 // accessing WriterMultiListener::m_vDepends
956 sw::RemoveFootnotesForNode(*getRootFrame(), *pNode, nullptr);
957 }
958 }
959 }
960 else
961 {
962 SwTextNode *const pNode(static_cast<SwTextNode*>(GetDep()));
963 if (pNode)
964 {
965 sw::RemoveFootnotesForNode(*getRootFrame(), *pNode, nullptr);
966 }
967 }
968 }
969
970 if (!GetDoc().IsInDtor())
971 {
972 if (SwView* pView = GetActiveView())
973 pView->GetEditWin().GetFrameControlsManager().RemoveControls(this);
974 }
975
977}
978
980{
982}
983
984namespace sw {
985
986// 1. if real insert => correct nStart/nEnd for full nLen
987// 2. if rl un-delete => do not correct nStart/nEnd but just include un-deleted
989 bool const isRealInsert,
990 SwTextNode const& rNode, sal_Int32 const nIndex, sal_Int32 const nLen)
991{
992 assert(!isRealInsert || nLen); // can 0 happen? yes, for redline in empty node
993 assert(nIndex <= rNode.Len());
994 assert(nIndex + nLen <= rNode.Len());
995 assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
996 if (!nLen)
997 {
998 return TextFrameIndex(0);
999 }
1000 OUStringBuffer text(rMerged.mergedText);
1001 sal_Int32 nTFIndex(0); // index used for insertion at the end
1002 sal_Int32 nInserted(0);
1003 bool bInserted(false);
1004 bool bFoundNode(false);
1005 auto itInsert(rMerged.extents.end());
1006 for (auto it = rMerged.extents.begin(); it != rMerged.extents.end(); ++it)
1007 {
1008 if (it->pNode == &rNode)
1009 {
1010 if (isRealInsert)
1011 {
1012 bFoundNode = true;
1013 if (it->nStart <= nIndex && nIndex <= it->nEnd)
1014 { // note: this can happen only once
1015 text.insert(nTFIndex + (nIndex - it->nStart),
1016 rNode.GetText().subView(nIndex, nLen));
1017 it->nEnd += nLen;
1018 nInserted = nLen;
1019 assert(!bInserted);
1020 bInserted = true;
1021 }
1022 else if (nIndex < it->nStart)
1023 {
1024 if (itInsert == rMerged.extents.end())
1025 {
1026 itInsert = it;
1027 }
1028 it->nStart += nLen;
1029 it->nEnd += nLen;
1030 }
1031 }
1032 else
1033 {
1034 assert(it == rMerged.extents.begin() || (it-1)->pNode != &rNode || (it-1)->nEnd < nIndex);
1035 if (nIndex + nLen < it->nStart)
1036 {
1037 itInsert = it;
1038 break;
1039 }
1040 if (nIndex < it->nStart)
1041 {
1042 text.insert(nTFIndex,
1043 rNode.GetText().subView(nIndex, it->nStart - nIndex));
1044 nInserted += it->nStart - nIndex;
1045 it->nStart = nIndex;
1046 bInserted = true;
1047 }
1048 assert(it->nStart <= nIndex);
1049 if (nIndex <= it->nEnd)
1050 {
1051 nTFIndex += it->nEnd - it->nStart;
1052 while (it->nEnd < nIndex + nLen)
1053 {
1054 auto *const pNext(
1055 (it+1) != rMerged.extents.end() && (it+1)->pNode == it->pNode
1056 ? &*(it+1)
1057 : nullptr);
1058 if (pNext && pNext->nStart <= nIndex + nLen)
1059 {
1060 text.insert(nTFIndex,
1061 rNode.GetText().subView(it->nEnd, pNext->nStart - it->nEnd));
1062 nTFIndex += pNext->nStart - it->nEnd;
1063 nInserted += pNext->nStart - it->nEnd;
1064 pNext->nStart = it->nStart;
1065 it = rMerged.extents.erase(it);
1066 }
1067 else
1068 {
1069 text.insert(nTFIndex,
1070 rNode.GetText().subView(it->nEnd, nIndex + nLen - it->nEnd));
1071 nTFIndex += nIndex + nLen - it->nEnd;
1072 nInserted += nIndex + nLen - it->nEnd;
1073 it->nEnd = nIndex + nLen;
1074 }
1075 }
1076 bInserted = true;
1077 break;
1078 }
1079 }
1080 }
1081 else if (rNode.GetIndex() < it->pNode->GetIndex() || bFoundNode)
1082 {
1083 if (itInsert == rMerged.extents.end())
1084 {
1085 itInsert = it;
1086 }
1087 break;
1088 }
1089 if (itInsert == rMerged.extents.end())
1090 {
1091 nTFIndex += it->nEnd - it->nStart;
1092 }
1093 }
1094// assert((bFoundNode || rMerged.extents.empty()) && "text node not found - why is it sending hints to us");
1095 if (!bInserted)
1096 { // must be in a gap
1097 rMerged.extents.emplace(itInsert, const_cast<SwTextNode*>(&rNode), nIndex, nIndex + nLen);
1098 text.insert(nTFIndex, rNode.GetText().subView(nIndex, nLen));
1099 nInserted = nLen;
1100 if (rMerged.extents.size() == 1 // also if it was empty!
1101 || rMerged.pParaPropsNode->GetIndex() < rNode.GetIndex())
1102 { // text inserted after current para-props node
1104 rMerged.pParaPropsNode = &const_cast<SwTextNode&>(rNode);
1106 }
1107 // called from SwRangeRedline::InvalidateRange()
1109 {
1110 const_cast<SwTextNode&>(rNode).SetRedlineMergeFlag(SwNode::Merge::NonFirst);
1111 }
1112 }
1113 rMerged.mergedText = text.makeStringAndClear();
1114 return TextFrameIndex(nInserted);
1115}
1116
1117// 1. if real delete => correct nStart/nEnd for full nLen
1118// 2. if rl delete => do not correct nStart/nEnd but just exclude deleted
1120 bool const isRealDelete,
1121 SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 const nLen)
1122{
1123 assert(nIndex <= rNode.Len());
1124 assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
1125 OUStringBuffer text(rMerged.mergedText);
1126 sal_Int32 nTFIndex(0);
1127 sal_Int32 nToDelete(nLen);
1128 sal_Int32 nDeleted(0);
1129 size_t nFoundNode(0);
1130 size_t nErased(0);
1131 auto it = rMerged.extents.begin();
1132 for (; it != rMerged.extents.end(); )
1133 {
1134 bool bErase(false);
1135 if (it->pNode == &rNode)
1136 {
1137 ++nFoundNode;
1138 if (nIndex + nToDelete < it->nStart)
1139 {
1140 nToDelete = 0;
1141 if (!isRealDelete)
1142 {
1143 break;
1144 }
1145 it->nStart -= nLen;
1146 it->nEnd -= nLen;
1147 }
1148 else
1149 {
1150 if (nIndex < it->nStart)
1151 {
1152 // do not adjust nIndex into the text frame index space!
1153 nToDelete -= it->nStart - nIndex;
1154 nIndex = it->nStart;
1155 // note: continue with the if check below, no else!
1156 }
1157 if (it->nStart <= nIndex && nIndex < it->nEnd)
1158 {
1159 sal_Int32 const nDeleteHere(nIndex + nToDelete <= it->nEnd
1160 ? nToDelete
1161 : it->nEnd - nIndex);
1162 text.remove(nTFIndex + (nIndex - it->nStart), nDeleteHere);
1163 bErase = nDeleteHere == it->nEnd - it->nStart;
1164 if (bErase)
1165 {
1166 ++nErased;
1167 assert(it->nStart == nIndex);
1168 it = rMerged.extents.erase(it);
1169 }
1170 else if (isRealDelete)
1171 { // adjust for deleted text
1172 it->nStart -= (nLen - nToDelete);
1173 it->nEnd -= (nLen - nToDelete + nDeleteHere);
1174 if (it != rMerged.extents.begin()
1175 && (it-1)->pNode == &rNode
1176 && (it-1)->nEnd == it->nStart)
1177 { // merge adjacent extents
1178 nTFIndex += it->nEnd - it->nStart;
1179 (it-1)->nEnd = it->nEnd;
1180 it = rMerged.extents.erase(it);
1181 bErase = true; // skip increment
1182 }
1183 }
1184 else
1185 { // exclude text marked as deleted
1186 if (nIndex + nDeleteHere == it->nEnd)
1187 {
1188 it->nEnd -= nDeleteHere;
1189 }
1190 else
1191 {
1192 if (nIndex == it->nStart)
1193 {
1194 it->nStart += nDeleteHere;
1195 }
1196 else
1197 {
1198 sal_Int32 const nOldEnd(it->nEnd);
1199 it->nEnd = nIndex;
1200 it = rMerged.extents.emplace(it+1,
1201 it->pNode, nIndex + nDeleteHere, nOldEnd);
1202 }
1203 assert(nDeleteHere == nToDelete);
1204 }
1205 }
1206 nDeleted += nDeleteHere;
1207 nToDelete -= nDeleteHere;
1208 nIndex += nDeleteHere;
1209 if (!isRealDelete && nToDelete == 0)
1210 {
1211 break;
1212 }
1213 }
1214 }
1215 }
1216 else if (nFoundNode != 0)
1217 {
1218 break;
1219 }
1220 if (!bErase)
1221 {
1222 nTFIndex += it->nEnd - it->nStart;
1223 ++it;
1224 }
1225 }
1226// assert(nFoundNode != 0 && "text node not found - why is it sending hints to us");
1227 assert(nIndex <= rNode.Len() + nLen);
1228 // if there's a remaining deletion, it must be in gap at the end of the node
1229// can't do: might be last one in node was erased assert(nLen == 0 || rMerged.empty() || (it-1)->nEnd <= nIndex);
1230 // note: if first node gets deleted then that must call DelFrames as
1231 // pFirstNode is never updated
1232 if (nErased && nErased == nFoundNode)
1233 { // all visible text from node was erased
1234#if 1
1235 if (rMerged.pParaPropsNode == &rNode)
1236 {
1238 rMerged.pParaPropsNode = rMerged.extents.empty()
1239 ? const_cast<SwTextNode*>(rMerged.pLastNode)
1240 : rMerged.extents.front().pNode;
1242 }
1243#endif
1244// NOPE must listen on all non-hidden nodes; particularly on pLastNode rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode));
1245 }
1246 rMerged.mergedText = text.makeStringAndClear();
1247 return TextFrameIndex(nDeleted);
1248}
1249
1250std::pair<SwTextNode*, sal_Int32>
1251MapViewToModel(MergedPara const& rMerged, TextFrameIndex const i_nIndex)
1252{
1253 sal_Int32 nIndex(i_nIndex);
1254 sw::Extent const* pExtent(nullptr);
1255 for (const auto& rExt : rMerged.extents)
1256 {
1257 pExtent = &rExt;
1258 if (nIndex < (pExtent->nEnd - pExtent->nStart))
1259 {
1260 return std::make_pair(pExtent->pNode, pExtent->nStart + nIndex);
1261 }
1262 nIndex = nIndex - (pExtent->nEnd - pExtent->nStart);
1263 }
1264 assert(nIndex == 0 && "view index out of bounds");
1265 return pExtent
1266 ? std::make_pair(pExtent->pNode, pExtent->nEnd) //1-past-the-end index
1267 : std::make_pair(const_cast<SwTextNode*>(rMerged.pLastNode), rMerged.pLastNode->Len());
1268}
1269
1270TextFrameIndex MapModelToView(MergedPara const& rMerged, SwTextNode const*const pNode, sal_Int32 const nIndex)
1271{
1272 assert(rMerged.pFirstNode->GetIndex() <= pNode->GetIndex()
1273 && pNode->GetIndex() <= rMerged.pLastNode->GetIndex());
1274 sal_Int32 nRet(0);
1275 bool bFoundNode(false);
1276 for (auto const& e : rMerged.extents)
1277 {
1278 if (pNode->GetIndex() < e.pNode->GetIndex())
1279 {
1280 return TextFrameIndex(nRet);
1281 }
1282 if (e.pNode == pNode)
1283 {
1284 if (e.nStart <= nIndex && nIndex <= e.nEnd)
1285 {
1286 return TextFrameIndex(nRet + (nIndex - e.nStart));
1287 }
1288 else if (nIndex < e.nStart)
1289 {
1290 // in gap before this extent => map to 0 here TODO???
1291 return TextFrameIndex(nRet);
1292 }
1293 bFoundNode = true;
1294 }
1295 else if (bFoundNode)
1296 {
1297 break;
1298 }
1299 nRet += e.nEnd - e.nStart;
1300 }
1301 if (bFoundNode)
1302 {
1303 // must be in a gap at the end of the node
1304 assert(nIndex <= pNode->Len());
1305 return TextFrameIndex(nRet);
1306 }
1307 else if (rMerged.extents.empty())
1308 {
1309 assert(nIndex <= pNode->Len());
1310 return TextFrameIndex(0);
1311 }
1312 return TextFrameIndex(rMerged.mergedText.getLength());
1313}
1314
1315} // namespace sw
1316
1317std::pair<SwTextNode*, sal_Int32>
1319{
1320//nope assert(GetPara());
1321 sw::MergedPara const*const pMerged(GetMergedPara());
1322 if (pMerged)
1323 {
1324 return sw::MapViewToModel(*pMerged, nIndex);
1325 }
1326 else
1327 {
1328 return std::make_pair(static_cast<SwTextNode*>(const_cast<sw::BroadcastingModify*>(
1329 SwFrame::GetDep())), sal_Int32(nIndex));
1330 }
1331}
1332
1334{
1335 std::pair<SwTextNode*, sal_Int32> const ret(MapViewToModel(nIndex));
1336 return SwPosition(*ret.first, ret.second);
1337}
1338
1339TextFrameIndex SwTextFrame::MapModelToView(SwTextNode const*const pNode, sal_Int32 const nIndex) const
1340{
1341//nope assert(GetPara());
1342 sw::MergedPara const*const pMerged(GetMergedPara());
1343 if (pMerged)
1344 {
1345 return sw::MapModelToView(*pMerged, pNode, nIndex);
1346 }
1347 else
1348 {
1349 assert(static_cast<const SwTextNode*>(SwFrame::GetDep()) == pNode);
1350 return TextFrameIndex(nIndex);
1351 }
1352}
1353
1355{
1356 SwTextNode const*const pNode(rPos.GetNode().GetTextNode());
1357 sal_Int32 const nIndex(rPos.GetContentIndex());
1358 return MapModelToView(pNode, nIndex);
1359}
1360
1361void SwTextFrame::SetMergedPara(std::unique_ptr<sw::MergedPara> p)
1362{
1363 SwTextNode *const pFirst(m_pMergedPara ? m_pMergedPara->pFirstNode : nullptr);
1364 m_pMergedPara = std::move(p);
1365 if (pFirst)
1366 {
1367 if (m_pMergedPara)
1368 {
1369 assert(pFirst == m_pMergedPara->pFirstNode);
1370 }
1371 else
1372 {
1373 pFirst->Add(this); // must register at node again
1374 }
1375 }
1376 // postcondition: frame must be listening somewhere
1377 assert(m_pMergedPara || GetDep());
1378}
1379
1380const OUString& SwTextFrame::GetText() const
1381{
1382//nope assert(GetPara());
1383 sw::MergedPara const*const pMerged(GetMergedPara());
1384 if (pMerged)
1385 return pMerged->mergedText;
1386 else
1387 return static_cast<SwTextNode const*>(SwFrame::GetDep())->GetText();
1388}
1389
1391{
1392 // FIXME can GetPara be 0 ? yes... this is needed in SwContentNotify::SwContentNotify() which is called before any formatting is started
1393//nope assert(GetPara());
1394 sw::MergedPara const*const pMerged(GetMergedPara());
1395 if (pMerged)
1396 {
1397// assert(pMerged->pFirstNode == pMerged->pParaPropsNode); // surprising news!
1398 return pMerged->pParaPropsNode;
1399 }
1400 else
1401 return static_cast<SwTextNode const*>(SwFrame::GetDep());
1402}
1403
1405{
1406 sw::MergedPara const*const pMerged(GetMergedPara());
1407 if (pMerged)
1408 return pMerged->extents.empty()
1409 ? pMerged->pFirstNode
1410 : pMerged->extents.front().pNode;
1411 else
1412 return static_cast<SwTextNode const*>(SwFrame::GetDep());
1413}
1414
1416{
1417//nope assert(GetPara());
1418 sw::MergedPara const*const pMerged(GetMergedPara());
1419 if (pMerged)
1420 return pMerged->pFirstNode;
1421 else
1422 return static_cast<SwTextNode const*>(SwFrame::GetDep());
1423}
1424
1426{
1427 return GetTextNodeFirst()->GetDoc();
1428}
1429
1431 sal_uInt16 const nScript, bool const bNoChar) const
1432{
1433 // a single character can be mapped uniquely!
1434 std::pair<SwTextNode const*, sal_Int32> const pos(MapViewToModel(nIndex));
1435 return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript);
1436}
1437
1439{
1440 if ( GetCacheIdx() != USHRT_MAX )
1441 {
1442 if (SwParaPortion *pPara = GetPara())
1443 pPara->ResetPreps();
1444 }
1445}
1446
1448{
1449 SwFrameSwapper aSwapper( this, true );
1450
1451 if( !getFrameArea().Width() && isFrameAreaDefinitionValid() && GetUpper()->isFrameAreaDefinitionValid() ) // invalid when stack overflows (StackHack)!
1452 {
1453// OSL_FAIL( "SwTextFrame::IsHiddenNow: thin frame" );
1454 return true;
1455 }
1456
1457 bool bHiddenCharsHidePara(false);
1458 bool bHiddenParaField(false);
1459 if (m_pMergedPara)
1460 {
1461 TextFrameIndex nHiddenStart(COMPLETE_STRING);
1462 TextFrameIndex nHiddenEnd(0);
1463 if (auto const pScriptInfo = GetScriptInfo())
1464 {
1465 pScriptInfo->GetBoundsOfHiddenRange(TextFrameIndex(0),
1466 nHiddenStart, nHiddenEnd);
1467 }
1468 else // ParaPortion is created in Format, but this is called earlier
1469 {
1470 SwScriptInfo aInfo;
1471 aInfo.InitScriptInfo(*m_pMergedPara->pFirstNode, m_pMergedPara.get(), IsRightToLeft());
1473 nHiddenStart, nHiddenEnd);
1474 }
1475 if (TextFrameIndex(0) == nHiddenStart &&
1476 TextFrameIndex(GetText().getLength()) <= nHiddenEnd)
1477 {
1478 bHiddenCharsHidePara = true;
1479 }
1480 sw::MergedAttrIter iter(*this);
1481 SwTextNode const* pNode(nullptr);
1482 int nNewResultWeight = 0;
1483 for (SwTextAttr const* pHint = iter.NextAttr(&pNode); pHint; pHint = iter.NextAttr(&pNode))
1484 {
1485 if (pHint->Which() == RES_TXTATR_FIELD)
1486 {
1487 // see also SwpHints::CalcHiddenParaField()
1488 const SwFormatField& rField = pHint->GetFormatField();
1489 int nCurWeight = pNode->GetDoc().FieldCanHideParaWeight(rField.GetField()->GetTyp()->Which());
1490 if (nCurWeight > nNewResultWeight)
1491 {
1492 nNewResultWeight = nCurWeight;
1493 bHiddenParaField = pNode->GetDoc().FieldHidesPara(*rField.GetField());
1494 }
1495 else if (nCurWeight == nNewResultWeight && bHiddenParaField)
1496 {
1497 // Currently, for both supported hiding types (HiddenPara, Database), "Don't hide"
1498 // takes precedence - i.e., if there's a "Don't hide" field of that weight, we only
1499 // care about fields of higher weight.
1500 bHiddenParaField = pNode->GetDoc().FieldHidesPara(*rField.GetField());
1501 }
1502 }
1503 }
1504 }
1505 else
1506 {
1507 bHiddenCharsHidePara = static_cast<SwTextNode const*>(SwFrame::GetDep())->HasHiddenCharAttribute( true );
1508 bHiddenParaField = static_cast<SwTextNode const*>(SwFrame::GetDep())->IsHiddenByParaField();
1509 }
1510 const SwViewShell* pVsh = getRootFrame()->GetCurrShell();
1511
1512 if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
1513 {
1514
1515 if (
1516 ( bHiddenParaField &&
1517 ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
1518 !pVsh->GetViewOptions()->IsFieldName() ) ) ||
1519 ( bHiddenCharsHidePara &&
1520 !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
1521 {
1522 // in order to put the cursor in the body text, one paragraph must
1523 // be visible - check this for the 1st body paragraph
1524 if (IsInDocBody() && FindPrevCnt() == nullptr)
1525 {
1526 bool isAllHidden(true);
1527 for (SwContentFrame const* pNext = FindNextCnt(true);
1528 pNext != nullptr; pNext = pNext->FindNextCnt(true))
1529 {
1530 if (!pNext->IsTextFrame()
1531 || !static_cast<SwTextFrame const*>(pNext)->IsHiddenNow())
1532 {
1533 isAllHidden = false;
1534 break;
1535 }
1536 }
1537 if (isAllHidden)
1538 {
1539 SAL_INFO("sw.core", "unhiding one body paragraph");
1540 return false;
1541 }
1542 }
1543 return true;
1544 }
1545 }
1546
1547 return false;
1548}
1549
1552{
1553 OSL_ENSURE( !GetFollow() && IsHiddenNow(),
1554 "HideHidden on visible frame of hidden frame has follow" );
1555
1558
1559 // format information is obsolete
1560 ClearPara();
1561}
1562
1564{
1565 SwPageFrame *pPage = nullptr;
1566 sw::MergedAttrIter iter(*this);
1567 SwTextNode const* pNode(nullptr);
1568 for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
1569 {
1570 if (pHt->Which() == RES_TXTATR_FTN)
1571 {
1572 TextFrameIndex const nIdx(MapModelToView(pNode, pHt->GetStart()));
1573 if (nEnd < nIdx)
1574 break;
1575 if (nStart <= nIdx)
1576 {
1577 if (!pPage)
1578 pPage = FindPageFrame();
1579 pPage->RemoveFootnote( this, static_cast<const SwTextFootnote*>(pHt) );
1580 }
1581 }
1582 }
1583}
1584
1594bool sw_HideObj( const SwTextFrame& _rFrame,
1595 const RndStdIds _eAnchorType,
1596 SwFormatAnchor const& rFormatAnchor,
1597 SwAnchoredObject* _pAnchoredObj )
1598{
1599 bool bRet( true );
1600
1601 if (_eAnchorType == RndStdIds::FLY_AT_CHAR)
1602 {
1603 const IDocumentSettingAccess *const pIDSA = &_rFrame.GetDoc().getIDocumentSettingAccess();
1608 _rFrame.IsInDocBody() && !_rFrame.FindNextCnt() )
1609 {
1610 SwTextNode const& rNode(*rFormatAnchor.GetAnchorNode()->GetTextNode());
1611 assert(FrameContainsNode(_rFrame, rNode.GetIndex()));
1612 sal_Int32 const nObjAnchorPos(rFormatAnchor.GetAnchorContentOffset());
1613 const sal_Unicode cAnchorChar = nObjAnchorPos < rNode.Len()
1614 ? rNode.GetText()[nObjAnchorPos]
1615 : 0;
1616 if (cAnchorChar == CH_TXTATR_BREAKWORD)
1617 {
1618 const SwTextAttr* const pHint(
1619 rNode.GetTextAttrForCharAt(nObjAnchorPos, RES_TXTATR_FLYCNT));
1620 if ( pHint )
1621 {
1622 const SwFrameFormat* pFrameFormat =
1623 static_cast<const SwTextFlyCnt*>(pHint)->GetFlyCnt().GetFrameFormat();
1624 if ( pFrameFormat->Which() == RES_FLYFRMFMT )
1625 {
1626 SwNodeIndex nContentIndex = *(pFrameFormat->GetContent().GetContentIdx());
1627 ++nContentIndex;
1628 if ( nContentIndex.GetNode().IsNoTextNode() )
1629 {
1630 bRet = false;
1631 // set needed data structure values for object positioning
1632 SwRectFnSet aRectFnSet(&_rFrame);
1633 SwRect aLastCharRect( _rFrame.getFrameArea() );
1634 aRectFnSet.SetWidth( aLastCharRect, 1 );
1635 _pAnchoredObj->maLastCharRect = aLastCharRect;
1636 _pAnchoredObj->mnLastTopOfLine = aRectFnSet.GetTop(aLastCharRect);
1637 }
1638 }
1639 }
1640 }
1641 }
1642 }
1643
1644 return bRet;
1645}
1646
1658{
1659 if ( GetDrawObjs() )
1660 {
1661 if ( IsHiddenNow() )
1662 {
1663 // complete paragraph is hidden. Thus, hide all objects
1664 for (SwAnchoredObject* i : *GetDrawObjs())
1665 {
1666 SdrObject* pObj = i->DrawObj();
1667 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
1668 // under certain conditions
1669 const RndStdIds eAnchorType( pContact->GetAnchorId() );
1670 if ((eAnchorType != RndStdIds::FLY_AT_CHAR) ||
1671 sw_HideObj(*this, eAnchorType, pContact->GetAnchorFormat(),
1672 i ))
1673 {
1674 pContact->MoveObjToInvisibleLayer( pObj );
1675 }
1676 }
1677 }
1678 else
1679 {
1680 // paragraph is visible, but can contain hidden text portion.
1681 // first we check if objects are allowed to be hidden:
1682 const SwViewShell* pVsh = getRootFrame()->GetCurrShell();
1683 const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
1684 !pVsh->GetViewOptions()->IsShowHiddenChar();
1685
1686 // Thus, show all objects, which are anchored at paragraph and
1687 // hide/show objects, which are anchored at/as character, according
1688 // to the visibility of the anchor character.
1689 for (SwAnchoredObject* i : *GetDrawObjs())
1690 {
1691 SdrObject* pObj = i->DrawObj();
1692 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
1693 // Determine anchor type only once
1694 const RndStdIds eAnchorType( pContact->GetAnchorId() );
1695
1696 if (eAnchorType == RndStdIds::FLY_AT_PARA)
1697 {
1698 pContact->MoveObjToVisibleLayer( pObj );
1699 }
1700 else if ((eAnchorType == RndStdIds::FLY_AT_CHAR) ||
1701 (eAnchorType == RndStdIds::FLY_AS_CHAR))
1702 {
1703 sal_Int32 nHiddenStart;
1704 sal_Int32 nHiddenEnd;
1705 const SwFormatAnchor& rAnchorFormat = pContact->GetAnchorFormat();
1707 *rAnchorFormat.GetAnchorNode()->GetTextNode(),
1708 rAnchorFormat.GetAnchorContentOffset(), nHiddenStart, nHiddenEnd);
1709 // Under certain conditions
1710 if ( nHiddenStart != COMPLETE_STRING && bShouldBeHidden &&
1711 sw_HideObj(*this, eAnchorType, rAnchorFormat, i))
1712 {
1713 pContact->MoveObjToInvisibleLayer( pObj );
1714 }
1715 else
1716 pContact->MoveObjToVisibleLayer( pObj );
1717 }
1718 else
1719 {
1720 OSL_FAIL( "<SwTextFrame::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
1721 }
1722 }
1723 }
1724 }
1725
1726 if (IsFollow())
1727 {
1728 SwTextFrame *pMaster = FindMaster();
1729 OSL_ENSURE(pMaster, "SwTextFrame without master");
1730 if (pMaster)
1731 pMaster->HideAndShowObjects();
1732 }
1733}
1734
1741TextFrameIndex SwTextFrame::FindBrk(std::u16string_view aText,
1742 const TextFrameIndex nStart,
1743 const TextFrameIndex nEnd)
1744{
1745 sal_Int32 nFound = sal_Int32(nStart);
1746 const sal_Int32 nEndLine = std::min(sal_Int32(nEnd), sal_Int32(aText.size()) - 1);
1747
1748 // Skip all leading blanks.
1749 while( nFound <= nEndLine && ' ' == aText[nFound] )
1750 {
1751 nFound++;
1752 }
1753
1754 // A tricky situation with the TextAttr-Dummy-character (in this case "$"):
1755 // "Dr.$Meyer" at the beginning of the second line. Typing a blank after that
1756 // doesn't result in the word moving into first line, even though that would work.
1757 // For this reason we don't skip the dummy char.
1758 while( nFound <= nEndLine && ' ' != aText[nFound] )
1759 {
1760 nFound++;
1761 }
1762
1763 return TextFrameIndex(nFound);
1764}
1765
1767{
1768 if (nPos == TextFrameIndex(COMPLETE_STRING)) // the "not found" range
1769 return false;
1770// Silence over-eager warning emitted at least by GCC trunk towards 6:
1771#if defined __GNUC__ && !defined __clang__
1772#pragma GCC diagnostic push
1773#pragma GCC diagnostic ignored "-Wstrict-overflow"
1774#endif
1775 if (nLen != TextFrameIndex(COMPLETE_STRING) && GetOffset() > nPos + nLen) // the range preceded us
1776#if defined __GNUC__ && !defined __clang__
1777#pragma GCC diagnostic pop
1778#endif
1779 return false;
1780
1781 if( !GetFollow() ) // the range doesn't precede us,
1782 return true; // nobody follows us.
1783
1784 TextFrameIndex const nMax = GetFollow()->GetOffset();
1785
1786 // either the range overlap or our text has been deleted
1787 // sw_redlinehide: GetText() should be okay here because it has already
1788 // been updated in the INS/DEL hint case
1789 if (nMax > nPos || nMax > TextFrameIndex(GetText().getLength()))
1790 return true;
1791
1792 // changes made in the first line of a follow can modify the master
1793 const SwParaPortion* pPara = GetFollow()->GetPara();
1794 return pPara && ( nPos <= nMax + pPara->GetLen() );
1795}
1796
1797inline void SwTextFrame::InvalidateRange(const SwCharRange &aRange, const tools::Long nD)
1798{
1799 if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
1800 InvalidateRange_( aRange, nD );
1801}
1802
1804{
1805 if ( !HasPara() )
1806 { InvalidateSize();
1807 return;
1808 }
1809
1810 SetWidow( false );
1811 SwParaPortion *pPara = GetPara();
1812
1813 bool bInv = false;
1814 if( 0 != nD )
1815 {
1816 // In nDelta the differences between old and new
1817 // linelengths are being added, that's why it's negative
1818 // if chars have been added and positive, if chars have
1819 // deleted
1820 pPara->SetDelta(pPara->GetDelta() + nD);
1821 bInv = true;
1822 }
1823 SwCharRange &rReformat = pPara->GetReformat();
1824 if(aRange != rReformat) {
1825 if (TextFrameIndex(COMPLETE_STRING) == rReformat.Len())
1826 rReformat = aRange;
1827 else
1828 rReformat += aRange;
1829 bInv = true;
1830 }
1831 if(bInv)
1832 {
1834 }
1835}
1836
1838{
1839 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
1840 "SwTextFrame::CalcLineSpace with swapped frame!" );
1841
1842 if( IsLocked() || !HasPara() )
1843 return;
1844
1845 if( GetDrawObjs() ||
1846 GetTextNodeForParaProps()->GetSwAttrSet().GetFirstLineIndent().IsAutoFirst())
1847 {
1848 Init();
1849 return;
1850 }
1851
1852 SwParaPortion *const pPara(GetPara());
1853 assert(pPara);
1854 if (pPara->IsFixLineHeight())
1855 {
1856 Init();
1857 return;
1858 }
1859
1860 Size aNewSize( getFramePrintArea().SSize() );
1861
1862 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this );
1863 SwTextFormatter aLine( this, &aInf );
1864 if( aLine.GetDropLines() )
1865 {
1866 Init();
1867 return;
1868 }
1869
1870 aLine.Top();
1871 aLine.RecalcRealHeight();
1872
1873 aNewSize.setHeight( (aLine.Y() - getFrameArea().Top()) + aLine.GetLineHeight() );
1874
1875 SwTwips nDelta = aNewSize.Height() - getFramePrintArea().Height();
1876 // Underflow with free-flying frames
1877 if( aInf.GetTextFly().IsOn() )
1878 {
1879 SwRect aTmpFrame( getFrameArea() );
1880 if( nDelta < 0 )
1881 aTmpFrame.Height( getFramePrintArea().Height() );
1882 else
1883 aTmpFrame.Height( aNewSize.Height() );
1884 if( aInf.GetTextFly().Relax( aTmpFrame ) )
1885 {
1886 Init();
1887 return;
1888 }
1889 }
1890
1891 if( !nDelta )
1892 return;
1893
1894 SwTextFrameBreak aBreak( this );
1895 if( GetFollow() || aBreak.IsBreakNow( aLine ) )
1896 {
1897 // if there is a Follow() or if we need to break here, reformat
1898 Init();
1899 }
1900 else
1901 {
1902 // everything is business as usual...
1903 pPara->SetPrepAdjust();
1904 pPara->SetPrep();
1905 }
1906}
1907
1908static void lcl_SetWrong( SwTextFrame& rFrame, SwTextNode const& rNode,
1909 sal_Int32 const nPos, sal_Int32 const nCnt, bool const bMove)
1910{
1911 if ( !rFrame.IsFollow() )
1912 {
1913 SwTextNode& rTextNode = const_cast<SwTextNode&>(rNode);
1914 sw::GrammarContact* pGrammarContact = sw::getGrammarContactFor(rTextNode);
1915 SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
1916 pGrammarContact->getGrammarCheck( rTextNode, false ) :
1917 rTextNode.GetGrammarCheck();
1918 bool bGrammarProxy = pWrongGrammar != rTextNode.GetGrammarCheck();
1919 if( bMove )
1920 {
1921 if( rTextNode.GetWrong() )
1922 rTextNode.GetWrong()->Move( nPos, nCnt );
1923 if( pWrongGrammar )
1924 pWrongGrammar->MoveGrammar( nPos, nCnt );
1925 if( bGrammarProxy && rTextNode.GetGrammarCheck() )
1926 rTextNode.GetGrammarCheck()->MoveGrammar( nPos, nCnt );
1927 if( rTextNode.GetSmartTags() )
1928 rTextNode.GetSmartTags()->Move( nPos, nCnt );
1929 }
1930 else
1931 {
1932 if( rTextNode.GetWrong() )
1933 rTextNode.GetWrong()->Invalidate( nPos, nCnt );
1934 if( pWrongGrammar )
1935 pWrongGrammar->Invalidate( nPos, nCnt );
1936 if( rTextNode.GetSmartTags() )
1937 rTextNode.GetSmartTags()->Invalidate( nPos, nCnt );
1938 }
1939 const sal_Int32 nEnd = nPos + (nCnt > 0 ? nCnt : 1 );
1940 if ( !rTextNode.GetWrong() && !rTextNode.IsWrongDirty() )
1941 {
1942 rTextNode.SetWrong( std::make_unique<SwWrongList>( WRONGLIST_SPELL ) );
1943 rTextNode.GetWrong()->SetInvalid( nPos, nEnd );
1944 }
1945 if ( !rTextNode.GetSmartTags() && !rTextNode.IsSmartTagDirty() )
1946 {
1947 rTextNode.SetSmartTags( std::make_unique<SwWrongList>( WRONGLIST_SMARTTAG ) );
1948 rTextNode.GetSmartTags()->SetInvalid( nPos, nEnd );
1949 }
1951 rTextNode.SetGrammarCheckDirty( true );
1952 rTextNode.SetWordCountDirty( true );
1953 rTextNode.SetAutoCompleteWordDirty( true );
1954 rTextNode.SetSmartTagDirty( true );
1955 }
1956
1957 SwRootFrame *pRootFrame = rFrame.getRootFrame();
1958 if (pRootFrame)
1959 {
1960 pRootFrame->SetNeedGrammarCheck( true );
1961 }
1962
1963 SwPageFrame *pPage = rFrame.FindPageFrame();
1964 if( pPage )
1965 {
1966 pPage->InvalidateSpelling();
1968 pPage->InvalidateWordCount();
1969 pPage->InvalidateSmartTags();
1970 }
1971}
1972
1973static void lcl_SetScriptInval(SwTextFrame& rFrame, TextFrameIndex const nPos)
1974{
1975 if( rFrame.GetPara() )
1977}
1978
1979// note: SwClientNotify will be called once for every frame => just fix own Ofst
1980static void lcl_ModifyOfst(SwTextFrame & rFrame,
1981 TextFrameIndex const nPos, TextFrameIndex const nLen,
1982 TextFrameIndex (* op)(TextFrameIndex const&, TextFrameIndex const&))
1983{
1984 assert(nLen != TextFrameIndex(COMPLETE_STRING));
1985 if (rFrame.IsFollow() && nPos < rFrame.GetOffset())
1986 {
1987 rFrame.ManipOfst( std::max(nPos, op(rFrame.GetOffset(), nLen)) );
1988 assert(sal_Int32(rFrame.GetOffset()) <= rFrame.GetText().getLength());
1989 }
1990}
1991
1992namespace {
1993
1994void UpdateMergedParaForMove(sw::MergedPara & rMerged,
1995 SwTextFrame & rTextFrame,
1996 bool & o_rbRecalcFootnoteFlag,
1997 SwTextNode const& rDestNode,
1998 SwTextNode const& rNode,
1999 sal_Int32 const nDestStart,
2000 sal_Int32 const nSourceStart,
2001 sal_Int32 const nLen)
2002{
2003 std::vector<std::pair<sal_Int32, sal_Int32>> deleted;
2004 sal_Int32 const nSourceEnd(nSourceStart + nLen);
2005 sal_Int32 nLastEnd(0);
2006 for (const auto& rExt : rMerged.extents)
2007 {
2008 if (rExt.pNode == &rNode)
2009 {
2010 sal_Int32 const nStart(std::max(nLastEnd, nSourceStart));
2011 sal_Int32 const nEnd(std::min(rExt.nStart, nSourceEnd));
2012 if (nStart < nEnd)
2013 {
2014 deleted.emplace_back(nStart, nEnd);
2015 }
2016 nLastEnd = rExt.nEnd;
2017 if (nSourceEnd <= rExt.nEnd)
2018 {
2019 break;
2020 }
2021 }
2022 else if (rNode.GetIndex() < rExt.pNode->GetIndex())
2023 {
2024 break;
2025 }
2026 }
2027 if (nLastEnd != rNode.Len()) // without nLen, string yet to be removed
2028 {
2029 if (nLastEnd < nSourceEnd)
2030 {
2031 deleted.emplace_back(std::max(nLastEnd, nSourceStart), nSourceEnd);
2032 }
2033 }
2034 if (deleted.empty())
2035 return;
2036
2037 o_rbRecalcFootnoteFlag = true;
2038 for (auto const& it : deleted)
2039 {
2040 sal_Int32 const nStart(it.first - nSourceStart + nDestStart);
2041 TextFrameIndex const nDeleted = UpdateMergedParaForDelete(rMerged, false,
2042 rDestNode, nStart, it.second - it.first);
2043//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);
2044// assert(nDeleted == it.second - it.first);
2045 if(nDeleted)
2046 {
2047 // InvalidateRange/lcl_SetScriptInval was called sufficiently for InsertText
2048 lcl_SetWrong(rTextFrame, rDestNode, nStart, it.first - it.second, false);
2049 TextFrameIndex const nIndex(sw::MapModelToView(rMerged, &rDestNode, nStart));
2050 lcl_ModifyOfst(rTextFrame, nIndex, nDeleted, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2051 }
2052 }
2053}
2054
2055} // namespace
2056
2061#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2062static bool isA11yRelevantAttribute(sal_uInt16 nWhich)
2063{
2064 return nWhich != RES_CHRATR_RSID;
2065}
2066
2067static bool hasA11yRelevantAttribute( const std::vector<sal_uInt16>& rWhichFmtAttr )
2068{
2069 for( sal_uInt16 nWhich : rWhichFmtAttr )
2070 if ( isA11yRelevantAttribute( nWhich ) )
2071 return true;
2072
2073 return false;
2074}
2075#endif // ENABLE_WASM_STRIP_ACCESSIBILITY
2076
2077// Note: for now this overrides SwClient::SwClientNotify; the intermediary
2078// classes still override SwClient::Modify, which should continue to work
2079// as their implementation of SwClientNotify is SwClient's which calls Modify.
2080// Therefore we also don't need to call SwClient::SwClientNotify(rModify, rHint)
2081// because that's all it does, and this implementation calls
2082// SwContentFrame::SwClientNotify() when appropriate.
2083void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint)
2084{
2085 SfxPoolItem const* pOld(nullptr);
2086 SfxPoolItem const* pNew(nullptr);
2087 sw::MoveText const* pMoveText(nullptr);
2088 sw::InsertText const* pInsertText(nullptr);
2089 sw::DeleteText const* pDeleteText(nullptr);
2090 sw::DeleteChar const* pDeleteChar(nullptr);
2091 sw::RedlineDelText const* pRedlineDelText(nullptr);
2092 sw::RedlineUnDelText const* pRedlineUnDelText(nullptr);
2093
2094 sal_uInt16 nWhich = 0;
2095 if (rHint.GetId() == SfxHintId::SwLegacyModify)
2096 {
2097 auto pHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
2098 pOld = pHint->m_pOld;
2099 pNew = pHint->m_pNew;
2100 nWhich = pHint->GetWhich();
2101 }
2102 else if (rHint.GetId() == SfxHintId::SwInsertText)
2103 {
2104 pInsertText = static_cast<const sw::InsertText*>(&rHint);
2105 }
2106 else if (rHint.GetId() == SfxHintId::SwDeleteText)
2107 {
2108 pDeleteText = static_cast<const sw::DeleteText*>(&rHint);
2109 }
2110 else if (rHint.GetId() == SfxHintId::SwDeleteChar)
2111 {
2112 pDeleteChar = static_cast<const sw::DeleteChar*>(&rHint);
2113 }
2114 else if (rHint.GetId() == SfxHintId::SwDocPosUpdateAtIndex)
2115 {
2116 auto pDocPosAt = static_cast<const sw::DocPosUpdateAtIndex*>(&rHint);
2117 Broadcast(SfxHint()); // notify SwAccessibleParagraph
2118 if(IsLocked())
2119 return;
2120 if(pDocPosAt->m_nDocPos > getFrameArea().Top())
2121 return;
2123 &pDocPosAt->m_rNode,
2124 pDocPosAt->m_nIndex));
2126 return;
2127 }
2128 else if (auto const pHt = dynamic_cast<sw::MoveText const*>(&rHint))
2129 {
2130 pMoveText = pHt;
2131 }
2132 else if (auto const pHynt = dynamic_cast<sw::RedlineDelText const*>(&rHint))
2133 {
2134 pRedlineDelText = pHynt;
2135 }
2136 else if (auto const pHnt = dynamic_cast<sw::RedlineUnDelText const*>(&rHint))
2137 {
2138 pRedlineUnDelText = pHnt;
2139 }
2140 else
2141 {
2142 assert(!"unexpected hint");
2143 }
2144
2145 if (m_pMergedPara)
2146 {
2147 assert(m_pMergedPara->listener.IsListeningTo(&rModify));
2148 }
2149
2150 SwTextNode const& rNode(static_cast<SwTextNode const&>(rModify));
2151
2152 // modifications concerning frame attributes are processed by the base class
2153 if( IsInRange( aFrameFormatSetRange, nWhich ) || RES_FMT_CHG == nWhich )
2154 {
2155 if (m_pMergedPara)
2156 { // ignore item set changes that don't apply
2157 SwTextNode const*const pAttrNode(
2158 (nWhich == RES_PAGEDESC || nWhich == RES_BREAK)
2159 ? m_pMergedPara->pFirstNode
2160 : m_pMergedPara->pParaPropsNode);
2161 if (pAttrNode != &rModify)
2162 {
2163 return;
2164 }
2165 }
2167 if( nWhich == RES_FMT_CHG && getRootFrame()->GetCurrShell() )
2168 {
2169 // collection has changed
2170 Prepare();
2172 lcl_SetWrong( *this, rNode, 0, COMPLETE_STRING, false );
2173 SetDerivedR2L( false );
2175 // Force complete paint due to existing indents.
2178 }
2179 return;
2180 }
2181
2182 if (m_pMergedPara && m_pMergedPara->pParaPropsNode != &rModify)
2183 {
2184 if (isPARATR(nWhich) || isPARATR_LIST(nWhich)) // FRMATR handled above
2185 {
2186 return; // ignore it
2187 }
2188 }
2189
2190 Broadcast(SfxHint()); // notify SwAccessibleParagraph
2191
2192 // while locked ignore all modifications
2193 if( IsLocked() )
2194 return;
2195
2196 // save stack
2197 // warning: one has to ensure that all variables are set
2199 TextFrameIndex nLen;
2200 bool bSetFieldsDirty = false;
2201 bool bRecalcFootnoteFlag = false;
2202
2203 if (pRedlineDelText)
2204 {
2205 if (m_pMergedPara)
2206 {
2207 sal_Int32 const nNPos = pRedlineDelText->nStart;
2208 sal_Int32 const nNLen = pRedlineDelText->nLen;
2209 nPos = MapModelToView(&rNode, nNPos);
2210 // update merged before doing anything else
2211 nLen = UpdateMergedParaForDelete(*m_pMergedPara, false, rNode, nNPos, nNLen);
2212 const sal_Int32 m = -nNLen;
2213 if (nLen && IsIdxInside(nPos, nLen))
2214 {
2216 }
2217 lcl_SetWrong( *this, rNode, nNPos, m, false );
2218 if (nLen)
2219 {
2220 lcl_SetScriptInval( *this, nPos );
2221 bSetFieldsDirty = bRecalcFootnoteFlag = true;
2222 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2223 }
2224 }
2225 }
2226 else if (pRedlineUnDelText)
2227 {
2228 if (m_pMergedPara)
2229 {
2230 sal_Int32 const nNPos = pRedlineUnDelText->nStart;
2231 sal_Int32 const nNLen = pRedlineUnDelText->nLen;
2232 nPos = MapModelToView(&rNode, nNPos);
2233 nLen = UpdateMergedParaForInsert(*m_pMergedPara, false, rNode, nNPos, nNLen);
2234 if (IsIdxInside(nPos, nLen))
2235 {
2236 if (!nLen)
2237 {
2238 // Refresh NumPortions even when line is empty!
2239 if (nPos)
2241 else
2242 Prepare();
2243 }
2244 else
2245 InvalidateRange_( SwCharRange( nPos, nLen ), nNLen );
2246 }
2247 lcl_SetWrong( *this, rNode, nNPos, nNLen, false );
2248 lcl_SetScriptInval( *this, nPos );
2249 bSetFieldsDirty = true;
2250 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator+<sal_Int32, Tag_TextFrameIndex>);
2251 }
2252 }
2253 else if (pMoveText)
2254 {
2255 if (m_pMergedPara
2256 && m_pMergedPara->pFirstNode->GetIndex() <= pMoveText->pDestNode->GetIndex()
2257 && pMoveText->pDestNode->GetIndex() <= m_pMergedPara->pLastNode->GetIndex())
2258 { // if it's not 2 nodes in merged frame, assume the target node doesn't have frames at all
2259 assert(abs(rNode.GetIndex() - pMoveText->pDestNode->GetIndex()) == SwNodeOffset(1));
2260 UpdateMergedParaForMove(*m_pMergedPara,
2261 *this,
2262 bRecalcFootnoteFlag,
2263 *pMoveText->pDestNode, rNode,
2264 pMoveText->nDestStart,
2265 pMoveText->nSourceStart,
2266 pMoveText->nLen);
2267 }
2268 else
2269 {
2270 // 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
2271 // assert(!m_pMergedPara || !getRootFrame()->IsHideRedlines() || !pMoveText->pDestNode->getLayoutFrame(getRootFrame()));
2272 }
2273 }
2274 else if (pInsertText)
2275 {
2276 nPos = MapModelToView(&rNode, pInsertText->nPos);
2277 // unlike redlines, inserting into fieldmark must be explicitly handled
2278 bool isHidden(false);
2279 switch (getRootFrame()->GetFieldmarkMode())
2280 {
2282 isHidden = pInsertText->isInsideFieldmarkResult;
2283 break;
2285 isHidden = pInsertText->isInsideFieldmarkCommand;
2286 break;
2287 case sw::FieldmarkMode::ShowBoth: // just to avoid the warning
2288 break;
2289 }
2290 if (!isHidden)
2291 {
2292 nLen = TextFrameIndex(pInsertText->nLen);
2293 if (m_pMergedPara)
2294 {
2295 UpdateMergedParaForInsert(*m_pMergedPara, true, rNode, pInsertText->nPos, pInsertText->nLen);
2296 }
2297 if( IsIdxInside( nPos, nLen ) )
2298 {
2299 if( !nLen )
2300 {
2301 // Refresh NumPortions even when line is empty!
2302 if( nPos )
2304 else
2305 Prepare();
2306 }
2307 else
2308 InvalidateRange_( SwCharRange( nPos, nLen ), pInsertText->nLen );
2309 }
2310 lcl_SetScriptInval( *this, nPos );
2311 bSetFieldsDirty = true;
2312 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator+<sal_Int32, Tag_TextFrameIndex>);
2313 }
2314 lcl_SetWrong( *this, rNode, pInsertText->nPos, pInsertText->nLen, true );
2315 }
2316 else if (pDeleteText)
2317 {
2318 nPos = MapModelToView(&rNode, pDeleteText->nStart);
2319 if (m_pMergedPara)
2320 { // update merged before doing anything else
2321 nLen = UpdateMergedParaForDelete(*m_pMergedPara, true, rNode, pDeleteText->nStart, pDeleteText->nLen);
2322 }
2323 else
2324 {
2325 nLen = TextFrameIndex(pDeleteText->nLen);
2326 }
2327 const sal_Int32 m = -pDeleteText->nLen;
2328 if ((!m_pMergedPara || nLen) && IsIdxInside(nPos, nLen))
2329 {
2330 if( !nLen )
2332 else
2334 }
2335 lcl_SetWrong( *this, rNode, pDeleteText->nStart, m, true );
2336 if (nLen)
2337 {
2338 lcl_SetScriptInval( *this, nPos );
2339 bSetFieldsDirty = bRecalcFootnoteFlag = true;
2340 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2341 }
2342 }
2343 else if (pDeleteChar)
2344 {
2345 nPos = MapModelToView(&rNode, pDeleteChar->m_nPos);
2346 if (m_pMergedPara)
2347 {
2348 nLen = UpdateMergedParaForDelete(*m_pMergedPara, true, rNode, pDeleteChar->m_nPos, 1);
2349 }
2350 else
2351 {
2352 nLen = TextFrameIndex(1);
2353 }
2354 lcl_SetWrong( *this, rNode, pDeleteChar->m_nPos, -1, true );
2355 if (nLen)
2356 {
2357 InvalidateRange( SwCharRange(nPos, nLen), -1 );
2358 lcl_SetScriptInval( *this, nPos );
2359 bSetFieldsDirty = bRecalcFootnoteFlag = true;
2360 lcl_ModifyOfst(*this, nPos, nLen, &o3tl::operator-<sal_Int32, Tag_TextFrameIndex>);
2361 }
2362 }
2363 else switch (nWhich)
2364 {
2365 case RES_LINENUMBER:
2366 {
2367 assert(false); // should have been forwarded to SwContentFrame
2369 }
2370 break;
2371 case RES_UPDATE_ATTR:
2372 {
2373 const SwUpdateAttr* pNewUpdate = static_cast<const SwUpdateAttr*>(pNew);
2374
2375 sal_Int32 const nNPos = pNewUpdate->getStart();
2376 sal_Int32 const nNLen = pNewUpdate->getEnd() - nNPos;
2377 nPos = MapModelToView(&rNode, nNPos);
2378 nLen = MapModelToView(&rNode, nNPos + nNLen) - nPos;
2379 if( IsIdxInside( nPos, nLen ) )
2380 {
2381 // We need to reformat anyways, even if the invalidated
2382 // range is empty.
2383 // E.g.: empty line, set 14 pt!
2384
2385 // FootnoteNumbers need to be formatted
2386 if( !nLen )
2387 nLen = TextFrameIndex(1);
2388
2390 const sal_uInt16 nTmp = pNewUpdate->getWhichAttr();
2391
2392 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_INETFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
2393 RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
2394 {
2395 lcl_SetWrong( *this, rNode, nNPos, nNPos + nNLen, false );
2396 lcl_SetScriptInval( *this, nPos );
2397 }
2398 }
2399
2400#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2401 if( isA11yRelevantAttribute( pNewUpdate->getWhichAttr() ) &&
2402 hasA11yRelevantAttribute( pNewUpdate->getFmtAttrs() ) )
2403 {
2404 SwViewShell* pViewSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2405 if ( pViewSh )
2406 {
2407 pViewSh->InvalidateAccessibleParaAttrs( *this );
2408 }
2409 }
2410#endif
2411 }
2412 break;
2413 case RES_OBJECTDYING:
2414 break;
2415
2417 {
2418 CalcLineSpace();
2421 if( IsInSct() && !GetPrev() )
2422 {
2423 SwSectionFrame *pSect = FindSctFrame();
2424 if( pSect->ContainsAny() == this )
2425 pSect->InvalidatePrt();
2426 }
2427
2428 // i#11859
2429 // (1) Also invalidate next frame on next page/column.
2430 // (2) Skip empty sections and hidden paragraphs
2431 // Thus, use method <InvalidateNextPrtArea()>
2433
2435 }
2436 break;
2437
2438 case RES_TXTATR_FIELD:
2440 {
2441 sal_Int32 const nNPos = static_cast<const SwFormatField*>(pNew)->GetTextField()->GetStart();
2442 nPos = MapModelToView(&rNode, nNPos);
2444 {
2445 if( pNew == pOld )
2446 {
2447 // only repaint
2448 // opt: invalidate window?
2451 }
2452 else
2454 }
2455 bSetFieldsDirty = true;
2456 // ST2
2457 if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
2458 lcl_SetWrong( *this, rNode, nNPos, nNPos + 1, false );
2459 }
2460 break;
2461
2462 case RES_TXTATR_FTN :
2463 {
2464 if (!IsInFootnote())
2465 { // the hint may be sent from the anchor node, or from a
2466 // node in the footnote; the anchor index is only valid in the
2467 // anchor node!
2468 assert(rNode == static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote()->GetTextNode());
2469 nPos = MapModelToView(&rNode,
2470 static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote()->GetStart());
2471 }
2472#ifdef _MSC_VER
2473 else nPos = TextFrameIndex(42); // shut up MSVC 2017 spurious warning C4701
2474#endif
2476 Prepare( PrepareHint::FootnoteInvalidation, static_cast<const SwFormatFootnote*>(pNew)->GetTextFootnote() );
2477 break;
2478 }
2479
2480 case RES_ATTRSET_CHG:
2481 {
2483
2484 const SwAttrSet& rNewSet = *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet();
2485 int nClear = 0;
2486 sal_uInt16 nCount = rNewSet.Count();
2487
2488 if( const SwFormatFootnote* pItem = rNewSet.GetItemIfSet( RES_TXTATR_FTN, false ) )
2489 {
2490 nPos = MapModelToView(&rNode, pItem->GetTextFootnote()->GetStart());
2493 nClear = 0x01;
2494 --nCount;
2495 }
2496
2497 if( const SwFormatField* pItem = rNewSet.GetItemIfSet( RES_TXTATR_FIELD, false ) )
2498 {
2499 nPos = MapModelToView(&rNode, pItem->GetTextField()->GetStart());
2501 {
2502 const SfxPoolItem* pOldItem = pOld ?
2503 &(static_cast<const SwAttrSetChg*>(pOld)->GetChgSet()->Get(RES_TXTATR_FIELD)) : nullptr;
2504 if( pItem == pOldItem )
2505 {
2508 }
2509 else
2511 }
2512 nClear |= 0x02;
2513 --nCount;
2514 }
2515 bool bLineSpace = SfxItemState::SET == rNewSet.GetItemState(
2516 RES_PARATR_LINESPACING, false ),
2517 bRegister = SfxItemState::SET == rNewSet.GetItemState(
2518 RES_PARATR_REGISTER, false );
2519 if ( bLineSpace || bRegister )
2520 {
2521 if (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2522 {
2524 CalcLineSpace();
2527
2528 // i#11859
2529 // (1) Also invalidate next frame on next page/column.
2530 // (2) Skip empty sections and hidden paragraphs
2531 // Thus, use method <InvalidateNextPrtArea()>
2533
2535 }
2536 nClear |= 0x04;
2537 if ( bLineSpace )
2538 {
2539 --nCount;
2540 if ((!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2541 && IsInSct() && !GetPrev())
2542 {
2543 SwSectionFrame *pSect = FindSctFrame();
2544 if( pSect->ContainsAny() == this )
2545 pSect->InvalidatePrt();
2546 }
2547 }
2548 if ( bRegister )
2549 --nCount;
2550 }
2551 if ( SfxItemState::SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
2552 false ))
2553 {
2554 if (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2555 {
2556 if (GetPrev())
2557 CheckKeep();
2558 Prepare();
2560 }
2561 nClear |= 0x08;
2562 --nCount;
2563 }
2564
2565 if( SfxItemState::SET == rNewSet.GetItemState( RES_BACKGROUND, false)
2566 && (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify)
2567 && !IsFollow() && GetDrawObjs() )
2568 {
2569 SwSortedObjs *pObjs = GetDrawObjs();
2570 for ( size_t i = 0; GetDrawObjs() && i < pObjs->size(); ++i )
2571 {
2572 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
2573 if ( auto pFly = pAnchoredObj->DynCastFlyFrame() )
2574 {
2575 if( !pFly->IsFlyInContentFrame() )
2576 {
2577 const SvxBrushItem &rBack =
2578 pFly->GetAttrSet()->GetBackground();
2579 // #GetTransChg#
2580 // following condition determines, if the fly frame
2581 // "inherites" the background color of text frame.
2582 // This is the case, if fly frame background
2583 // color is "no fill"/"auto fill" and if the fly frame
2584 // has no background graphic.
2585 // Thus, check complete fly frame background
2586 // color and *not* only its transparency value
2587 if ( (rBack.GetColor() == COL_TRANSPARENT) &&
2588 rBack.GetGraphicPos() == GPOS_NONE )
2589 {
2590 pFly->SetCompletePaint();
2591 pFly->InvalidatePage();
2592 }
2593 }
2594 }
2595 }
2596 }
2597
2598 if ( SfxItemState::SET ==
2599 rNewSet.GetItemState( RES_TXTATR_CHARFMT, false ) )
2600 {
2601 lcl_SetWrong( *this, rNode, 0, COMPLETE_STRING, false );
2603 }
2604 else if ( SfxItemState::SET ==
2605 rNewSet.GetItemState( RES_CHRATR_LANGUAGE, false ) ||
2606 SfxItemState::SET ==
2607 rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, false ) ||
2608 SfxItemState::SET ==
2609 rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, false ) )
2610 lcl_SetWrong( *this, rNode, 0, COMPLETE_STRING, false );
2611 else if ( SfxItemState::SET ==
2612 rNewSet.GetItemState( RES_CHRATR_FONT, false ) ||
2613 SfxItemState::SET ==
2614 rNewSet.GetItemState( RES_CHRATR_CJK_FONT, false ) ||
2615 SfxItemState::SET ==
2616 rNewSet.GetItemState( RES_CHRATR_CTL_FONT, false ) )
2618 else if ( SfxItemState::SET ==
2619 rNewSet.GetItemState( RES_FRAMEDIR, false )
2620 && (!m_pMergedPara || m_pMergedPara->pParaPropsNode == &rModify))
2621 {
2622 SetDerivedR2L( false );
2624 // Force complete paint due to existing indents.
2626 }
2627
2628 if( nCount )
2629 {
2630 if( getRootFrame()->GetCurrShell() )
2631 {
2632 Prepare();
2634 }
2635
2636 if (nClear || (m_pMergedPara &&
2637 (m_pMergedPara->pParaPropsNode != &rModify ||
2638 m_pMergedPara->pFirstNode != &rModify)))
2639 {
2640 assert(pOld);
2641 SwAttrSetChg aOldSet( *static_cast<const SwAttrSetChg*>(pOld) );
2642 SwAttrSetChg aNewSet( *static_cast<const SwAttrSetChg*>(pNew) );
2643
2644 if (m_pMergedPara && m_pMergedPara->pParaPropsNode != &rModify)
2645 {
2646 for (sal_uInt16 i = RES_PARATR_BEGIN; i != RES_FRMATR_END; ++i)
2647 {
2648 if (i != RES_BREAK && i != RES_PAGEDESC)
2649 {
2650 aOldSet.ClearItem(i);
2651 aNewSet.ClearItem(i);
2652 }
2653 }
2654 for (sal_uInt16 i = XATTR_FILL_FIRST; i <= XATTR_FILL_LAST; ++i)
2655 {
2656 aOldSet.ClearItem(i);
2657 aNewSet.ClearItem(i);
2658 }
2659 }
2660 if (m_pMergedPara && m_pMergedPara->pFirstNode != &rModify)
2661 {
2662 aOldSet.ClearItem(RES_BREAK);
2663 aNewSet.ClearItem(RES_BREAK);
2664 aOldSet.ClearItem(RES_PAGEDESC);
2665 aNewSet.ClearItem(RES_PAGEDESC);
2666 }
2667
2668 if( 0x01 & nClear )
2669 {
2670 aOldSet.ClearItem( RES_TXTATR_FTN );
2671 aNewSet.ClearItem( RES_TXTATR_FTN );
2672 }
2673 if( 0x02 & nClear )
2674 {
2675 aOldSet.ClearItem( RES_TXTATR_FIELD );
2676 aNewSet.ClearItem( RES_TXTATR_FIELD );
2677 }
2678 if ( 0x04 & nClear )
2679 {
2680 if ( bLineSpace )
2681 {
2684 }
2685 if ( bRegister )
2686 {
2687 aOldSet.ClearItem( RES_PARATR_REGISTER );
2688 aNewSet.ClearItem( RES_PARATR_REGISTER );
2689 }
2690 }
2691 if ( 0x08 & nClear )
2692 {
2693 aOldSet.ClearItem( RES_PARATR_SPLIT );
2694 aNewSet.ClearItem( RES_PARATR_SPLIT );
2695 }
2696 if (aOldSet.Count() || aNewSet.Count())
2697 {
2698 SwContentFrame::SwClientNotify(rModify, sw::LegacyModifyHint(&aOldSet, &aNewSet));
2699 }
2700 }
2701 else
2703 }
2704
2705#if !ENABLE_WASM_STRIP_ACCESSIBILITY
2706 if (isA11yRelevantAttribute(nWhich))
2707 {
2708 SwViewShell* pViewSh = getRootFrame() ? getRootFrame()->GetCurrShell() : nullptr;
2709 if ( pViewSh )
2710 {
2711 pViewSh->InvalidateAccessibleParaAttrs( *this );
2712 }
2713 }
2714#endif
2715 }
2716 break;
2717 case RES_PARATR_SPLIT:
2718 if ( GetPrev() )
2719 CheckKeep();
2720 Prepare();
2721 bSetFieldsDirty = true;
2722 break;
2723 case RES_FRAMEDIR :
2724 assert(false); // should have been forwarded to SwContentFrame
2725 SetDerivedR2L( false );
2727 break;
2728 default:
2729 {
2730 Prepare();
2732 if ( !nWhich )
2733 {
2734 // is called by e. g. HiddenPara with 0
2735 SwFrame *pNxt = FindNext();
2736 if ( nullptr != pNxt )
2737 pNxt->InvalidatePrt();
2738 }
2739 }
2740 } // switch
2741
2742 if( bSetFieldsDirty )
2744
2745 if ( bRecalcFootnoteFlag )
2747}
2748
2750{
2751 if(RES_VIRTPAGENUM_INFO == rHint.Which() && IsInDocBody() && !IsFollow())
2752 {
2753 SwVirtPageNumInfo& rInfo = static_cast<SwVirtPageNumInfo&>(rHint);
2754 if(const SwPageFrame* pPage = FindPageFrame())
2755 return pPage->UpdateVirtPageNumInfo(rInfo, this);
2756 }
2757 return true;
2758}
2759
2760void SwTextFrame::PrepWidows( const sal_uInt16 nNeed, bool bNotify )
2761{
2762 OSL_ENSURE(GetFollow() && nNeed, "+SwTextFrame::Prepare: lost all friends");
2763
2764 SwParaPortion *pPara = GetPara();
2765 if ( !pPara )
2766 return;
2767 pPara->SetPrepWidows();
2768
2769 sal_uInt16 nHave = nNeed;
2770
2771 // We yield a few lines and shrink in CalcPreps()
2772 SwSwapIfNotSwapped swap( this );
2773
2774 SwTextSizeInfo aInf( this );
2775 SwTextMargin aLine( this, &aInf );
2776 aLine.Bottom();
2777 TextFrameIndex nTmpLen = aLine.GetCurr()->GetLen();
2778 while( nHave && aLine.PrevLine() )
2779 {
2780 if( nTmpLen )
2781 --nHave;
2782 nTmpLen = aLine.GetCurr()->GetLen();
2783 }
2784
2785 // If it's certain that we can yield lines, the Master needs
2786 // to check the widow rule
2787 if( !nHave )
2788 {
2789 bool bSplit = true;
2790 if( !IsFollow() ) // only a master decides about orphans
2791 {
2792 const WidowsAndOrphans aWidOrp( this );
2793 bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
2794 aLine.GetLineNr() >= aLine.GetDropLines() );
2795 }
2796
2797 if( bSplit )
2798 {
2799 GetFollow()->SetOffset( aLine.GetEnd() );
2800 aLine.TruncLines( true );
2801 if( pPara->IsFollowField() )
2802 GetFollow()->SetFieldFollow( true );
2803 }
2804 }
2805 if ( bNotify )
2806 {
2809 }
2810}
2811
2812static bool lcl_ErgoVadis(SwTextFrame* pFrame, TextFrameIndex & rPos, const PrepareHint ePrep)
2813{
2814 const SwFootnoteInfo &rFootnoteInfo = pFrame->GetDoc().GetFootnoteInfo();
2815 if( ePrep == PrepareHint::ErgoSum )
2816 {
2817 if( rFootnoteInfo.m_aErgoSum.isEmpty() )
2818 return false;
2819 rPos = pFrame->GetOffset();
2820 }
2821 else
2822 {
2823 if( rFootnoteInfo.m_aQuoVadis.isEmpty() )
2824 return false;
2825 if( pFrame->HasFollow() )
2826 rPos = pFrame->GetFollow()->GetOffset();
2827 else
2828 rPos = TextFrameIndex(pFrame->GetText().getLength());
2829 if( rPos )
2830 --rPos; // our last character
2831 }
2832 return true;
2833}
2834
2835// Silence over-eager warning emitted at least by GCC 5.3.1
2836#if defined __GNUC__ && !defined __clang__
2837# pragma GCC diagnostic push
2838# pragma GCC diagnostic ignored "-Wstrict-overflow"
2839#endif
2840bool SwTextFrame::Prepare( const PrepareHint ePrep, const void* pVoid,
2841 bool bNotify )
2842{
2843 bool bParaPossiblyInvalid = false;
2844
2845 SwFrameSwapper aSwapper( this, false );
2846
2847 if ( IsEmpty() )
2848 {
2849 switch ( ePrep )
2850 {
2852 SetInvalidVert( true ); // Test
2853 [[fallthrough]];
2856 case PrepareHint::FootnoteInvalidationGone : return bParaPossiblyInvalid;
2857
2859 {
2860 // We also need an InvalidateSize for Areas (with and without columns),
2861 // so that we format and bUndersized is set (if needed)
2862 if( IsInFly() || IsInSct() )
2863 {
2864 SwTwips nTmpBottom = GetUpper()->getFrameArea().Top() +
2866 if( nTmpBottom < getFrameArea().Bottom() )
2867 break;
2868 }
2869 // Are there any free-flying frames on this page?
2870 SwTextFly aTextFly( this );
2871 if( aTextFly.IsOn() )
2872 {
2873 // Does any free-flying frame overlap?
2874 if ( aTextFly.Relax() || IsUndersized() )
2875 break;
2876 }
2877 if (GetTextNodeForParaProps()->GetSwAttrSet().GetRegister().GetValue())
2878 break;
2879
2880 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrame()));
2881 if (pGrid && GetTextNodeForParaProps()->GetSwAttrSet().GetParaGrid().GetValue())
2882 break;
2883
2884 // i#28701 - consider anchored objects
2885 if ( GetDrawObjs() )
2886 break;
2887
2888 return bParaPossiblyInvalid;
2889 }
2890 default:
2891 break;
2892 }
2893 }
2894
2895 // Split fly anchors are technically empty (have no SwParaPortion), but otherwise behave like
2896 // other split text frames, which are non-empty.
2897 bool bSplitFlyAnchor = GetOffset() == TextFrameIndex(0) && HasFollow()
2898 && GetFollow()->GetOffset() == TextFrameIndex(0);
2899
2900 if( !HasPara() && !bSplitFlyAnchor && PrepareHint::MustFit != ePrep )
2901 {
2902 SetInvalidVert( true ); // Test
2903 OSL_ENSURE( !IsLocked(), "SwTextFrame::Prepare: three of a perfect pair" );
2904 if ( bNotify )
2906 else
2908 return bParaPossiblyInvalid;
2909 }
2910
2911 // Get object from cache while locking
2912 SwTextLineAccess aAccess( this );
2913 SwParaPortion *pPara = aAccess.GetPara();
2914
2915 switch( ePrep )
2916 {
2918 {
2920 aFrm.Height(0);
2921 }
2922
2923 {
2925 aPrt.Height(0);
2926 }
2927
2930 [[fallthrough]];
2932 pPara->SetPrepAdjust();
2933 if( IsFootnoteNumFrame() != pPara->IsFootnoteNum() ||
2934 IsUndersized() )
2935 {
2937 if( GetOffset() && !IsFollow() )
2939 }
2940 break;
2942 pPara->SetPrepMustFit(true);
2943 [[fallthrough]];
2945 pPara->SetPrepAdjust();
2946 break;
2947 case PrepareHint::Widows :
2948 // MustFit is stronger than anything else
2949 if( pPara->IsPrepMustFit() )
2950 return bParaPossiblyInvalid;
2951 // see comment in WidowsAndOrphans::FindOrphans and CalcPreps()
2952 PrepWidows( *static_cast<const sal_uInt16 *>(pVoid), bNotify );
2953 break;
2954
2956 {
2957 SwTextFootnote const *pFootnote = static_cast<SwTextFootnote const *>(pVoid);
2958 if( IsInFootnote() )
2959 {
2960 // Am I the first TextFrame of a footnote?
2961 if( !GetPrev() )
2962 // So we're a TextFrame of the footnote, which has
2963 // to display the footnote number or the ErgoSum text
2965
2966 if( !GetNext() )
2967 {
2968 // We're the last Footnote; we need to update the
2969 // QuoVadis texts now
2970 const SwFootnoteInfo &rFootnoteInfo = GetDoc().GetFootnoteInfo();
2971 if( !pPara->UpdateQuoVadis( rFootnoteInfo.m_aQuoVadis ) )
2972 {
2973 TextFrameIndex nPos = pPara->GetParLen();
2974 if( nPos )
2975 --nPos;
2977 }
2978 }
2979 }
2980 else
2981 {
2982 // We are the TextFrame _with_ the footnote
2984 &pFootnote->GetTextNode(), pFootnote->GetStart());
2986 }
2987 break;
2988 }
2990 {
2991 // Test
2992 {
2993 SetInvalidVert( false );
2994 bool bOld = IsVertical();
2995 SetInvalidVert( true );
2996 if( bOld != IsVertical() )
2998 }
2999
3000 if( HasFollow() )
3001 {
3002 TextFrameIndex nNxtOfst = GetFollow()->GetOffset();
3003 if( nNxtOfst )
3004 --nNxtOfst;
3005 InvalidateRange(SwCharRange( nNxtOfst, TextFrameIndex(1)), 1);
3006 }
3007 if( IsInFootnote() )
3008 {
3014 }
3015 // If we have a page number field, we must invalidate those spots
3016 SwTextNode const* pNode(nullptr);
3017 sw::MergedAttrIter iter(*this);
3018 TextFrameIndex const nEnd = GetFollow()
3020 for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
3021 {
3022 TextFrameIndex const nStart(MapModelToView(pNode, pHt->GetStart()));
3023 if (nStart >= GetOffset())
3024 {
3025 if (nStart >= nEnd)
3026 break;
3027
3028 // If we're flowing back and own a Footnote, the Footnote also flows
3029 // with us. So that it doesn't obstruct us, we send ourselves
3030 // an ADJUST_FRM.
3031 // pVoid != 0 means MoveBwd()
3032 const sal_uInt16 nWhich = pHt->Which();
3033 if (RES_TXTATR_FIELD == nWhich ||
3034 (HasFootnote() && pVoid && RES_TXTATR_FTN == nWhich))
3036 }
3037 }
3038 // A new boss, a new chance for growing
3039 if( IsUndersized() )
3040 {
3043 }
3044 break;
3045 }
3046
3048 {
3049 if ( isFramePrintAreaValid() )
3050 {
3051 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrame()));
3052 if (pGrid && GetTextNodeForParaProps()->GetSwAttrSet().GetParaGrid().GetValue())
3053 InvalidatePrt();
3054 }
3055
3056 // If we don't overlap with anybody:
3057 // did any free-flying frame overlapped _before_ the position change?
3058 bool bFormat = pPara->HasFly();
3059 if( !bFormat )
3060 {
3061 if( IsInFly() )
3062 {
3063 SwTwips nTmpBottom = GetUpper()->getFrameArea().Top() +
3065 if( nTmpBottom < getFrameArea().Bottom() )
3066 bFormat = true;
3067 }
3068 if( !bFormat )
3069 {
3070 if ( GetDrawObjs() )
3071 {
3072 const size_t nCnt = GetDrawObjs()->size();
3073 for ( size_t i = 0; i < nCnt; ++i )
3074 {
3075 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
3076 // i#28701 - consider all
3077 // to-character anchored objects
3078 if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId()
3079 == RndStdIds::FLY_AT_CHAR )
3080 {
3081 bFormat = true;
3082 break;
3083 }
3084 }
3085 }
3086 if( !bFormat )
3087 {
3088 // Are there any free-flying frames on this page?
3089 SwTextFly aTextFly( this );
3090 if( aTextFly.IsOn() )
3091 {
3092 // Does any free-flying frame overlap?
3093 const bool bRelaxed = aTextFly.Relax();
3094 bFormat = bRelaxed || IsUndersized();
3095 if (bRelaxed)
3096 {
3097 // It's possible that pPara was deleted above; retrieve it again
3098 pPara = aAccess.GetPara();
3099 }
3100 }
3101 }
3102 }
3103 }
3104
3105 if( bFormat )
3106 {
3107 if( !IsLocked() )
3108 {
3109 if( pPara->GetRepaint().HasArea() )
3111 Init();
3112 pPara = nullptr;
3114 }
3115 }
3116 else
3117 {
3118 if (GetTextNodeForParaProps()->GetSwAttrSet().GetRegister().GetValue())
3119 bParaPossiblyInvalid = Prepare( PrepareHint::Register, nullptr, bNotify );
3120 // The Frames need to be readjusted, which caused by changes
3121 // in position
3122 else if( HasFootnote() )
3123 {
3124 bParaPossiblyInvalid = Prepare( PrepareHint::AdjustSizeWithoutFormatting, nullptr, bNotify );
3126 }
3127 else
3128 return bParaPossiblyInvalid; // So that there's no SetPrep()
3129
3130 if (bParaPossiblyInvalid)
3131 {
3132 // It's possible that pPara was deleted above; retrieve it again
3133 pPara = aAccess.GetPara();
3134 }
3135
3136 }
3137 break;
3138 }
3140 if (GetTextNodeForParaProps()->GetSwAttrSet().GetRegister().GetValue())
3141 {
3142 pPara->SetPrepAdjust();
3143 CalcLineSpace();
3144
3145 // It's possible that pPara was deleted above; retrieve it again
3146 bParaPossiblyInvalid = true;
3147 pPara = aAccess.GetPara();
3148
3151 SwFrame* pNxt = GetIndNext();
3152 if ( nullptr != pNxt )
3153 {
3154 pNxt->InvalidatePrt_();
3155 if ( pNxt->IsLayoutFrame() )
3156 pNxt->InvalidatePage();
3157 }
3159 }
3160 break;
3162 {
3163 // If a Follow is calling us, because a footnote is being deleted, our last
3164 // line has to be formatted, so that the first line of the Follow can flow up.
3165 // Which had flowed to the next page to be together with the footnote (this is
3166 // especially true for areas with columns)
3167 OSL_ENSURE( GetFollow(), "PrepareHint::FootnoteInvalidationGone may only be called by Follow" );
3169 if( IsFollow() && GetOffset() == nPos ) // If we don't have a mass of text, we call our
3171 if( nPos )
3172 --nPos; // The char preceding our Follow
3174 return bParaPossiblyInvalid;
3175 }
3178 {
3180 if( lcl_ErgoVadis( this, nPos, ePrep ) )
3182 }
3183 break;
3185 {
3186 if( pVoid )
3187 {
3188 TextFrameIndex const nWhere = CalcFlyPos( static_cast<SwFrameFormat const *>(pVoid) );
3189 OSL_ENSURE( TextFrameIndex(COMPLETE_STRING) != nWhere, "Prepare: Why me?" );
3191 return bParaPossiblyInvalid;
3192 }
3193 [[fallthrough]]; // else: continue with default case block
3194 }
3195 case PrepareHint::Clear:
3196 default:
3197 {
3198 if( IsLocked() )
3199 {
3201 {
3202 TextFrameIndex const nLen = (GetFollow()
3203 ? GetFollow()->GetOffset()
3205 - GetOffset();
3207 }
3208 }
3209 else
3210 {
3211 if( pPara->GetRepaint().HasArea() )
3213 Init();
3214 pPara = nullptr;
3215 if( GetOffset() && !IsFollow() )
3217 if ( bNotify )
3219 else
3221 }
3222 return bParaPossiblyInvalid; // no SetPrep() happened
3223 }
3224 }
3225 if( pPara )
3226 {
3227 pPara->SetPrep();
3228 }
3229
3230 return bParaPossiblyInvalid;
3231}
3232#if defined __GNUC__ && !defined __clang__
3233# pragma GCC diagnostic pop
3234#endif
3235
3245{
3249public:
3250 SwTestFormat( SwTextFrame* pTextFrame, const SwFrame* pPrv, SwTwips nMaxHeight );
3251 ~SwTestFormat();
3252};
3253
3254SwTestFormat::SwTestFormat( SwTextFrame* pTextFrame, const SwFrame* pPre, SwTwips nMaxHeight )
3255 : pFrame( pTextFrame )
3256{
3259
3260 SwRectFnSet aRectFnSet(pFrame);
3261 SwTwips nLower = aRectFnSet.GetBottomMargin(*pFrame);
3262
3263 {
3264 // indeed, here the GetUpper()->getFramePrintArea() gets copied and manipulated
3267 aFrm += pFrame->GetUpper()->getFrameArea().Pos();
3268 aRectFnSet.SetHeight( aFrm, nMaxHeight );
3269
3270 if( pFrame->GetPrev() )
3271 {
3272 aRectFnSet.SetPosY(
3273 aFrm,
3274 aRectFnSet.GetBottom(pFrame->GetPrev()->getFrameArea()) - ( aRectFnSet.IsVert() ? nMaxHeight + 1 : 0 ) );
3275 }
3276 }
3277
3279 const SwBorderAttrs &rAttrs = *aAccess.Get();
3280
3281 {
3283 aRectFnSet.SetPosX(aPrt, rAttrs.CalcLeft( pFrame ) );
3284 }
3285
3286 if( pPre )
3287 {
3288 SwTwips nUpper = pFrame->CalcUpperSpace( &rAttrs, pPre );
3290 aRectFnSet.SetPosY(aPrt, nUpper );
3291 }
3292
3293 {
3295 aRectFnSet.SetHeight( aPrt, std::max( tools::Long(0) , aRectFnSet.GetHeight(pFrame->getFrameArea()) - aRectFnSet.GetTop(aPrt) - nLower ) );
3296 aRectFnSet.SetWidth( aPrt, aRectFnSet.GetWidth(pFrame->getFrameArea()) - ( rAttrs.CalcLeft( pFrame ) + rAttrs.CalcRight( pFrame ) ) );
3297 }
3298
3299 pOldPara = pFrame->HasPara() ? pFrame->GetPara() : nullptr;
3300 pFrame->SetPara( new SwParaPortion(), false );
3301 OSL_ENSURE( ! pFrame->IsSwapped(), "A frame is swapped before Format_" );
3302
3303 if ( pFrame->IsVertical() )
3305
3306 SwTextFormatInfo aInf( pFrame->getRootFrame()->GetCurrShell()->GetOut(), pFrame, false, true, true );
3307 SwTextFormatter aLine( pFrame, &aInf );
3308
3309 pFrame->Format_( aLine, aInf );
3310
3311 if ( pFrame->IsVertical() )
3313
3314 OSL_ENSURE( ! pFrame->IsSwapped(), "A frame is swapped after Format_" );
3315}
3316
3318{
3319 {
3321 aFrm.setSwRect(aOldFrame);
3322 }
3323
3324 {
3326 aPrt.setSwRect(aOldPrt);
3327 }
3328
3330}
3331
3332bool SwTextFrame::TestFormat( const SwFrame* pPrv, SwTwips &rMaxHeight, bool &bSplit )
3333{
3335
3336 if( IsLocked() && GetUpper()->getFramePrintArea().Width() <= 0 )
3337 return false;
3338
3339 SwTestFormat aSave( this, pPrv, rMaxHeight );
3340
3341 return SwTextFrame::WouldFit(rMaxHeight, bSplit, true, false);
3342}
3343
3356bool SwTextFrame::WouldFit(SwTwips &rMaxHeight, bool &bSplit, bool bTst, bool bMoveBwd)
3357{
3358 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
3359 "SwTextFrame::WouldFit with swapped frame" );
3360 SwRectFnSet aRectFnSet(this);
3361
3362 if( IsLocked() )
3363 return false;
3364
3365 // it can happen that the IdleCollector removed the cached information
3366 if( !IsEmpty() )
3367 GetFormatted();
3368
3369 // i#27801 - correction: 'short cut' for empty paragraph
3370 // can *not* be applied, if test format is in progress. The test format doesn't
3371 // adjust the frame and the printing area - see method <SwTextFrame::Format_(..)>,
3372 // which is called in <SwTextFrame::TestFormat(..)>
3373 if ( IsEmpty() && !bTst )
3374 {
3375 bSplit = false;
3376 SwTwips nHeight = aRectFnSet.IsVert() ? getFramePrintArea().SSize().Width() : getFramePrintArea().SSize().Height();
3377 if( rMaxHeight < nHeight )
3378 return false;
3379 else
3380 {
3381 rMaxHeight -= nHeight;
3382 return true;
3383 }
3384 }
3385
3386 // GetPara can still be 0 in edge cases
3387 // We return true in order to be reformatted on the new Page
3388 OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
3389 if( !HasPara() || ( !aRectFnSet.GetHeight(getFrameArea()) && IsHiddenNow() ) )
3390 return true;
3391
3392 // Because the Orphan flag only exists for a short moment, we also check
3393 // whether the Framesize is set to very huge by CalcPreps, in order to
3394 // force a MoveFwd
3395 if (IsWidow() || (aRectFnSet.IsVert()
3396 ? (0 == getFrameArea().Left())
3397 : (sw::WIDOW_MAGIC - 20000 < getFrameArea().Bottom())))
3398 {
3399 SetWidow(false);
3400 if ( GetFollow() )
3401 {
3402 // If we've ended up here due to a Widow request by our Follow, we check
3403 // whether there's a Follow with a real height at all.
3404 // Else (e.g. for newly created SctFrames) we ignore the IsWidow() and
3405 // still check if we can find enough room
3406 if (((!aRectFnSet.IsVert() && getFrameArea().Bottom() <= sw::WIDOW_MAGIC - 20000) ||
3407 ( aRectFnSet.IsVert() && 0 < getFrameArea().Left() ) ) &&
3408 ( GetFollow()->IsVertical() ?
3409 !GetFollow()->getFrameArea().Width() :
3410 !GetFollow()->getFrameArea().Height() ) )
3411 {
3412 SwTextFrame* pFoll = GetFollow()->GetFollow();
3413 while( pFoll &&
3414 ( pFoll->IsVertical() ?
3415 !pFoll->getFrameArea().Width() :
3416 !pFoll->getFrameArea().Height() ) )
3417 pFoll = pFoll->GetFollow();
3418 if( pFoll )
3419 return false;
3420 }
3421 else
3422 return false;
3423 }
3424 }
3425
3426 SwSwapIfNotSwapped swap( this );
3427
3428 SwTextSizeInfo aInf( this );
3429 SwTextMargin aLine( this, &aInf );
3430
3431 WidowsAndOrphans aFrameBreak( this, rMaxHeight, bSplit );
3432
3433 bool bRet = true;
3434
3435 aLine.Bottom();
3436 // is breaking necessary?
3437 bSplit = !aFrameBreak.IsInside( aLine );
3438 if ( bSplit )
3439 bRet = !aFrameBreak.IsKeepAlways() && aFrameBreak.WouldFit(aLine, rMaxHeight, bTst, bMoveBwd);
3440 else
3441 {
3442 // we need the total height including the current line
3443 aLine.Top();
3444 do
3445 {
3446 rMaxHeight -= aLine.GetLineHeight();
3447 } while ( aLine.Next() );
3448 }
3449
3450 return bRet;
3451}
3452
3454{
3455 OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
3456 "SwTextFrame::GetParHeight with swapped frame" );
3457
3458 if( !HasPara() )
3459 { // For non-empty paragraphs this is a special case
3460 // For UnderSized we can simply just ask 1 Twip more
3461 sal_uInt16 nRet = o3tl::narrowing<sal_uInt16>(getFramePrintArea().SSize().Height());
3462 if( IsUndersized() )
3463 {
3464 if( IsEmpty() || GetText().isEmpty() )
3465 nRet = o3tl::narrowing<sal_uInt16>(EmptyHeight());
3466 else
3467 ++nRet;
3468 }
3469 return nRet;
3470 }
3471
3472 // TODO: Refactor and improve code
3473 const SwLineLayout* pLineLayout = GetPara();
3474 SwTwips nHeight = pLineLayout ? pLineLayout->GetRealHeight() : 0;
3475
3476 // Is this paragraph scrolled? Our height until now is at least
3477 // one line height too low then
3478 if( GetOffset() && !IsFollow() )
3479 nHeight *= 2;
3480
3481 while ( pLineLayout && pLineLayout->GetNext() )
3482 {
3483 pLineLayout = pLineLayout->GetNext();
3484 nHeight = nHeight + pLineLayout->GetRealHeight();
3485 }
3486
3487 return nHeight;
3488}
3489
3493SwTextFrame* SwTextFrame::GetFormatted( bool bForceQuickFormat )
3494{
3495 vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
3496 SwSwapIfSwapped swap( this );
3497
3498 // In case the SwLineLayout was cleared out of the s_pTextCache, recreate it
3499 // Not for empty paragraphs
3500 if( !HasPara() && !(isFrameAreaDefinitionValid() && IsEmpty()) )
3501 {
3502 // Calc() must be called, because frame position can be wrong
3503 const bool bFormat = isFrameAreaSizeValid();
3504 Calc(pRenderContext); // calls Format() if invalid
3505
3506 // If the flags were valid (hence bFormat=true), Calc did nothing,
3507 // so Format() must be called manually in order to recreate
3508 // the SwLineLayout that has been deleted from the
3509 // SwTextFrame::s_pTextCache (hence !HasPara() above).
3510 // Optimization with FormatQuick()
3511 if( bFormat && !FormatQuick( bForceQuickFormat ) )
3512 Format(getRootFrame()->GetCurrShell()->GetOut());
3513 }
3514
3515 return this;
3516}
3517
3519{
3520 // i#31490
3521 // If we are currently locked, we better return with a
3522 // fairly reasonable value:
3523 if ( IsLocked() )
3524 return getFramePrintArea().Width();
3525
3526 SwParaPortion* pOldPara = GetPara();
3527 SwParaPortion *pDummy = new SwParaPortion();
3528 SetPara( pDummy, false );
3529 const SwPageFrame* pPage = FindPageFrame();
3530
3531 const Point aOldFramePos = getFrameArea().Pos();
3532 const SwTwips nOldFrameWidth = getFrameArea().Width();
3533 const SwTwips nOldPrtWidth = getFramePrintArea().Width();
3534 const SwTwips nPageWidth = GetUpper()->IsVertical() ?
3535 pPage->getFramePrintArea().Height() :
3536 pPage->getFramePrintArea().Width();
3537
3538 {
3540 aFrm.Width( nPageWidth );
3541 }
3542
3543 {
3545 aPrt.Width( nPageWidth );
3546 }
3547
3548 // i#25422 objects anchored as character in RTL
3549 if ( IsRightToLeft() )
3550 {
3552 aFrm.Pos().AdjustX(nOldFrameWidth - nPageWidth );
3553 }
3554
3555 TextFrameLockGuard aLock( this );
3556
3557 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this, false, true, true );
3558 aInf.SetIgnoreFly( true );
3559 SwTextFormatter aLine( this, &aInf );
3560 SwHookOut aHook( aInf );
3561
3562 // i#54031 - assure minimum of MINLAY twips.
3563 const SwTwips nMax = std::max( SwTwips(MINLAY), aLine.CalcFitToContent_() + 1 );
3564
3565 {
3567 aFrm.Width( nOldFrameWidth );
3568
3569 // i#25422 objects anchored as character in RTL
3570 if ( IsRightToLeft() )
3571 {
3572 aFrm.Pos() = aOldFramePos;
3573 }
3574 }
3575
3576 {
3578 aPrt.Width( nOldPrtWidth );
3579 }
3580
3581 SetPara( pOldPara );
3582
3583 return nMax;
3584}
3585
3593{
3594 if ( IsLocked() )
3595 return;
3596
3597 // reset additional first line offset
3599
3600 const SwTextNode* pTextNode( GetTextNodeForParaProps() );
3601 // sw_redlinehide: check that pParaPropsNode is the correct one
3602 assert(pTextNode->IsNumbered(getRootFrame()) == pTextNode->IsNumbered(nullptr));
3603 if (!(pTextNode->IsNumbered(getRootFrame()) &&
3604 pTextNode->IsCountedInList() && pTextNode->GetNumRule()))
3605 return;
3606
3607 int nListLevel = pTextNode->GetActualListLevel();
3608
3609 if (nListLevel < 0)
3610 nListLevel = 0;
3611
3612 if (nListLevel >= MAXLEVEL)
3613 nListLevel = MAXLEVEL - 1;
3614
3615 const SwNumFormat& rNumFormat =
3616 pTextNode->GetNumRule()->Get( o3tl::narrowing<sal_uInt16>(nListLevel) );
3618 return;
3619
3620 // keep current paragraph portion and apply dummy paragraph portion
3621 SwParaPortion* pOldPara = GetPara();
3622 SwParaPortion *pDummy = new SwParaPortion();
3623 SetPara( pDummy, false );
3624
3625 // lock paragraph
3626 TextFrameLockGuard aLock( this );
3627
3628 // simulate text formatting
3629 SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this, false, true, true );
3630 aInf.SetIgnoreFly( true );
3631 SwTextFormatter aLine( this, &aInf );
3632 SwHookOut aHook( aInf );
3633 aLine.CalcFitToContent_();
3634
3635 // determine additional first line offset
3636 const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
3637 if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFootnoteNumPortion() )
3638 {
3639 SwTwips nNumberPortionWidth( pFirstPortion->Width() );
3640
3641 const SwLinePortion* pPortion = pFirstPortion->GetNextPortion();
3642 while ( pPortion &&
3643 pPortion->InNumberGrp() && !pPortion->IsFootnoteNumPortion())
3644 {
3645 nNumberPortionWidth += pPortion->Width();
3646 pPortion = pPortion->GetNextPortion();
3647 }
3648
3649 if ( ( IsRightToLeft() &&
3650 rNumFormat.GetNumAdjust() == SvxAdjust::Left ) ||
3651 ( !IsRightToLeft() &&
3652 rNumFormat.GetNumAdjust() == SvxAdjust::Right ) )
3653 {
3654 mnAdditionalFirstLineOffset = -nNumberPortionWidth;
3655 }
3656 else if ( rNumFormat.GetNumAdjust() == SvxAdjust::Center )
3657 {
3658 mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
3659 }
3660 }
3661
3662 // restore paragraph portion
3663 SetPara( pOldPara );
3664}
3665
3678void SwTextFrame::CalcHeightOfLastLine( const bool _bUseFont )
3679{
3680 // i#71281
3681 // Invalidate printing area, if height of last line changes
3682 const SwTwips nOldHeightOfLastLine( mnHeightOfLastLine );
3683
3684 // determine output device
3686 OSL_ENSURE( pVsh, "<SwTextFrame::_GetHeightOfLastLineForPropLineSpacing()> - no SwViewShell" );
3687
3688 // i#78921
3689 // There could be no <SwViewShell> instance in the case of loading a binary
3690 // StarOffice file format containing an embedded Writer document.
3691 if ( !pVsh )
3692 {
3693 return;
3694 }
3695 OutputDevice* pOut = pVsh->GetOut();
3697 if ( !pVsh->GetViewOptions()->getBrowseMode() ||
3698 pVsh->GetViewOptions()->IsPrtFormat() )
3699 {
3701 }
3702 OSL_ENSURE( pOut, "<SwTextFrame::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
3703
3704 if ( !pOut )
3705 {
3706 return;
3707 }
3708
3709 // determine height of last line
3710 if ( _bUseFont || pIDSA->get(DocumentSettingId::OLD_LINE_SPACING ) )
3711 {
3712 // former determination of last line height for proportional line
3713 // spacing - take height of font set at the paragraph
3714 // FIXME actually... must the font match across all nodes?
3715 SwFont aFont( &GetTextNodeForParaProps()->GetSwAttrSet(), pIDSA );
3716
3717 // we must ensure that the font is restored correctly on the OutputDevice
3718 // otherwise Last!=Owner could occur
3719 if ( pLastFont )
3720 {
3721 SwFntObj *pOldFont = pLastFont;
3722 pLastFont = nullptr;
3723 aFont.SetFntChg( true );
3724 aFont.ChgPhysFnt( pVsh, *pOut );
3725 mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
3726 assert(pLastFont && "coverity[var_deref_model] - pLastFont should be set in SwSubFont::ChgFnt");
3727 pLastFont->Unlock();
3728 pLastFont = pOldFont;
3729 pLastFont->SetDevFont( pVsh, *pOut );
3730 }
3731 else
3732 {
3733 vcl::Font aOldFont = pOut->GetFont();
3734 aFont.SetFntChg( true );
3735 aFont.ChgPhysFnt( pVsh, *pOut );
3736 mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
3737 assert(pLastFont && "coverity[var_deref_model] - pLastFont should be set in SwSubFont::ChgFnt");
3738 pLastFont->Unlock();
3739 pLastFont = nullptr;
3740 pOut->SetFont( aOldFont );
3741 }
3742 }
3743 else
3744 {
3745 // new determination of last line height - take actually height of last line
3746 // i#89000
3747 // assure same results, if paragraph is undersized
3748 if ( IsUndersized() )
3749 {
3751 }
3752 else
3753 {
3754 bool bCalcHeightOfLastLine = true;
3755 if ( ( !HasPara() && IsEmpty( ) ) || GetText().isEmpty() )
3756 {
3758 bCalcHeightOfLastLine = false;
3759 }
3760
3761 if ( bCalcHeightOfLastLine )
3762 {
3763 OSL_ENSURE( HasPara(),
3764 "<SwTextFrame::CalcHeightOfLastLine()> - missing paragraph portions." );
3765 const SwLineLayout* pLineLayout = GetPara();
3766 while ( pLineLayout && pLineLayout->GetNext() )
3767 {
3768 // iteration to last line
3769 pLineLayout = pLineLayout->GetNext();
3770 }
3771 if ( pLineLayout )
3772 {
3773 SwTwips nAscent, nDescent, nDummy1, nDummy2;
3774 // i#47162 - suppress consideration of
3775 // fly content portions and the line portion.
3776 pLineLayout->MaxAscentDescent( nAscent, nDescent,
3777 nDummy1, nDummy2,
3778 nullptr, true );
3779 // i#71281
3780 // Suppress wrong invalidation of printing area, if method is
3781 // called recursive.
3782 // Thus, member <mnHeightOfLastLine> is only set directly, if
3783 // no recursive call is needed.
3784 const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
3785 // i#47162 - if last line only contains
3786 // fly content portions, <mnHeightOfLastLine> is zero.
3787 // In this case determine height of last line by the font
3788 if ( nNewHeightOfLastLine == 0 )
3789 {
3790 CalcHeightOfLastLine( true );
3791 }
3792 else
3793 {
3794 mnHeightOfLastLine = nNewHeightOfLastLine;
3795 }
3796 }
3797 }
3798 }
3799 }
3800 // i#71281
3801 // invalidate printing area, if height of last line changes
3802 if ( mnHeightOfLastLine != nOldHeightOfLastLine )
3803 {
3804 InvalidatePrt();
3805 }
3806}
3807
3817tools::Long SwTextFrame::GetLineSpace( const bool _bNoPropLineSpace ) const
3818{
3819 tools::Long nRet = 0;
3820
3822
3823 switch( rSpace.GetInterLineSpaceRule() )
3824 {
3825 case SvxInterLineSpaceRule::Prop:
3826 {
3827 if ( _bNoPropLineSpace )
3828 {
3829 break;
3830 }
3831
3832 // i#11860 - adjust spacing implementation for object positioning
3833 // - compatibility to MS Word
3834 nRet = GetHeightOfLastLine();
3835
3836 tools::Long nTmp = nRet;
3837 nTmp *= rSpace.GetPropLineSpace();
3838 nTmp /= 100;
3839 nTmp -= nRet;
3840 if ( nTmp > 0 )
3841 nRet = nTmp;
3842 else
3843 nRet = 0;
3844 }
3845 break;
3846 case SvxInterLineSpaceRule::Fix:
3847 {
3848 if ( rSpace.GetInterLineSpace() > 0 )
3849 nRet = rSpace.GetInterLineSpace();
3850 }
3851 break;
3852 default:
3853 break;
3854 }
3855 return nRet;
3856}
3857
3859{
3860 if ( !HasPara() )
3861 {
3863 return IsVertical() ? o3tl::narrowing<sal_uInt16>(getFramePrintArea().Width()) : o3tl::narrowing<sal_uInt16>(getFramePrintArea().Height());
3864 return USHRT_MAX;
3865 }
3866 const SwParaPortion *pPara = GetPara();
3867 if ( !pPara )
3868 return USHRT_MAX;
3869
3870 // tdf#146500 Lines with only fly overlap cannot be "moved", so the idea
3871 // here is to continue until there's some text.
3872 // FIXME ideally we want to count a fly to the line in which it is anchored
3873 // - it may even be anchored in some other paragraph! SwFlyPortion doesn't
3874 // have a pointer sadly so no way to find out.
3875 sal_uInt16 nHeight(0);
3876 for (SwLineLayout const* pLine = pPara; pLine; pLine = pLine->GetNext())
3877 {
3878 nHeight += pLine->Height();
3879 bool hasNonFly(false);
3880 for (SwLinePortion const* pPortion = pLine->GetFirstPortion();
3881 pPortion; pPortion = pPortion->GetNextPortion())
3882 {
3883 switch (pPortion->GetWhichPor())
3884 {
3885 case PortionType::Fly:
3886 case PortionType::Glue:
3888 break;
3889 default:
3890 {
3891 hasNonFly = true;
3892 break;
3893 }
3894 }
3895 if (hasNonFly)
3896 {
3897 break;
3898 }
3899 }
3900 if (hasNonFly)
3901 {
3902 break;
3903 }
3904 }
3905 return nHeight;
3906}
3907
3909{
3910 sal_Int32 nRet = 0;
3911 SwTextFrame *pFrame = this;
3912 do
3913 {
3914 pFrame->GetFormatted();
3915 if( !pFrame->HasPara() )
3916 break;
3917 SwTextSizeInfo aInf( pFrame );
3918 SwTextMargin aLine( pFrame, &aInf );
3920 aLine.Bottom();
3921 else
3922 aLine.CharToLine( nPos );
3923 nRet = nRet + aLine.GetLineNr();
3924 pFrame = pFrame->GetFollow();
3925 } while ( pFrame && pFrame->GetOffset() <= nPos );
3926 return nRet;
3927}
3928
3930{
3931 // not necessary to format here (GetFormatted etc.), because we have to come from there!
3932 sal_Int32 nNew = 0;
3933 const SwLineNumberInfo &rInf = GetDoc().GetLineNumberInfo();
3934 if ( !GetText().isEmpty() && HasPara() )
3935 {
3936 SwTextSizeInfo aInf( this );
3937 SwTextMargin aLine( this, &aInf );
3938 if ( rInf.IsCountBlankLines() )
3939 {
3940 aLine.Bottom();
3941 nNew = aLine.GetLineNr();
3942 }
3943 else
3944 {
3945 do
3946 {
3947 if( aLine.GetCurr()->HasContent() )
3948 ++nNew;
3949 } while ( aLine.NextLine() );
3950 }
3951 }
3952 else if ( rInf.IsCountBlankLines() )
3953 nNew = 1;
3954
3955 if ( nNew == mnThisLines )
3956 return;
3957
3958 if (!IsInTab() && GetTextNodeForParaProps()->GetSwAttrSet().GetLineNumber().IsCount())
3959 {
3961 mnThisLines = nNew;
3963 SwFrame *pNxt = GetNextContentFrame();
3964 while( pNxt && pNxt->IsInTab() )
3965 {
3966 pNxt = pNxt->FindTabFrame();
3967 if( nullptr != pNxt )
3968 pNxt = pNxt->FindNextCnt();
3969 }
3970 if( pNxt )
3971 pNxt->InvalidateLineNum();
3972
3973 // Extend repaint to the bottom.
3974 if ( HasPara() )
3975 {
3976 SwRepaint& rRepaint = GetPara()->GetRepaint();
3977 rRepaint.Bottom( std::max( rRepaint.Bottom(),
3979 }
3980 }
3981 else // Paragraphs which are not counted should not manipulate the AllLines.
3982 mnThisLines = nNew;
3983}
3984
3986{
3988
3989 if ( IsInTab() )
3990 return;
3991
3992 const sal_Int32 nOld = GetAllLines();
3994 sal_Int32 nNewNum;
3995 const bool bRestart = GetDoc().GetLineNumberInfo().IsRestartEachPage();
3996
3997 if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
3998 nNewNum = rLineNum.GetStartValue() - 1;
3999 // If it is a follow or not has not be considered if it is a restart at each page; the
4000 // restart should also take effect at follows.
4001 else if ( bRestart && FindPageFrame()->FindFirstBodyContent() == this )
4002 {
4003 nNewNum = 0;
4004 }
4005 else
4006 {
4008 while ( pPrv &&
4009 (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
4010 pPrv = pPrv->GetPrevContentFrame();
4011
4012 // i#78254 Restart line numbering at page change
4013 // First body content may be in table!
4014 if ( bRestart && pPrv && pPrv->FindPageFrame() != FindPageFrame() )
4015 pPrv = nullptr;
4016
4017 nNewNum = pPrv ? static_cast<SwTextFrame*>(pPrv)->GetAllLines() : 0;
4018 }
4019 if ( rLineNum.IsCount() )
4020 nNewNum += GetThisLines();
4021
4022 if ( nOld == nNewNum )
4023 return;
4024
4025 mnAllLines = nNewNum;
4027 while ( pNxt &&
4028 (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
4029 pNxt = pNxt->GetNextContentFrame();
4030 if ( pNxt )
4031 {
4032 if ( pNxt->GetUpper() != GetUpper() )
4033 pNxt->InvalidateLineNum();
4034 else
4035 pNxt->InvalidateLineNum_();
4036 }
4037}
4038
4040{
4041 const SwParaPortion* pPara = isFrameAreaDefinitionValid() ? GetPara() : nullptr;
4042
4043 if (pPara)
4044 {
4045 if ( IsFollow() )
4046 rPH.Skip( GetOffset() );
4047
4048 const SwLineLayout* pLine = pPara;
4049 while ( pLine )
4050 {
4051 const SwLinePortion* pPor = pLine->GetFirstPortion();
4052 while ( pPor )
4053 {
4054 pPor->HandlePortion( rPH );
4055 pPor = pPor->GetNextPortion();
4056 }
4057
4058 rPH.LineBreak();
4059 pLine = pLine->GetNext();
4060 }
4061 }
4062
4063 rPH.Finish();
4064}
4065
4067{
4068 const SwParaPortion* pPara = GetPara();
4069 return pPara ? &pPara->GetScriptInfo() : nullptr;
4070}
4071
4075static SwTwips lcl_CalcFlyBasePos( const SwTextFrame& rFrame, SwRect aFlyRect,
4076 SwTextFly const & rTextFly )
4077{
4078 SwRectFnSet aRectFnSet(&rFrame);
4079 SwTwips nRet = rFrame.IsRightToLeft() ?
4080 aRectFnSet.GetRight(rFrame.getFrameArea()) :
4081 aRectFnSet.GetLeft(rFrame.getFrameArea());
4082
4083 do
4084 {
4085 SwRect aRect = rTextFly.GetFrame( aFlyRect );
4086 if ( 0 != aRectFnSet.GetWidth(aRect) )
4087 {
4088 if ( rFrame.IsRightToLeft() )
4089 {
4090 if ( aRectFnSet.GetRight(aRect) -
4091 aRectFnSet.GetRight(aFlyRect) >= 0 )
4092 {
4093 aRectFnSet.SetRight(
4094aFlyRect, aRectFnSet.GetLeft(aRect) );
4095 nRet = aRectFnSet.GetLeft(aRect);
4096 }
4097 else
4098 break;
4099 }
4100 else
4101 {
4102 if ( aRectFnSet.GetLeft(aFlyRect) -
4103 aRectFnSet.GetLeft(aRect) >= 0 )
4104 {
4105 aRectFnSet.SetLeft(
4106aFlyRect, aRectFnSet.GetRight(aRect) + 1 );
4107 nRet = aRectFnSet.GetRight(aRect);
4108 }
4109 else
4110 break;
4111 }
4112 }
4113 else
4114 break;
4115 }
4116 while ( aRectFnSet.GetWidth(aFlyRect) > 0 );
4117
4118 return nRet;
4119}
4120
4122{
4123 OSL_ENSURE( !IsVertical() || !IsSwapped(),
4124 "SwTextFrame::CalcBasePosForFly with swapped frame!" );
4125
4126 if (!GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::ADD_FLY_OFFSETS))
4127 return;
4128
4129 SwRectFnSet aRectFnSet(this);
4130
4132
4133 // Get first 'real' line and adjust position and height of line rectangle.
4134 // Correct behaviour if no 'real' line exists
4135 // (empty paragraph with and without a dummy portion)
4136 SwTwips nFlyAnchorVertOfstNoWrap = 0;
4137 {
4138 SwTwips nTop = aRectFnSet.GetTop(aFlyRect);
4139 const SwLineLayout* pLay = GetPara();
4140 SwTwips nLineHeight = 200;
4141 while( pLay && pLay->IsDummy() && pLay->GetNext() )
4142 {
4143 nTop += pLay->Height();
4144 nFlyAnchorVertOfstNoWrap += pLay->Height();
4145 pLay = pLay->GetNext();
4146 }
4147 if ( pLay )
4148 {
4149 nLineHeight = pLay->Height();
4150 }
4151 aRectFnSet.SetTopAndHeight( aFlyRect, nTop, nLineHeight );
4152 }
4153
4154 SwTextFly aTextFly( this );
4155 aTextFly.SetIgnoreCurrentFrame( true );
4156 aTextFly.SetIgnoreContour( true );
4157 // ignore objects in page header|footer for
4158 // text frames not in page header|footer
4159 aTextFly.SetIgnoreObjsInHeaderFooter( true );
4160 SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTextFly );
4161 aTextFly.SetIgnoreCurrentFrame( false );
4162 SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTextFly );
4163
4164 // make values relative to frame start position
4165 SwTwips nLeft = IsRightToLeft() ?
4166 aRectFnSet.GetRight(getFrameArea()) :
4167 aRectFnSet.GetLeft(getFrameArea());
4168
4169 mnFlyAnchorOfst = nRet1 - nLeft;
4170 mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
4171
4172 if (!GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS))
4173 return;
4174
4175 if (mnFlyAnchorOfstNoWrap > 0)
4176 mnFlyAnchorVertOfstNoWrap = nFlyAnchorVertOfstNoWrap;
4177}
4178
4179SwTwips SwTextFrame::GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const
4180{
4181 return bIgnoreFlysAnchoredAtThisFrame ? 0 : mnFlyAnchorVertOfstNoWrap;
4182}
4183
4188{
4190 for( const SwTextFrame *pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
4191 {
4192 SwRect aRec( pFrame->GetPaintArea() );
4193 const SwRootFrame *pRootFrame = pFrame->getRootFrame();
4194 SwViewShell *pCurShell = pRootFrame ? pRootFrame->GetCurrShell() : nullptr;
4195 if( pCurShell )
4196 pCurShell->InvalidateWindows( aRec );
4197 }
4198}
4199
4201{
4202 if (pWrtSh && pWrtSh->GetViewOptions()->IsShowOutlineContentVisibilityButton() &&
4203 GetTextNodeFirst()->IsOutline())
4204 {
4205 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
4208 }
4209}
4210
4211/* 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.
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
constexpr tools::Long X() const
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)
static TextNumerals GetCTLTextNumerals()
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:353
void ClearItem(sal_uInt16 nWhichL)
Definition: hints.cxx:122
const SwFormatLineNumber & GetLineNumber(bool=true) const
Definition: fmtline.hxx:66
const SvxLineSpacingItem & GetLineSpacing(bool=true) const
Definition: paratr.hxx:201
SwBorderAttrs * Get()
Definition: frmtool.cxx:2696
tools::Long CalcLeft(const SwFrame *pCaller) const
Definition: frmtool.cxx:2382
tools::Long CalcRight(const SwFrame *pCaller) const
Definition: frmtool.cxx:2311
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
virtual void MoveObjToInvisibleLayer(SdrObject *_pDrawObj)
method to move drawing object to corresponding invisible layer
Definition: dcontact.cxx:237
const SwFormatAnchor & GetAnchorFormat() const
some virtual helper methods for information about the object (Writer fly frame resp.
Definition: dcontact.hxx:138
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:59
SwContentFrame * GetPrevContentFrame() const
Definition: cntfrm.hxx:128
virtual void DestroyImpl() override
Definition: ssfrm.cxx:428
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:120
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:762
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: wsfrm.cxx:2353
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1223
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:727
LanguageType nOldLanguageType
Definition: txtfrm.hxx:978
SwDigitModeModifier(const OutputDevice &rOutp, LanguageType eCurLang)
Definition: txtfrm.cxx:724
const OutputDevice & rOut
Definition: txtfrm.hxx:977
Definition: doc.hxx:197
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:645
bool FieldHidesPara(const SwField &rField) const
Definition: doc.cxx:1385
IDocumentDeviceAccess const & getIDocumentDeviceAccess() const
Definition: doc.cxx:252
const SwLineNumberInfo & GetLineNumberInfo() const
Definition: lineinfo.cxx:49
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:371
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:649
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:190
int FieldCanHideParaWeight(SwFieldIds eFieldId) const
Definition: doc.cxx:1370
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:6832
SwFieldIds Which() const
Definition: fldbas.hxx:276
SwFieldType * GetTyp() const
Definition: fldbas.hxx:402
void SetDevFont(const SwViewShell *pSh, OutputDevice &rOut)
Definition: fntcache.cxx:568
To take Asian or other languages into consideration, an SwFont object consists of 3 SwSubFonts (Latin...
Definition: swfont.hxx:135
void SetFntChg(const bool bNew)
Definition: swfont.hxx:212
void ChgPhysFnt(SwViewShell const *pSh, OutputDevice &rOut)
Definition: swfont.cxx:893
tools::Long GetHeight() const
Definition: swfont.hxx:287
bool RemoveFootnote(const SwContentFrame *, const SwTextFootnote *, bool bPrep=true)
Definition: ftnfrm.cxx:1736
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
FlyAnchors.
Definition: fmtanchr.hxx:37
sal_Int32 GetAnchorContentOffset() const
Definition: atrfrm.cxx:1631
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1614
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const SwField * GetField() const
Definition: fmtfld.hxx:131
SfxPoolItem subclass for footnotes and endnotes, stored in the anchor text node.
Definition: fmtftn.hxx:47
Contains the line numbering properties of this paragraph.
Definition: fmtline.hxx:33
bool IsCount() const
Definition: fmtline.hxx:60
sal_uLong GetStartValue() const
Definition: fmtline.hxx:59
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
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:72
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:956
SwFrameSwapper(const SwTextFrame *pFrame, bool bSwapIfNotSwapped)
Definition: txtfrm.cxx:667
const SwTextFrame * pFrame
Definition: txtfrm.hxx:957
Base class of the Writer layout elements.
Definition: frame.hxx:315
void InvalidateLineNum_()
Definition: frame.hxx:801
bool IsTextFrame() const
Definition: frame.hxx:1240
void SetDerivedR2L(bool bNew)
Definition: frame.hxx:636
bool IsInDtor() const
Definition: frame.hxx:898
void InvalidateLineNum()
Definition: frame.hxx:1056
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:195
bool IsInDocBody() const
Definition: frame.hxx:949
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1121
SwContentFrame * FindPrevCnt()
Definition: findfrm.cxx:201
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwFrame * FindNext()
Definition: frame.hxx:1147
SwFrame * GetNext()
Definition: frame.hxx:682
SwFrameType mnFrameType
Definition: frame.hxx:414
bool IsVertLRBT() const
Definition: frame.hxx:989
bool IsInFootnote() const
Definition: frame.hxx:955
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1799
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:568
bool IsInTab() const
Definition: frame.hxx:961
static SwCache & GetCache()
Definition: frame.hxx:523
bool IsRightToLeft() const
Definition: frame.hxx:993
bool IsInFly() const
Definition: frame.hxx:967
void InvalidateNextPrtArea()
method to invalidate printing area of next frame #i11859#
Definition: findfrm.cxx:1367
void dumpInfosAsXml(xmlTextWriterPtr writer) const
Definition: xmldump.cxx:171
void InvalidatePrt()
Definition: frame.hxx:1042
void ValidateLineNum()
Definition: frame.hxx:766
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
bool IsVertical() const
Definition: frame.hxx:979
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:618
SwRootFrame * getRootFrame()
Definition: frame.hxx:685
bool IsNoTextFrame() const
Definition: frame.hxx:1244
void SetCompletePaint() const
Definition: frame.hxx:1000
void InvalidatePrt_()
Definition: frame.hxx:785
SwFrame * GetPrev()
Definition: frame.hxx:683
void InvalidateSize_()
Definition: frame.hxx:777
bool IsVertLR() const
Definition: frame.hxx:985
void InvalidateSize()
Definition: frame.hxx:1035
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:217
void SetInvalidVert(bool bNew)
Definition: frame.hxx:634
SwPageFrame * FindPageFrame()
Definition: frame.hxx:686
sw::BroadcastingModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:478
SwFrame * GetIndNext()
Definition: frame.hxx:733
bool IsLayoutFrame() const
Definition: frame.hxx:1176
bool IsInSct() const
Definition: frame.hxx:973
void MoveGrammar(sal_Int32 nPos, sal_Int32 nDiff)
TElementType * Next()
Definition: calbck.hxx:380
TElementType * First()
Definition: calbck.hxx:372
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method <ContainsAny()> doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:131
const OutputDevice & m_rOut
Definition: txtfrm.hxx:966
SwLayoutModeModifier(const OutputDevice &rOutp)
Definition: txtfrm.cxx:701
void Modify(bool bChgToRTL)
Definition: txtfrm.cxx:711
vcl::text::ComplexTextLayoutFlags m_nOldLayoutMode
Definition: txtfrm.hxx:967
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:231
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
void dumpAsXmlAttributes(xmlTextWriterPtr writer, std::u16string_view rText, TextFrameIndex nOffset) const
Definition: porlin.cxx:333
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:75
bool InNumberGrp() const
Definition: porlin.hxx:109
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
virtual void dumpAsXml(xmlTextWriterPtr pWriter, const OUString &rText, TextFrameIndex &rOffset) const
Definition: porlin.cxx:324
virtual void HandlePortion(SwPortionHandler &rPH) const
Definition: porlin.cxx:319
bool IsFootnoteNumPortion() const
Definition: porlin.hxx:128
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:123
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodeOffset GetIndex() const
Definition: node.hxx:312
bool IsNoTextNode() const
Definition: node.hxx:194
SwDoc & GetDoc()
Definition: node.hxx:233
Merge GetRedlineMergeFlag() const
Definition: node.hxx:116
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:87
A page of the document layout.
Definition: pagefrm.hxx:60
void InvalidateWordCount() const
Definition: pagefrm.hxx:406
void InvalidateAutoCompleteWords() const
Definition: pagefrm.hxx:402
void InvalidateSmartTags() const
Definition: pagefrm.hxx:398
void InvalidateSpelling() const
Definition: pagefrm.hxx:393
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:2647
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()=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:1372
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1387
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1395
void SetPosX(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1405
void SetRight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1394
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1386
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1396
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1382
void SetPosY(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1406
void SetTopAndHeight(SwRect &rRect, tools::Long nTop, tools::Long nHeight) const
Definition: frame.hxx:1433
tools::Long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1409
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1384
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1383
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1385
void SetLeft(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1393
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:85
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:215
bool HasMergedParas() const
Definition: wsfrm.cxx:4773
void SetNeedGrammarCheck(bool bVal)
Definition: rootfrm.hxx:271
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:2025
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:3245
SwTestFormat(SwTextFrame *pTextFrame, const SwFrame *pPrv, SwTwips nMaxHeight)
Definition: txtfrm.cxx:3254
SwParaPortion * pOldPara
Definition: txtfrm.cxx:3247
SwRect aOldPrt
Definition: txtfrm.cxx:3248
SwTextFrame * pFrame
Definition: txtfrm.cxx:3246
SwRect aOldFrame
Definition: txtfrm.cxx:3248
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:125
void SetIgnoreObjsInHeaderFooter(const bool bNew)
Definition: txtfly.hxx:384
void SetIgnoreContour(bool bNew)
Definition: txtfly.hxx:379
void SetIgnoreCurrentFrame(bool bNew)
Definition: txtfly.hxx:374
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:331
SwRect GetFrame(const SwRect &rPortion) const
Definition: txtfly.hxx:369
bool IsOn() const
Definition: txtfly.hxx:326
SwTextAttr subclass for footnotes and endnotes.
Definition: txtftn.hxx:34
void DelFrames(const SwRootFrame *)
Definition: atrftn.cxx:475
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:72
void SetIgnoreFly(const bool bNew)
Definition: inftxt.hxx:576
SwTwips CalcFitToContent_()
Definition: itrform2.cxx:2340
void RecalcRealHeight()
Definition: itrform2.cxx:2101
bool IsBreakNow(SwTextMargin &rLine)
Definition: widorp.cxx:224
bool IsKeepAlways() const
Definition: widorp.hxx:38
bool IsInside(SwTextMargin const &rLine) const
BP 18.6.93: Widows.
Definition: widorp.cxx:106
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
void 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
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:3493
bool IsFootnoteNumFrame() const
Am I a FootnoteFrame, with a number at the start of the paragraph?
Definition: txtfrm.hxx:640
SwDoc & GetDoc()
Definition: txtfrm.hxx:475
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout.
Definition: txtfrm.cxx:580
bool TestFormat(const SwFrame *pPrv, SwTwips &nMaxHeight, bool &bSplit)
The WouldFit equivalent for temporarily rewired TextFrames nMaxHeight returns the required size here ...
Definition: txtfrm.cxx:3332
void SetOffset(TextFrameIndex nNewOfst)
Definition: txtfrm.hxx:899
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:889
void CalcFootnoteFlag(TextFrameIndex nStop=TextFrameIndex(COMPLETE_STRING))
Does the Frame have a local footnote (in this Frame or Follow)?
Definition: txtftn.cxx:104
void HideAndShowObjects()
Hides respectively shows objects, which are anchored at paragraph, at/as a character of the paragraph...
Definition: txtfrm.cxx:1657
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1333
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1430
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:453
bool HasPara() const
Definition: txtfrm.hxx:853
void UpdateOutlineContentVisibilityButton(SwWrtShell *pWrtSh) const
Definition: txtfrm.cxx:4200
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1318
void InvalidateRange(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1797
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:1361
bool FormatQuick(bool bForceQuickFormat)
Definition: frmform.cxx:2192
SwTwips GetBaseVertOffsetForFly(bool bIgnoreFlysAnchoredAtThisFrame) const
Definition: txtfrm.cxx:4179
bool IsWidow() const
Definition: txtfrm.hxx:537
bool IsSwapped() const
Definition: txtfrm.hxx:553
SwTwips mnFlyAnchorOfst
Definition: txtfrm.hxx:189
void HideHidden()
Removes Textfrm's attachments, when it's hidden.
Definition: txtfrm.cxx:1551
void CalcBaseOfstForFly()
Definition: txtfrm.cxx:4121
SwTextNode const * GetTextNodeForFirstText() const
Definition: txtfrm.cxx:1404
SwTwips mnHeightOfLastLine
Definition: txtfrm.hxx:197
virtual bool WouldFit(SwTwips &nMaxHeight, bool &bSplit, bool bTst, bool bMoveBwd) override
nMaxHeight is the required height bSplit indicates, that the paragraph has to be split bTst indicates...
Definition: txtfrm.cxx:3356
bool IsIdxInside(TextFrameIndex nPos, TextFrameIndex nLen) const
Definition: txtfrm.cxx:1766
sal_Int32 GetAllLines() const
For displaying the line numbers.
Definition: txtfrm.hxx:685
void ClearPara()
Removes the Line information from the Cache but retains the entry itself.
Definition: txtcache.cxx:104
virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override
Definition: xmldump.cxx:297
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
Calculates the frame area size and the print area, in case they are invalid.
Definition: frmform.cxx:1881
void CalcLineSpace()
Definition: txtfrm.cxx:1837
void PrepWidows(const sal_uInt16 nNeed, bool bNotify)
Definition: txtfrm.cxx:2760
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:465
bool HasFootnote() const
Definition: txtfrm.hxx:540
sal_Int32 mnAllLines
Definition: txtfrm.hxx:184
void SetWidow(const bool bNew)
Definition: txtfrm.hxx:254
void ResetPreps()
Definition: txtfrm.cxx:1438
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:3678
sal_Int32 mnThisLines
Definition: txtfrm.hxx:185
static void repaintTextFrames(const SwTextNode &rNode)
Repaint all text frames of the given text node.
Definition: txtfrm.cxx:4187
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:3592
SwTwips GetParHeight() const
Returns the sum of line height in pLine.
Definition: txtfrm.cxx:3453
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
void dumpAsXml(xmlTextWriterPtr writer=nullptr) const override
Definition: txtfrm.cxx:796
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1339
virtual bool GetInfo(SfxPoolItem &) const override
Definition: txtfrm.cxx:2749
void SetHasRotatedPortions(bool bHasRotatedPortions)
Definition: txtftn.cxx:98
bool IsLocked() const
Definition: txtfrm.hxx:535
SwTwips mnFlyAnchorOfstNoWrap
Definition: txtfrm.hxx:191
SwTwips CalcFitToContent()
Simulates a formatting as if there were not right margin or Flys or other obstacles and returns the w...
Definition: txtfrm.cxx:3518
void InvalidateRange_(const SwCharRange &, const tools::Long=0)
Definition: txtfrm.cxx:1803
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout.
Definition: txtfrm.cxx:473
void VisitPortions(SwPortionHandler &rPH) const
Visit all portions for Accessibility.
Definition: txtfrm.cxx:4039
std::unique_ptr< sw::MergedPara > m_pMergedPara
redline merge data
Definition: txtfrm.hxx:205
tools::Long GetLineSpace(const bool _bNoPropLineSpacing=false) const
Returns the additional line spacing for the next paragraph.
Definition: txtfrm.cxx:3817
void SetFieldFollow(const bool bNew)
Definition: txtfrm.hxx:257
void HideFootnotes(TextFrameIndex nStart, TextFrameIndex nEnd)
Definition: txtfrm.cxx:1563
SwTextFrame(SwTextNode *const, SwFrame *, sw::FrameMode eMode)
Definition: txtfrm.cxx:764
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1354
SwTwips mnFlyAnchorVertOfstNoWrap
The y position for wrap-through flys anchored at this paragraph.
Definition: txtfrm.hxx:193
static TextFrameIndex FindBrk(std::u16string_view aText, TextFrameIndex nStart, TextFrameIndex nEnd)
Returns the first possible break point in the current line.
Definition: txtfrm.cxx:1741
bool IsHiddenNow() const
Hidden.
Definition: txtfrm.cxx:1447
void Format_(SwTextFormatter &rLine, SwTextFormatInfo &rInf, const bool bAdjust=false)
Definition: frmform.cxx:1408
void ChgThisLines()
Definition: txtfrm.cxx:3929
sal_Int32 GetLineCount(TextFrameIndex nPos)
Determines the line count.
Definition: txtfrm.cxx:3908
sal_Int32 GetThisLines() const
Definition: txtfrm.hxx:686
const SwScriptInfo * GetScriptInfo() const
Returns the script info stored at the paraportion.
Definition: txtfrm.cxx:4066
sal_uInt16 GetCacheIdx() const
Definition: txtfrm.hxx:631
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:472
void RemoveFromCache()
Removes this frame completely from the Cache.
Definition: txtcache.cxx:120
void SetOffset_(TextFrameIndex nNewOfst)
Definition: frmform.cxx:822
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true) override
SwContentFrame: the shortcut for the Frames If the void* casts wrongly, it's its own fault!...
Definition: txtfrm.cxx:2840
virtual ~SwTextFrame() override
Definition: txtfrm.cxx:979
SwTwips GetHeightOfLastLine() const
Definition: txtfrm.hxx:785
void ManipOfst(TextFrameIndex const nNewOfst)
Definition: txtfrm.hxx:456
void SwapWidthAndHeight()
Swaps width and height of the text frame.
Definition: txtfrm.cxx:420
void RecalcAllLines()
Definition: txtfrm.cxx:3985
sal_uInt16 FirstLineHeight() const
Returns the first line height.
Definition: txtfrm.cxx:3858
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1380
SwTwips mnAdditionalFirstLineOffset
Definition: txtfrm.hxx:202
bool mbIsSwapped
Definition: txtfrm.hxx:243
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1390
virtual void SwClientNotify(SwModify const &rModify, SfxHint const &rHint) override
Definition: txtfrm.cxx:2083
bool IsEmpty() const
Definition: txtfrm.hxx:539
virtual void DestroyImpl() override
Definition: txtfrm.cxx:937
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_Int32 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:112
void SetWrongDirty(sw::WrongState eNew) const
Definition: txtedt.cxx:2345
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:291
bool IsSmartTagDirty() const
Definition: txtedt.cxx:2375
SwWrongList * GetSmartTags()
Definition: txtedt.cxx:2325
SwWrongList * GetWrong()
Definition: txtedt.cxx:2271
void SetWordCountDirty(bool bNew) const
Definition: txtedt.cxx:2335
void SetGrammarCheckDirty(bool bNew) const
Definition: txtedt.cxx:2360
void SetSmartTags(std::unique_ptr< SwWrongList > pNew)
Definition: txtedt.cxx:2307
void SetSmartTagDirty(bool bNew) const
Definition: txtedt.cxx:2370
void SetAutoCompleteWordDirty(bool bNew) const
Definition: txtedt.cxx:2380
bool IsCountedInList() const
Definition: ndtxt.cxx:4393
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2921
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:4248
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2989
SwGrammarMarkUp * GetGrammarCheck()
Definition: txtedt.cxx:2297
bool IsWrongDirty() const
Definition: txtedt.cxx:2355
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:252
void SetWrong(std::unique_ptr< SwWrongList > pNew)
Definition: txtedt.cxx:2256
const OUString & GetText() const
Definition: ndtxt.hxx:244
void AddToListRLHidden()
Definition: ndtxt.cxx:4480
void RemoveFromListRLHidden()
Definition: ndtxt.cxx:4522
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:3155
SwTextFly & GetTextFly()
Definition: inftxt.hxx:387
const std::vector< sal_uInt16 > & getFmtAttrs() const
Definition: hints.hxx:293
sal_uInt16 getWhichAttr() const
Definition: hints.hxx:288
sal_Int32 getStart() const
Definition: hints.hxx:278
sal_Int32 getEnd() const
Definition: hints.hxx:283
bool IsShowOutlineContentVisibilityButton() const
Definition: viewopt.cxx:177
bool IsShowHiddenPara() const
Definition: viewopt.hxx:568
bool IsPrtFormat() const
Definition: viewopt.hxx:705
bool getBrowseMode() const
Definition: viewopt.hxx:636
bool IsShowHiddenChar(bool bHard=false) const
Definition: viewopt.hxx:487
bool IsFieldName() const
Definition: viewopt.hxx:417
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:365
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:452
void InvalidateAccessibleParaAttrs(const SwTextFrame &rTextFrame)
invalidate attributes for paragraphs and paragraph's characters
Definition: viewsh.cxx:2625
vcl::Window * GetWin() const
Definition: viewsh.hxx:364
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:568
Definition: view.hxx:146
SwEditWin & GetEditWin()
Definition: view.hxx:426