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