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