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