LibreOffice Module sw (master)  1
txtftn.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 <sal/config.h>
21 
22 #include <string_view>
23 
24 #include <viewsh.hxx>
25 #include <doc.hxx>
27 #include <pagefrm.hxx>
28 #include <rootfrm.hxx>
29 #include <ndtxt.hxx>
30 #include <SwPortionHandler.hxx>
31 #include <txtftn.hxx>
32 #include <flyfrm.hxx>
33 #include <fmtftn.hxx>
34 #include <ftninfo.hxx>
35 #include <charfmt.hxx>
36 #include <rowfrm.hxx>
37 #include <editeng/brushitem.hxx>
39 #include <tabfrm.hxx>
40 #include <sortedobjs.hxx>
41 
42 #include <swfont.hxx>
43 #include "porftn.hxx"
44 #include "porfly.hxx"
45 #include "porlay.hxx"
46 #include <txtfrm.hxx>
47 #include "itrform2.hxx"
48 #include <ftnfrm.hxx>
49 #include <pagedesc.hxx>
50 #include "redlnitr.hxx"
51 #include <sectfrm.hxx>
52 #include <layouter.hxx>
53 #include <frmtool.hxx>
54 #include <ndindex.hxx>
57 #include <swmodule.hxx>
58 #include <unotextrange.hxx>
59 #include <redline.hxx>
60 #include <editeng/colritem.hxx>
61 #include <editeng/udlnitem.hxx>
63 
64 #include <com/sun/star/beans/XPropertySet.hpp>
65 #include <com/sun/star/awt/CharSet.hpp>
66 #include <com/sun/star/text/XTextRange.hpp>
67 
68 using namespace ::com::sun::star;
69 
71 {
72  if (IsInTab())
73  return false; // tdf#102073 first frame in cell doesn't have mpPrev set
74  const SwFootnoteFrame* pFootnote = FindFootnoteFrame()->GetMaster();
75  while( pFootnote && !pFootnote->ContainsContent() )
76  pFootnote = pFootnote->GetMaster();
77  return !pFootnote;
78 }
79 
84 {
85  SwTextFrame *pFrame = this;
86  const bool bFwd = MapModelToView(&pFootnote->GetTextNode(), pFootnote->GetStart()) >= GetOffset();
87  while( pFrame )
88  {
89  if( SwFootnoteBossFrame::FindFootnote( pFrame, pFootnote ) )
90  return pFrame;
91  pFrame = bFwd ? pFrame->GetFollow() :
92  pFrame->IsFollow() ? pFrame->FindMaster() : nullptr;
93  }
94  return pFrame;
95 }
96 
97 void SwTextFrame::SetHasRotatedPortions(bool bHasRotatedPortions)
98 {
99  mbHasRotatedPortions = bHasRotatedPortions;
100 }
101 
102 #ifdef DBG_UTIL
103 void SwTextFrame::CalcFootnoteFlag(TextFrameIndex nStop) // For testing the SplitFrame
104 #else
106 #endif
107 {
108  mbFootnote = false;
109 
110 #ifdef DBG_UTIL
111  const TextFrameIndex nEnd = nStop != TextFrameIndex(COMPLETE_STRING)
112  ? nStop
113  : GetFollow() ? GetFollow()->GetOffset() : TextFrameIndex(COMPLETE_STRING);
114 #else
115  const TextFrameIndex nEnd = GetFollow()
116  ? GetFollow()->GetOffset()
118 #endif
119 
120  SwTextNode const* pNode(nullptr);
121  sw::MergedAttrIter iter(*this);
122  for (SwTextAttr const* pHt = iter.NextAttr(&pNode); pHt; pHt = iter.NextAttr(&pNode))
123  {
124  if ( pHt->Which() == RES_TXTATR_FTN )
125  {
126  TextFrameIndex const nIdx(MapModelToView(pNode, pHt->GetStart()));
127  if ( nEnd < nIdx )
128  break;
129  if( GetOffset() <= nIdx )
130  {
131  mbFootnote = true;
132  break;
133  }
134  }
135  }
136 }
137 
139 {
140  OSL_ENSURE( HasFootnote(), "Who´s calling me?" );
142  const SwFootnoteFrame *pFootnote = pBoss->FindFirstFootnote( this );
143  if (pFootnote && FTNPOS_CHAPTER != GetDoc().GetFootnoteInfo().m_ePos &&
144  ( !pBoss->GetUpper()->IsSctFrame() ||
145  !static_cast<SwSectionFrame*>(pBoss->GetUpper())->IsFootnoteAtEnd() ) )
146  {
147  const SwFootnoteContFrame *pCont = pBoss->FindFootnoteCont();
148  bool bReArrange = true;
149 
150  SwRectFnSet aRectFnSet(this);
151  if ( pCont && aRectFnSet.YDiff( aRectFnSet.GetTop(pCont->getFrameArea()),
152  aRectFnSet.GetBottom(getFrameArea()) ) > 0 )
153  {
154  pBoss->RearrangeFootnotes( aRectFnSet.GetBottom(getFrameArea()), false,
155  pFootnote->GetAttr() );
157  ValidateFrame();
158  pFootnote = pBoss->FindFirstFootnote( this );
159  }
160  else
161  bReArrange = false;
162  if( !pCont || !pFootnote || bReArrange != (pFootnote->FindFootnoteBossFrame() == pBoss) )
163  {
164  SwTextFormatInfo aInf( getRootFrame()->GetCurrShell()->GetOut(), this );
165  SwTextFormatter aLine( this, &aInf );
166  aLine.TruncLines();
167  SetPara( nullptr ); // May be deleted!
168  ResetPreps();
169  return false;
170  }
171  }
172  return true;
173 }
174 
179 static SwTwips lcl_GetFootnoteLower( const SwTextFrame* pFrame, SwTwips nLower )
180 {
181  // nLower is an absolute value. It denotes the bottom of the line
182  // containing the footnote.
183  SwRectFnSet aRectFnSet(pFrame);
184 
185  OSL_ENSURE( !pFrame->IsVertical() || !pFrame->IsSwapped(),
186  "lcl_GetFootnoteLower with swapped frame" );
187 
188  SwTwips nAdd;
189  SwTwips nRet = nLower;
190 
191  // Check if text is inside a table.
192  if ( pFrame->IsInTab() )
193  {
194  // If pFrame is inside a table, we have to check if
195  // a) The table is not allowed to split or
196  // b) The table row is not allowed to split
197 
198  // Inside a table, there are no footnotes,
199  // see SwFrame::FindFootnoteBossFrame. So we don't have to check
200  // the case that pFrame is inside a (footnote collecting) section
201  // within the table.
202  const SwFrame* pRow = pFrame;
203  while( !pRow->IsRowFrame() || !pRow->GetUpper()->IsTabFrame() )
204  pRow = pRow->GetUpper();
205  const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pRow->GetUpper());
206 
207  OSL_ENSURE( pTabFrame && pRow &&
208  pRow->GetUpper()->IsTabFrame(), "Upper of row should be tab" );
209 
210  const bool bDontSplit = !pTabFrame->IsFollow() &&
211  !pTabFrame->IsLayoutSplitAllowed();
212 
213  SwTwips nMin = 0;
214  if ( bDontSplit )
215  nMin = aRectFnSet.GetBottom(pTabFrame->getFrameArea());
216  else if ( !static_cast<const SwRowFrame*>(pRow)->IsRowSplitAllowed() )
217  nMin = aRectFnSet.GetBottom(pRow->getFrameArea());
218 
219  if ( nMin && aRectFnSet.YDiff( nMin, nLower ) > 0 )
220  nRet = nMin;
221 
222  nAdd = aRectFnSet.GetBottomMargin(*pRow->GetUpper());
223  }
224  else
225  nAdd = aRectFnSet.GetBottomMargin(*pFrame);
226 
227  if( nAdd > 0 )
228  {
229  if ( aRectFnSet.IsVert() )
230  nRet -= nAdd;
231  else
232  nRet += nAdd;
233  }
234 
235  // #i10770#: If there are fly frames anchored at previous paragraphs,
236  // the deadline should consider their lower borders.
237  const SwFrame* pStartFrame = pFrame->GetUpper()->GetLower();
238  OSL_ENSURE( pStartFrame, "Upper has no lower" );
239  SwTwips nFlyLower = aRectFnSet.IsVert() ? LONG_MAX : 0;
240  while ( pStartFrame != pFrame )
241  {
242  OSL_ENSURE( pStartFrame, "Frame chain is broken" );
243  if ( pStartFrame->GetDrawObjs() )
244  {
245  const SwSortedObjs &rObjs = *pStartFrame->GetDrawObjs();
246  for (SwAnchoredObject* pAnchoredObj : rObjs)
247  {
248  SwRect aRect( pAnchoredObj->GetObjRect() );
249 
250  auto pFlyFrame = pAnchoredObj->DynCastFlyFrame();
251  if ( !pFlyFrame ||
252  pFlyFrame->isFrameAreaDefinitionValid() )
253  {
254  const SwTwips nBottom = aRectFnSet.GetBottom(aRect);
255  if ( aRectFnSet.YDiff( nBottom, nFlyLower ) > 0 )
256  nFlyLower = nBottom;
257  }
258  }
259  }
260 
261  pStartFrame = pStartFrame->GetNext();
262  }
263 
264  if ( aRectFnSet.IsVert() )
265  nRet = std::min( nRet, nFlyLower );
266  else
267  nRet = std::max( nRet, nFlyLower );
268 
269  return nRet;
270 }
271 
273 {
274  OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
275  "SwTextFrame::GetFootnoteLine with swapped frame" );
276 
277  SwTextFrame *pThis = const_cast<SwTextFrame*>(this);
278 
279  if( !HasPara() )
280  {
281  // #109071# GetFormatted() does not work here, because most probably
282  // the frame is currently locked. We return the previous value.
283  return pThis->mnFootnoteLine > 0 ?
284  pThis->mnFootnoteLine :
286  }
287 
288  SwTwips nRet;
289  {
290  SwSwapIfNotSwapped swap(const_cast<SwTextFrame *>(this));
291 
292  SwTextInfo aInf( pThis );
293  SwTextIter aLine( pThis, &aInf );
295  &pFootnote->GetTextNode(), pFootnote->GetStart()));
296  aLine.CharToLine( nPos );
297 
298  nRet = aLine.Y() + aLine.GetLineHeight();
299  if( IsVertical() )
300  nRet = SwitchHorizontalToVertical( nRet );
301  }
302 
303  nRet = lcl_GetFootnoteLower( pThis, nRet );
304 
305  pThis->mnFootnoteLine = nRet;
306  return nRet;
307 }
308 
314 {
315  OSL_ENSURE( !IsFollow() && IsInFootnote(), "SwTextFrame::SetFootnoteLine: moon walk" );
316 
317  const SwFootnoteFrame *pFootnoteFrame = FindFootnoteFrame();
318  const SwTextFrame *pRef = static_cast<const SwTextFrame *>(pFootnoteFrame->GetRef());
320  if( pBoss != pRef->FindFootnoteBossFrame( !pFootnoteFrame->GetAttr()->
321  GetFootnote().IsEndNote() ) )
322  return 0;
323 
324  SwSwapIfSwapped swap(const_cast<SwTextFrame *>(this));
325 
326  SwTwips nHeight = pRef->IsInFootnoteConnect() ?
327  1 : pRef->GetFootnoteLine( pFootnoteFrame->GetAttr() );
328  if( nHeight )
329  {
330  // As odd as it may seem: the first Footnote on the page may not touch the
331  // Footnote Reference, when entering text in the Footnote Area.
332  const SwFrame *pCont = pFootnoteFrame->GetUpper();
333 
334  // Height within the Container which we're allowed to consume anyways
335  SwRectFnSet aRectFnSet(pCont);
336  SwTwips nTmp = aRectFnSet.YDiff( aRectFnSet.GetPrtBottom(*pCont),
337  aRectFnSet.GetTop(getFrameArea()) );
338 
339 #if OSL_DEBUG_LEVEL > 0
340  if( nTmp < 0 )
341  {
342  bool bInvalidPos = false;
343  const SwLayoutFrame* pTmp = GetUpper();
344  while( !bInvalidPos && pTmp )
345  {
346  bInvalidPos = !pTmp->isFrameAreaPositionValid() ||
347  !pTmp->Lower()->isFrameAreaPositionValid();
348  if( pTmp == pCont )
349  break;
350  pTmp = pTmp->GetUpper();
351  }
352  OSL_ENSURE( bInvalidPos, "Hanging below FootnoteCont" );
353  }
354 #endif
355 
356  if ( aRectFnSet.YDiff( aRectFnSet.GetTop(pCont->getFrameArea()), nHeight) > 0 )
357  {
358  // Growth potential of the container
359  if ( !pRef->IsInFootnoteConnect() )
360  {
361  SwSaveFootnoteHeight aSave( const_cast<SwFootnoteBossFrame*>(pBoss), nHeight );
362  nHeight = const_cast<SwFootnoteContFrame*>(static_cast<const SwFootnoteContFrame*>(pCont))->Grow( LONG_MAX, true );
363  }
364  else
365  nHeight = const_cast<SwFootnoteContFrame*>(static_cast<const SwFootnoteContFrame*>(pCont))->Grow( LONG_MAX, true );
366 
367  nHeight += nTmp;
368  if( nHeight < 0 )
369  nHeight = 0;
370  }
371  else
372  { // The container has to shrink
373  nTmp += aRectFnSet.YDiff( aRectFnSet.GetTop(pCont->getFrameArea()), nHeight);
374  if( nTmp > 0 )
375  nHeight = nTmp;
376  else
377  nHeight = 0;
378  }
379  }
380 
381  return nHeight;
382 }
383 
385 {
386  // Check whether we're in a FootnoteFrame
387  if( GetIndPrev() || !IsInFootnote() )
388  return nullptr;
389 
390  // To the preceding FootnoteFrame
391  SwFootnoteFrame *pFootnoteFrame = FindFootnoteFrame()->GetMaster();
392  if( !pFootnoteFrame )
393  return nullptr;
394 
395  // Now the last Content
396  SwContentFrame *pCnt = pFootnoteFrame->ContainsContent();
397  if( !pCnt )
398  return nullptr;
399  SwContentFrame *pLast;
400  do
401  { pLast = pCnt;
402  pCnt = pCnt->GetNextContentFrame();
403  } while( pCnt && pFootnoteFrame->IsAnLower( pCnt ) );
404  return static_cast<SwTextFrame*>(pLast);
405 }
406 
408 {
409  if ( !IsFootnoteAllowed() )
410  return;
411 
412  bool bRollBack = nLen != TextFrameIndex(COMPLETE_STRING);
413  TextFrameIndex nEnd;
414  SwTextFrame* pSource;
415  if( bRollBack )
416  {
417  nEnd = nStart + nLen;
418  pSource = GetFollow();
419  if( !pSource )
420  return;
421  }
422  else
423  {
425  pSource = this;
426  }
427 
428  SwPageFrame* pUpdate = nullptr;
429  bool bRemove = false;
430  SwFootnoteBossFrame *pFootnoteBoss = nullptr;
431  SwFootnoteBossFrame *pEndBoss = nullptr;
432  bool bFootnoteEndDoc = FTNPOS_CHAPTER == GetDoc().GetFootnoteInfo().m_ePos;
433  SwTextNode const* pNode(nullptr);
434  sw::MergedAttrIterReverse iter(*this);
435  for (SwTextAttr const* pHt = iter.PrevAttr(&pNode); pHt; pHt = iter.PrevAttr(&pNode))
436  {
437  if (RES_TXTATR_FTN != pHt->Which())
438  continue;
439 
440  TextFrameIndex const nIdx(MapModelToView(pNode, pHt->GetStart()));
441  if (nStart > nIdx)
442  break;
443 
444  if (nEnd >= nIdx)
445  {
446  SwTextFootnote const*const pFootnote(static_cast<SwTextFootnote const*>(pHt));
447  const bool bEndn = pFootnote->GetFootnote().IsEndNote();
448 
449  if (bEndn)
450  {
451  if (!pEndBoss)
452  pEndBoss = pSource->FindFootnoteBossFrame();
453  }
454  else
455  {
456  if (!pFootnoteBoss)
457  {
458  pFootnoteBoss = pSource->FindFootnoteBossFrame( true );
459  if( pFootnoteBoss->GetUpper()->IsSctFrame() )
460  {
461  SwSectionFrame* pSect = static_cast<SwSectionFrame*>(
462  pFootnoteBoss->GetUpper());
463  if (pSect->IsFootnoteAtEnd())
464  bFootnoteEndDoc = false;
465  }
466  }
467  }
468 
469  // We don't delete, but move instead.
470  // Three cases are to be considered:
471  // 1) There's neither Follow nor PrevFollow:
472  // -> RemoveFootnote() (maybe even a OSL_ENSURE(value))
473  //
474  // 2) nStart > GetOffset, I have a Follow
475  // -> Footnote moves into Follow
476  //
477  // 3) nStart < GetOffset, I am a Follow
478  // -> Footnote moves into the PrevFollow
479  //
480  // Both need to be on one Page/in one Column
481  SwFootnoteFrame *pFootnoteFrame = SwFootnoteBossFrame::FindFootnote(pSource, pFootnote);
482 
483  if (pFootnoteFrame)
484  {
485  const bool bEndDoc = bEndn || bFootnoteEndDoc;
486  if( bRollBack )
487  {
488  while (pFootnoteFrame)
489  {
490  pFootnoteFrame->SetRef( this );
491  pFootnoteFrame = pFootnoteFrame->GetFollow();
492  SetFootnote( true );
493  }
494  }
495  else if (GetFollow())
496  {
497  SwContentFrame *pDest = GetFollow();
498  while (pDest->GetFollow() && static_cast<SwTextFrame*>(pDest->
499  GetFollow())->GetOffset() <= nIdx)
500  pDest = pDest->GetFollow();
502  pDest,pFootnote),"SwTextFrame::RemoveFootnote: footnote exists");
503 
504  // Never deregister; always move
505  if (bEndDoc ||
506  !pFootnoteFrame->FindFootnoteBossFrame()->IsBefore(pDest->FindFootnoteBossFrame(!bEndn))
507  )
508  {
509  SwPageFrame* pTmp = pFootnoteFrame->FindPageFrame();
510  if( pUpdate && pUpdate != pTmp )
511  pUpdate->UpdateFootnoteNum();
512  pUpdate = pTmp;
513  while ( pFootnoteFrame )
514  {
515  pFootnoteFrame->SetRef( pDest );
516  pFootnoteFrame = pFootnoteFrame->GetFollow();
517  }
518  }
519  else
520  {
521  pFootnoteBoss->MoveFootnotes( this, pDest, pFootnote );
522  bRemove = true;
523  }
524  static_cast<SwTextFrame*>(pDest)->SetFootnote( true );
525 
526  OSL_ENSURE( SwFootnoteBossFrame::FindFootnote( pDest,
527  pFootnote),"SwTextFrame::RemoveFootnote: footnote ChgRef failed");
528  }
529  else
530  {
531  if (!bEndDoc || ( bEndn && pEndBoss->IsInSct() &&
533  pEndBoss->FindSctFrame(), nullptr ) ))
534  {
535  if( bEndn )
536  pEndBoss->RemoveFootnote( this, pFootnote );
537  else
538  pFootnoteBoss->RemoveFootnote( this, pFootnote );
539  bRemove = bRemove || !bEndDoc;
540  OSL_ENSURE( !SwFootnoteBossFrame::FindFootnote( this, pFootnote ),
541  "SwTextFrame::RemoveFootnote: can't get off that footnote" );
542  }
543  }
544  }
545  }
546  }
547  if (pUpdate)
548  pUpdate->UpdateFootnoteNum();
549 
550  // We break the oscillation
551  if (bRemove && !bFootnoteEndDoc && HasPara())
552  {
554  ValidateFrame();
555  }
556 
557  // We call the RemoveFootnote from within the FindBreak, because the last line is
558  // to be passed to the Follow. The Offset of the Follow is, however, outdated;
559  // it'll be set soon. CalcFntFlag depends on a correctly set Follow Offset.
560  // Therefore we temporarily calculate the Follow Offset here
562  if( HasFollow() && nStart > GetOffset() )
563  {
564  nOldOfst = GetFollow()->GetOffset();
565  GetFollow()->ManipOfst(nStart + (bRollBack ? nLen : TextFrameIndex(0)));
566  }
567  pSource->CalcFootnoteFlag();
568  if (nOldOfst < TextFrameIndex(COMPLETE_STRING))
569  GetFollow()->ManipOfst( nOldOfst );
570 }
571 
572 
592 void SwTextFrame::ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDeadLine )
593 {
594  OSL_ENSURE( !IsVertical() || !IsSwapped(),
595  "SwTextFrame::ConnectFootnote with swapped frame" );
596 
597  mbFootnote = true;
598  mbInFootnoteConnect = true; // Just reset!
599  // See if pFootnote is an endnote on a separate endnote page.
601  const bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
602  const bool bEnd = pFootnote->GetFootnote().IsEndNote();
603 
604  // We want to store this value, because it is needed as a fallback
605  // in GetFootnoteLine(), if there is no paragraph information available
606  mnFootnoteLine = nDeadLine;
607 
608  // We always need a parent (Page/Column)
609  SwSectionFrame *pSect;
610  SwContentFrame *pContent = this;
611  if( bEnd && IsInSct() )
612  {
613  pSect = FindSctFrame();
614  if( pSect->IsEndnAtEnd() )
615  pContent = pSect->FindLastContent( SwFindMode::EndNote );
616  if( !pContent )
617  pContent = this;
618  }
619 
620  SwFootnoteBossFrame *pBoss = pContent->FindFootnoteBossFrame( !bEnd );
621 
622  pSect = pBoss->FindSctFrame();
623  bool bDocEnd = bEnd ? !( pSect && pSect->IsEndnAtEnd() ) :
624  ( !( pSect && pSect->IsFootnoteAtEnd() ) &&
626 
627  // Footnote can be registered with the Follow
628  SwContentFrame *pSrcFrame = FindFootnoteRef( pFootnote );
629 
630  if( bDocEnd )
631  {
632  if ((pSect || bContinuousEndnotes) && pSrcFrame)
633  {
634  SwFootnoteFrame *pFootnoteFrame = SwFootnoteBossFrame::FindFootnote( pSrcFrame, pFootnote );
635  if (pFootnoteFrame && (pFootnoteFrame->IsInSct() || bContinuousEndnotes))
636  {
637  // We either have a foot/endnote that goes to the end of the section or are in Word
638  // compatibility mode where endnotes go to the end of the document. Handle both
639  // cases by removing the footnote here, then later appending them to the correct
640  // last page of the document or section.
641  pBoss->RemoveFootnote( pSrcFrame, pFootnote );
642  pSrcFrame = nullptr;
643  }
644  }
645  }
646  else if( bEnd && pSect )
647  {
648  SwFootnoteFrame *pFootnoteFrame = pSrcFrame ? SwFootnoteBossFrame::FindFootnote( pSrcFrame, pFootnote ) : nullptr;
649  if( pFootnoteFrame && !pFootnoteFrame->GetUpper() )
650  pFootnoteFrame = nullptr;
651  SwDoc *const pDoc = &GetDoc();
652  if( SwLayouter::Collecting( pDoc, pSect, pFootnoteFrame ) )
653  {
654  if( !pSrcFrame )
655  {
656  SwFootnoteFrame *pNew = new SwFootnoteFrame(pDoc->GetDfltFrameFormat(),this,this,pFootnote);
657  SwNodeIndex aIdx( *pFootnote->GetStartNode(), 1 );
658  ::InsertCnt_( pNew, pDoc, aIdx.GetIndex() );
660  }
661  else if( pSrcFrame != this )
662  SwFootnoteBossFrame::ChangeFootnoteRef( pSrcFrame, pFootnote, this );
663  mbInFootnoteConnect = false;
664  return;
665  }
666  else if( pSrcFrame )
667  {
668  SwFootnoteBossFrame *pFootnoteBoss = pFootnoteFrame->FindFootnoteBossFrame();
669  if( !pFootnoteBoss->IsInSct() ||
670  pFootnoteBoss->ImplFindSctFrame()->GetSection()!=pSect->GetSection() )
671  {
672  pBoss->RemoveFootnote( pSrcFrame, pFootnote );
673  pSrcFrame = nullptr;
674  }
675  }
676  }
677 
678  if( bDocEnd || bEnd )
679  {
680  if( !pSrcFrame )
681  pBoss->AppendFootnote( this, pFootnote );
682  else if( pSrcFrame != this )
683  SwFootnoteBossFrame::ChangeFootnoteRef( pSrcFrame, pFootnote, this );
684  mbInFootnoteConnect = false;
685  return;
686  }
687 
688  SwSaveFootnoteHeight aHeight( pBoss, nDeadLine );
689 
690  if( !pSrcFrame ) // No Footnote was found at all
691  pBoss->AppendFootnote( this, pFootnote );
692  else
693  {
694  SwFootnoteFrame *pFootnoteFrame = SwFootnoteBossFrame::FindFootnote( pSrcFrame, pFootnote );
695  SwFootnoteBossFrame *pFootnoteBoss = pFootnoteFrame->FindFootnoteBossFrame();
696 
697  bool bBrutal = false;
698 
699  if( pFootnoteBoss == pBoss ) // Ref and Footnote are on the same Page/Column
700  {
701  SwFrame *pCont = pFootnoteFrame->GetUpper();
702 
703  SwRectFnSet aRectFnSet(pCont);
704  tools::Long nDiff = aRectFnSet.YDiff( aRectFnSet.GetTop(pCont->getFrameArea()),
705  nDeadLine );
706 
707  if( nDiff >= 0 )
708  {
709  // If the Footnote has been registered to a Follow, we need to
710  // rewire it now too
711  if ( pSrcFrame != this )
712  SwFootnoteBossFrame::ChangeFootnoteRef( pSrcFrame, pFootnote, this );
713 
714  // We have some room left, so the Footnote can grow
715  if ( pFootnoteFrame->GetFollow() && nDiff > 0 )
716  {
717  SwFrameDeleteGuard aDeleteGuard(pCont);
718  SwTwips nHeight = aRectFnSet.GetHeight(pCont->getFrameArea());
719  pBoss->RearrangeFootnotes( nDeadLine, false, pFootnote );
721  ValidateFrame();
723  if ( pSh && nHeight == aRectFnSet.GetHeight(pCont->getFrameArea()) )
724  // So that we don't miss anything
725  pSh->InvalidateWindows( pCont->getFrameArea() );
726  }
727  mbInFootnoteConnect = false;
728  return;
729  }
730  else
731  bBrutal = true;
732  }
733  else
734  {
735  // Ref and Footnote are not on one Page; attempt to move is necessary
736  SwFrame* pTmp = this;
737  while( pTmp->GetNext() && pSrcFrame != pTmp )
738  pTmp = pTmp->GetNext();
739  if( pSrcFrame == pTmp )
740  bBrutal = true;
741  else
742  { // If our Parent is in a column Area, but the Page already has a
743  // FootnoteContainer, we can only brute force it
744  if( pSect && pSect->FindFootnoteBossFrame( !bEnd )->FindFootnoteCont() )
745  bBrutal = true;
746 
747  else if ( !pFootnoteFrame->GetPrev() ||
748  pFootnoteBoss->IsBefore( pBoss )
749  )
750  {
751  SwFootnoteBossFrame *pSrcBoss = pSrcFrame->FindFootnoteBossFrame( !bEnd );
752  pSrcBoss->MoveFootnotes( pSrcFrame, this, pFootnote );
753  }
754  else
755  SwFootnoteBossFrame::ChangeFootnoteRef( pSrcFrame, pFootnote, this );
756  }
757  }
758 
759  // The brute force method: Remove Footnote and append.
760  // We need to call SetFootnoteDeadLine(), as we can more easily adapt the
761  // nMaxFootnoteHeight after RemoveFootnote
762  if( bBrutal )
763  {
764  pBoss->RemoveFootnote( pSrcFrame, pFootnote, false );
765  std::unique_ptr<SwSaveFootnoteHeight> pHeight(bEnd ? nullptr : new SwSaveFootnoteHeight( pBoss, nDeadLine ));
766  pBoss->AppendFootnote( this, pFootnote );
767  }
768  }
769 
770  // In column Areas, that not yet reach the Page's border a RearrangeFootnotes is not
771  // useful yet, as the Footnote container has not yet been calculated
772  if( !pSect || !pSect->Growable() )
773  {
774  // Validate environment, to avoid oscillation
775  SwSaveFootnoteHeight aNochmal( pBoss, nDeadLine );
777  pBoss->RearrangeFootnotes( nDeadLine, true );
778  ValidateFrame();
779  }
780  else if( pSect->IsFootnoteAtEnd() )
781  {
783  ValidateFrame();
784  }
785 
786  mbInFootnoteConnect = false;
787 }
788 
793  SwTextAttr *pHint )
794 {
795  OSL_ENSURE( ! m_pFrame->IsVertical() || m_pFrame->IsSwapped(),
796  "NewFootnotePortion with unswapped frame" );
797 
798  SwTextFootnote *pFootnote = static_cast<SwTextFootnote*>(pHint);
799 
800  if( !m_pFrame->IsFootnoteAllowed() )
801  return new SwFootnotePortion("", pFootnote);
802 
803  const SwFormatFootnote& rFootnote = pFootnote->GetFootnote();
804  SwDoc *const pDoc = &m_pFrame->GetDoc();
805 
806  if( rInf.IsTest() )
807  return new SwFootnotePortion(rFootnote.GetViewNumStr(*pDoc, m_pFrame->getRootFrame()), pFootnote);
808 
810 
811  sal_uInt16 nReal;
812  {
813  sal_uInt16 nOldReal = m_pCurr->GetRealHeight();
814  sal_uInt16 nOldAscent = m_pCurr->GetAscent();
815  sal_uInt16 nOldHeight = m_pCurr->Height();
816  CalcRealHeight();
817  nReal = m_pCurr->GetRealHeight();
818  if( nReal < nOldReal )
819  nReal = nOldReal;
820  m_pCurr->SetRealHeight( nOldReal );
821  m_pCurr->Height( nOldHeight );
822  m_pCurr->SetAscent( nOldAscent );
823  }
824 
825  SwTwips nLower = Y() + nReal;
826 
827  const bool bVertical = m_pFrame->IsVertical();
828  if( bVertical )
829  nLower = m_pFrame->SwitchHorizontalToVertical( nLower );
830 
831  nLower = lcl_GetFootnoteLower( m_pFrame, nLower );
832 
833  // We just refresh.
834  // The Connect does not do anything useful in this case, but will
835  // mostly throw away the Footnote and create it anew.
836  if( !rInf.IsQuick() )
837  m_pFrame->ConnectFootnote( pFootnote, nLower );
838 
839  SwTextFrame *pScrFrame = m_pFrame->FindFootnoteRef( pFootnote );
841  SwFootnoteFrame *pFootnoteFrame = nullptr;
842  if( pScrFrame )
843  pFootnoteFrame = SwFootnoteBossFrame::FindFootnote( pScrFrame, pFootnote );
844 
845  // We see whether our Append has caused some Footnote to
846  // still be on the Page/Column. If not, our line disappears too,
847  // which will lead to the following undesired behaviour:
848  // Footnote1 still fits onto the Page/Column, but Footnote2 doesn't.
849  // The Footnote2 Reference remains on the Page/Column. The Footnote itself
850  // is on the next Page/Column.
851  //
852  // Exception: If the Page/Column cannot accommodate another line,
853  // the Footnote Reference should be moved to the next one.
854  if( !rFootnote.IsEndNote() )
855  {
856  SwSectionFrame *pSct = pBoss->FindSctFrame();
857  bool bAtSctEnd = pSct && pSct->IsFootnoteAtEnd();
858  if( FTNPOS_CHAPTER != pDoc->GetFootnoteInfo().m_ePos || bAtSctEnd )
859  {
860  SwFrame* pFootnoteCont = pBoss->FindFootnoteCont();
861  // If the Parent is within an Area, it can only be a Column of this
862  // Area. If this one is not the first Column, we can avoid it.
863  if( !m_pFrame->IsInTab() && ( GetLineNr() > 1 || m_pFrame->GetPrev() ||
864  ( !bAtSctEnd && m_pFrame->GetIndPrev() ) ||
865  ( pSct && pBoss->GetPrev() ) ) )
866  {
867  if( !pFootnoteCont )
868  {
869  rInf.SetStop( true );
870  return nullptr;
871  }
872  else
873  {
874  // There must not be any Footnote Containers in column Areas and at the same time on the
875  // Page/Page column
876  if( pSct && !bAtSctEnd ) // Is the Container in a (column) Area?
877  {
878  SwFootnoteBossFrame* pTmp = pBoss->FindSctFrame()->FindFootnoteBossFrame( true );
879  SwFootnoteContFrame* pFootnoteC = pTmp->FindFootnoteCont();
880  if( pFootnoteC )
881  {
882  SwFootnoteFrame* pTmpFrame = static_cast<SwFootnoteFrame*>(pFootnoteC->Lower());
883  if( pTmpFrame && *pTmpFrame < pFootnote )
884  {
885  rInf.SetStop( true );
886  return nullptr;
887  }
888  }
889  }
890  // Is this the last Line that fits?
891  SwTwips nTmpBot = Y() + nReal * 2;
892 
893  if( bVertical )
894  nTmpBot = m_pFrame->SwitchHorizontalToVertical( nTmpBot );
895 
896  SwRectFnSet aRectFnSet(pFootnoteCont);
897 
898  const tools::Long nDiff = aRectFnSet.YDiff(
899  aRectFnSet.GetTop(pFootnoteCont->getFrameArea()),
900  nTmpBot );
901 
902  if( pScrFrame && nDiff < 0 )
903  {
904  if( pFootnoteFrame )
905  {
906  SwFootnoteBossFrame *pFootnoteBoss = pFootnoteFrame->FindFootnoteBossFrame();
907  if( pFootnoteBoss != pBoss )
908  {
909  // We're in the last Line and the Footnote has moved
910  // to another Page. We also want to be on that Page!
911  rInf.SetStop( true );
912  return nullptr;
913  }
914  }
915  }
916  }
917  }
918  }
919  }
920  // Finally: Create FootnotePortion and exit ...
922  rFootnote.GetViewNumStr(*pDoc, m_pFrame->getRootFrame()),
923  pFootnote, nReal );
924  rInf.SetFootnoteInside( true );
925 
926  return pRet;
927 }
928 
933 {
934  OSL_ENSURE( m_pFrame->IsInFootnote() && !m_pFrame->GetIndPrev() && !rInf.IsFootnoteDone(),
935  "This is the wrong place for a ftnnumber" );
936  if( rInf.GetTextStart() != m_nStart ||
937  rInf.GetTextStart() != rInf.GetIdx() )
938  return nullptr;
939 
940  const SwFootnoteFrame* pFootnoteFrame = m_pFrame->FindFootnoteFrame();
941  const SwTextFootnote* pFootnote = pFootnoteFrame->GetAttr();
942 
943  // Aha! So we're in the Footnote Area!
944  SwFormatFootnote& rFootnote = const_cast<SwFormatFootnote&>(pFootnote->GetFootnote());
945 
946  SwDoc *const pDoc = &m_pFrame->GetDoc();
947  OUString aFootnoteText(rFootnote.GetViewNumStr(*pDoc, m_pFrame->getRootFrame(), true));
948 
949  const SwEndNoteInfo* pInfo;
950  if( rFootnote.IsEndNote() )
951  pInfo = &pDoc->GetEndNoteInfo();
952  else
953  pInfo = &pDoc->GetFootnoteInfo();
954 
955  const SwAttrSet* pParSet = &rInf.GetCharAttr();
956  const IDocumentSettingAccess* pIDSA = &pDoc->getIDocumentSettingAccess();
957  std::unique_ptr<SwFont> pNumFnt(new SwFont( pParSet, pIDSA ));
958 
959  // #i37142#
960  // Underline style of paragraph font should not be considered
961  // Overline style of paragraph font should not be considered
962  // Weight style of paragraph font should not be considered
963  // Posture style of paragraph font should not be considered
964  // See also #i18463# and SwTextFormatter::NewNumberPortion()
965  pNumFnt->SetUnderline( LINESTYLE_NONE );
966  pNumFnt->SetOverline( LINESTYLE_NONE );
967  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::Latin );
968  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CJK );
969  pNumFnt->SetItalic( ITALIC_NONE, SwFontScript::CTL );
970  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::Latin );
971  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CJK );
972  pNumFnt->SetWeight( WEIGHT_NORMAL, SwFontScript::CTL );
973 
974  const auto xAnchor = rFootnote.getAnchor(*pDoc);
975  uno::Reference<beans::XPropertySet> xAnchorProps(xAnchor, uno::UNO_QUERY);
976  if (xAnchorProps.is())
977  {
978  auto aAny = xAnchorProps->getPropertyValue("CharFontCharSet");
979  sal_Int16 eCharSet;
980  if ((aAny >>= eCharSet) && eCharSet == awt::CharSet::SYMBOL)
981  {
982  OUString aFontName;
983  aAny = xAnchorProps->getPropertyValue("CharFontName");
984  if (aAny >>= aFontName)
985  {
986  pNumFnt->SetName(aFontName, SwFontScript::Latin);
987  pNumFnt->SetName(aFontName, SwFontScript::CJK);
988  pNumFnt->SetName(aFontName, SwFontScript::CTL);
989  pNumFnt->SetCharSet(RTL_TEXTENCODING_SYMBOL, SwFontScript::Latin);
990  pNumFnt->SetCharSet(RTL_TEXTENCODING_SYMBOL, SwFontScript::CJK);
991  pNumFnt->SetCharSet(RTL_TEXTENCODING_SYMBOL, SwFontScript::CTL);
992  }
993  }
994  }
995 
996  const SwAttrSet& rSet = pInfo->GetCharFormat(*pDoc)->GetAttrSet();
997  pNumFnt->SetDiffFnt(&rSet, pIDSA );
998  pNumFnt->SetVertical( pNumFnt->GetOrientation(), m_pFrame->IsVertical() );
999 
1000  // tdf#85610 apply redline coloring to the footnote numbering in the footnote area
1001  SwUnoInternalPaM aPam(*pDoc);
1002  if ( ::sw::XTextRangeToSwPaM(aPam, xAnchor) )
1003  {
1004  SwRedlineTable::size_type nRedlinePos = 0;
1005  const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
1006  const SwRangeRedline* pRedline = rTable.FindAtPosition( *aPam.Start(), nRedlinePos );
1007  if (pRedline)
1008  {
1009  SwAttrPool& rPool = pDoc->GetAttrPool();
1011 
1012  std::size_t aAuthor = (1 < pRedline->GetStackCount())
1013  ? pRedline->GetAuthor( 1 )
1014  : pRedline->GetAuthor();
1015 
1016  if ( RedlineType::Delete == pRedline->GetType() )
1017  SW_MOD()->GetDeletedAuthorAttr(aAuthor, aSet);
1018  else
1019  SW_MOD()->GetInsertAuthorAttr(aAuthor, aSet);
1020 
1021  if (const SvxColorItem* pItem = aSet.GetItemIfSet(RES_CHRATR_COLOR))
1022  pNumFnt->SetColor(pItem->GetValue());
1023  if (const SvxUnderlineItem* pItem = aSet.GetItemIfSet(RES_CHRATR_UNDERLINE))
1024  pNumFnt->SetUnderline(pItem->GetLineStyle());
1025  if (const SvxCrossedOutItem* pItem = aSet.GetItemIfSet(RES_CHRATR_CROSSEDOUT))
1026  pNumFnt->SetStrikeout( pItem->GetStrikeout() );
1027  }
1028  }
1029 
1030  SwFootnoteNumPortion* pNewPor = new SwFootnoteNumPortion( aFootnoteText, std::move(pNumFnt) );
1031  pNewPor->SetLeft( !m_pFrame->IsRightToLeft() );
1032  return pNewPor;
1033 }
1034 
1035 static OUString lcl_GetPageNumber( const SwPageFrame* pPage )
1036 {
1037  OSL_ENSURE( pPage, "GetPageNumber: Homeless TextFrame" );
1038  const sal_uInt16 nVirtNum = pPage->GetVirtPageNum();
1039  const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType();
1040  return rNum.GetNumStr( nVirtNum );
1041 }
1042 
1044 {
1045  // We cannot assume we're a Follow
1046  if( !m_pFrame->IsInFootnote() || m_pFrame->GetPrev() ||
1047  rInf.IsErgoDone() || rInf.GetIdx() != m_pFrame->GetOffset() ||
1049  return nullptr;
1050 
1051  // we are in the footnote container
1052  const SwFootnoteInfo &rFootnoteInfo = m_pFrame->GetDoc().GetFootnoteInfo();
1053  SwTextFrame *pQuoFrame = m_pFrame->FindQuoVadisFrame();
1054  if( !pQuoFrame )
1055  return nullptr;
1056  const SwPageFrame* pPage = m_pFrame->FindPageFrame();
1057  const SwPageFrame* pQuoPage = pQuoFrame->FindPageFrame();
1058  if( pPage == pQuoFrame->FindPageFrame() )
1059  return nullptr; // If the QuoVadis is on the same Column/Page
1060  const OUString aPage = lcl_GetPageNumber( pPage );
1061  SwParaPortion *pPara = pQuoFrame->GetPara();
1062  if( pPara )
1063  pPara->SetErgoSumNum( aPage );
1064  if( rFootnoteInfo.m_aErgoSum.isEmpty() )
1065  return nullptr;
1066  SwErgoSumPortion *pErgo = new SwErgoSumPortion( rFootnoteInfo.m_aErgoSum,
1067  lcl_GetPageNumber( pQuoPage ) );
1068  return pErgo;
1069 }
1070 
1072 {
1073  OSL_ENSURE( ! m_pFrame->IsVertical() || ! m_pFrame->IsSwapped(),
1074  "SwTextFormatter::FormatQuoVadis with swapped frame" );
1075 
1077  return nOffset;
1078 
1079  const SwFrame* pErgoFrame = m_pFrame->FindFootnoteFrame()->GetFollow();
1080  if( !pErgoFrame && m_pFrame->HasFollow() )
1081  pErgoFrame = m_pFrame->GetFollow();
1082  if( !pErgoFrame )
1083  return nOffset;
1084 
1085  if( pErgoFrame == m_pFrame->GetNext() )
1086  {
1087  SwFrame *pCol = m_pFrame->FindColFrame();
1088  while( pCol && !pCol->GetNext() )
1089  pCol = pCol->GetUpper()->FindColFrame();
1090  if( pCol )
1091  return nOffset;
1092  }
1093  else
1094  {
1095  const SwPageFrame* pPage = m_pFrame->FindPageFrame();
1096  const SwPageFrame* pErgoPage = pErgoFrame->FindPageFrame();
1097  if( pPage == pErgoPage )
1098  return nOffset; // If the ErgoSum is on the same Page
1099  }
1100 
1101  SwTextFormatInfo &rInf = GetInfo();
1102  const SwFootnoteInfo &rFootnoteInfo = m_pFrame->GetDoc().GetFootnoteInfo();
1103  if( rFootnoteInfo.m_aQuoVadis.isEmpty() )
1104  return nOffset;
1105 
1106  // A remark on QuoVadis/ErgoSum:
1107  // We use the Font set for the Paragraph for these texts.
1108  // Thus, we initialize:
1109  // TODO: ResetFont();
1110  FeedInf( rInf );
1111  SeekStartAndChg( rInf, true );
1112  if( GetRedln() && m_pCurr->HasRedline() )
1113  {
1114  std::pair<SwTextNode const*, sal_Int32> const pos(
1115  GetTextFrame()->MapViewToModel(nOffset));
1116  GetRedln()->Seek(*m_pFont, pos.first->GetIndex(), pos.second, 0);
1117  }
1118 
1119  // A tricky special case: Flyfrms extend into the Line and are at the
1120  // position we want to insert the Quovadis text
1121  // Let's see if it is that bad indeed:
1123  sal_uInt16 nLastLeft = 0;
1124  while( pPor )
1125  {
1126  if ( pPor->IsFlyPortion() )
1127  nLastLeft = static_cast<SwFlyPortion*>(pPor)->GetFix() +
1128  static_cast<SwFlyPortion*>(pPor)->Width();
1129  pPor = pPor->GetNextPortion();
1130  }
1131 
1132  // The old game all over again: we want the Line to wrap around
1133  // at a certain point, so we adjust the width.
1134  // nLastLeft is now basically the right margin
1135  const sal_uInt16 nOldRealWidth = rInf.RealWidth();
1136  rInf.RealWidth( nOldRealWidth - nLastLeft );
1137 
1138  OUString aErgo = lcl_GetPageNumber( pErgoFrame->FindPageFrame() );
1139  SwQuoVadisPortion *pQuo = new SwQuoVadisPortion(rFootnoteInfo.m_aQuoVadis, aErgo );
1140  pQuo->SetAscent( rInf.GetAscent() );
1141  pQuo->Height( rInf.GetTextHeight() );
1142  pQuo->Format( rInf );
1143  sal_uInt16 nQuoWidth = pQuo->Width();
1144  SwLinePortion* pCurrPor = pQuo;
1145 
1146  while ( rInf.GetRest() )
1147  {
1148  SwLinePortion* pFollow = rInf.GetRest();
1149  rInf.SetRest( nullptr );
1150  pCurrPor->Move( rInf );
1151 
1152  OSL_ENSURE( pFollow->IsQuoVadisPortion(),
1153  "Quo Vadis, rest of QuoVadisPortion" );
1154 
1155  // format the rest and append it to the other QuoVadis parts
1156  pFollow->Format( rInf );
1157  nQuoWidth = nQuoWidth + pFollow->Width();
1158 
1159  pCurrPor->Append( pFollow );
1160  pCurrPor = pFollow;
1161  }
1162 
1163  Right( Right() - nQuoWidth );
1164 
1165  TextFrameIndex nRet;
1166  {
1168 
1169  nRet = FormatLine( m_nStart );
1170  }
1171 
1172  Right( rInf.Left() + nOldRealWidth - 1 );
1173 
1174  nLastLeft = nOldRealWidth - m_pCurr->Width();
1175  FeedInf( rInf );
1176 
1177  // It's possible that there's a Margin Portion at the end, which would
1178  // just cause a lot of trouble, when respanning
1179  pPor = m_pCurr->FindLastPortion();
1180  SwGluePortion *pGlue = pPor->IsMarginPortion() ? static_cast<SwMarginPortion*>(pPor) : nullptr;
1181  if( pGlue )
1182  {
1183  pGlue->Height( 0 );
1184  pGlue->Width( 0 );
1185  pGlue->SetLen(TextFrameIndex(0));
1186  pGlue->SetAscent( 0 );
1187  pGlue->SetNextPortion( nullptr );
1188  pGlue->SetFixWidth(0);
1189  }
1190 
1191  // Luxury: We make sure the QuoVadis text appears on the right, by
1192  // using Glues.
1193  nLastLeft = nLastLeft - nQuoWidth;
1194  if( nLastLeft )
1195  {
1196  if( nLastLeft > pQuo->GetAscent() ) // Minimum distance
1197  {
1198  switch( GetAdjust() )
1199  {
1200  case SvxAdjust::Block:
1201  {
1202  if( !m_pCurr->GetLen() ||
1204  nLastLeft = pQuo->GetAscent();
1205  nQuoWidth = nQuoWidth + nLastLeft;
1206  break;
1207  }
1208  case SvxAdjust::Right:
1209  {
1210  nLastLeft = pQuo->GetAscent();
1211  nQuoWidth = nQuoWidth + nLastLeft;
1212  break;
1213  }
1214  case SvxAdjust::Center:
1215  {
1216  nQuoWidth = nQuoWidth + pQuo->GetAscent();
1217  tools::Long nDiff = nLastLeft - nQuoWidth;
1218  if( nDiff < 0 )
1219  {
1220  nLastLeft = pQuo->GetAscent();
1221  nQuoWidth = o3tl::narrowing<sal_uInt16>(-nDiff + nLastLeft);
1222  }
1223  else
1224  {
1225  nQuoWidth = 0;
1226  nLastLeft = sal_uInt16(( pQuo->GetAscent() + nDiff ) / 2);
1227  }
1228  break;
1229  }
1230  default:
1231  nQuoWidth = nQuoWidth + nLastLeft;
1232  }
1233  }
1234  else
1235  nQuoWidth = nQuoWidth + nLastLeft;
1236  if( nLastLeft )
1237  {
1238  pGlue = new SwGluePortion(0);
1239  pGlue->Width( nLastLeft );
1240  pPor->Append( pGlue );
1241  pPor = pPor->GetNextPortion();
1242  }
1243  }
1244 
1245  // Finally: we insert the QuoVadis Portion
1246  pCurrPor = pQuo;
1247  while ( pCurrPor )
1248  {
1249  // pPor->Append deletes the pPortion pointer of pPor.
1250  // Therefore we have to keep a pointer to the next portion
1251  pQuo = static_cast<SwQuoVadisPortion*>(pCurrPor->GetNextPortion());
1252  pPor->Append( pCurrPor );
1253  pPor = pPor->GetNextPortion();
1254  pCurrPor = pQuo;
1255  }
1256 
1257  m_pCurr->Width( m_pCurr->Width() + nQuoWidth );
1258 
1259  // And adjust again, due to the adjustment and due to the following special
1260  // case:
1261  // The DummyUser has set a smaller Font in the Line than the one used
1262  // by the QuoVadis text ...
1264 
1265  return nRet;
1266 }
1267 
1276 {
1277  sal_uInt16 nRstHeight = GetFrameRstHeight();
1278  if( m_pCurr && nRstHeight > m_pCurr->Height() )
1279  {
1280  SwLineLayout *pLay = new SwLineLayout;
1281  nRstHeight = nRstHeight - m_pCurr->Height();
1282  pLay->Height( nRstHeight );
1283  pLay->SetAscent( nRstHeight );
1284  Insert( pLay );
1285  Next();
1286  }
1287 }
1288 
1289 namespace {
1290 
1291 class SwFootnoteSave
1292 {
1293  SwTextSizeInfo* m_pInf;
1294  SwFont* m_pFnt;
1295  std::unique_ptr<SwFont> m_pOld;
1296 
1297  SwFootnoteSave(const SwFootnoteSave&) = delete;
1298  SwFootnoteSave& operator=(const SwFootnoteSave&) = delete;
1299 
1300 public:
1301  SwFootnoteSave( const SwTextSizeInfo &rInf,
1302  const SwTextFootnote *pTextFootnote,
1303  const bool bApplyGivenScriptType,
1304  const SwFontScript nGivenScriptType );
1305  ~SwFootnoteSave() COVERITY_NOEXCEPT_FALSE;
1306 };
1307 
1308 }
1309 
1310 SwFootnoteSave::SwFootnoteSave(const SwTextSizeInfo& rInf, const SwTextFootnote* pTextFootnote,
1311  const bool bApplyGivenScriptType,
1312  const SwFontScript nGivenScriptType)
1313  : m_pInf(&const_cast<SwTextSizeInfo&>(rInf))
1314  , m_pFnt(nullptr)
1315 {
1316  if( pTextFootnote && rInf.GetTextFrame() )
1317  {
1318  m_pFnt = const_cast<SwTextSizeInfo&>(rInf).GetFont();
1319  m_pOld.reset(new SwFont(*m_pFnt));
1320  m_pOld->GetTox() = m_pFnt->GetTox();
1321  m_pFnt->GetTox() = 0;
1322  SwFormatFootnote& rFootnote = const_cast<SwFormatFootnote&>(pTextFootnote->GetFootnote());
1323  const SwDoc *const pDoc = &rInf.GetTextFrame()->GetDoc();
1324 
1325  // #i98418#
1326  if ( bApplyGivenScriptType )
1327  {
1328  m_pFnt->SetActual(nGivenScriptType);
1329  }
1330  else
1331  {
1332  // examine text and set script
1333  OUString aTmpStr(rFootnote.GetViewNumStr(*pDoc, rInf.GetTextFrame()->getRootFrame()));
1334  m_pFnt->SetActual(SwScriptInfo::WhichFont(0, aTmpStr));
1335  }
1336 
1337  const SwEndNoteInfo* pInfo;
1338  if( rFootnote.IsEndNote() )
1339  pInfo = &pDoc->GetEndNoteInfo();
1340  else
1341  pInfo = &pDoc->GetFootnoteInfo();
1342  const SwAttrSet& rSet = pInfo->GetAnchorCharFormat(const_cast<SwDoc&>(*pDoc))->GetAttrSet();
1343  m_pFnt->SetDiffFnt(&rSet, &pDoc->getIDocumentSettingAccess());
1344 
1345  // we reduce footnote size, if we are inside a double line portion
1346  if (!m_pOld->GetEscapement() && 50 == m_pOld->GetPropr())
1347  {
1348  Size aSize = m_pFnt->GetSize(m_pFnt->GetActual());
1349  m_pFnt->SetSize(Size(aSize.Width() / 2, aSize.Height() / 2), m_pFnt->GetActual());
1350  }
1351 
1352  // set the correct rotation at the footnote font
1353  if( const SvxCharRotateItem* pItem = rSet.GetItemIfSet( RES_CHRATR_ROTATE ) )
1354  m_pFnt->SetVertical(pItem->GetValue(),
1355  rInf.GetTextFrame()->IsVertical());
1356 
1357  m_pFnt->ChgPhysFnt(m_pInf->GetVsh(), *m_pInf->GetOut());
1358 
1359  if( const SvxBrushItem* pItem = rSet.GetItemIfSet( RES_CHRATR_BACKGROUND ) )
1360  m_pFnt->SetBackColor(pItem->GetColor());
1361  }
1362  else
1363  m_pFnt = nullptr;
1364 }
1365 
1366 SwFootnoteSave::~SwFootnoteSave() COVERITY_NOEXCEPT_FALSE
1367 {
1368  if (m_pFnt)
1369  {
1370  // Put back SwFont
1371  *m_pFnt = *m_pOld;
1372  m_pFnt->GetTox() = m_pOld->GetTox();
1373  m_pFnt->ChgPhysFnt(m_pInf->GetVsh(), *m_pInf->GetOut());
1374  m_pOld.reset();
1375  }
1376 }
1377 
1378 SwFootnotePortion::SwFootnotePortion( const OUString &rExpand,
1379  SwTextFootnote *pFootn, sal_uInt16 nReal )
1380  : SwFieldPortion( rExpand, nullptr )
1381  , m_pFootnote(pFootn)
1382  , m_nOrigHeight( nReal )
1383  // #i98418#
1384  , mbPreferredScriptTypeSet( false )
1385  , mnPreferredScriptType( SwFontScript::Latin )
1386 {
1387  SetLen(TextFrameIndex(1));
1389 }
1390 
1391 bool SwFootnotePortion::GetExpText( const SwTextSizeInfo &, OUString &rText ) const
1392 {
1393  rText = m_aExpand;
1394  return true;
1395 }
1396 
1398 {
1399  // #i98418#
1400 // SwFootnoteSave aFootnoteSave( rInf, pFootnote );
1401  SwFootnoteSave aFootnoteSave( rInf, m_pFootnote, mbPreferredScriptTypeSet, mnPreferredScriptType );
1402  // the idx is manipulated in SwExpandPortion::Format
1403  // this flag indicates, that a footnote is allowed to trigger
1404  // an underflow during SwTextGuess::Guess
1405  rInf.SetFakeLineStart( rInf.GetIdx() > rInf.GetLineStart() );
1406  const bool bFull = SwFieldPortion::Format( rInf );
1407  rInf.SetFakeLineStart( false );
1408  SetAscent( rInf.GetAscent() );
1409  Height( rInf.GetTextHeight() );
1410  rInf.SetFootnoteDone( !bFull );
1411  if( !bFull )
1412  rInf.SetParaFootnote();
1413  return bFull;
1414 }
1415 
1417 {
1418  // #i98418#
1419 // SwFootnoteSave aFootnoteSave( rInf, pFootnote );
1420  SwFootnoteSave aFootnoteSave( rInf, m_pFootnote, mbPreferredScriptTypeSet, mnPreferredScriptType );
1421  rInf.DrawViewOpt( *this, PortionType::Footnote );
1422  SwExpandPortion::Paint( rInf );
1423 }
1424 
1426 {
1427  // #i98418#
1428 // SwFootnoteSave aFootnoteSave( rInfo, pFootnote );
1429  SwFootnoteSave aFootnoteSave( rInfo, m_pFootnote, mbPreferredScriptTypeSet, mnPreferredScriptType );
1430  return SwExpandPortion::GetTextSize( rInfo );
1431 }
1432 
1433 // #i98418#
1435 {
1436  mbPreferredScriptTypeSet = true;
1437  mnPreferredScriptType = nPreferredScriptType;
1438 }
1439 
1440 SwFieldPortion *SwQuoVadisPortion::Clone( const OUString &rExpand ) const
1441 {
1442  return new SwQuoVadisPortion( rExpand, m_aErgo );
1443 }
1444 
1445 SwQuoVadisPortion::SwQuoVadisPortion( const OUString &rExp, const OUString& rStr )
1446  : SwFieldPortion( rExp ), m_aErgo(rStr)
1447 {
1448  SetLen(TextFrameIndex(0));
1450 }
1451 
1453 {
1454  // First try; maybe the Text fits
1455  CheckScript( rInf );
1456  bool bFull = SwFieldPortion::Format( rInf );
1457  SetLen(TextFrameIndex(0));
1458 
1459  if( bFull )
1460  {
1461  // Second try; we make the String shorter
1462  m_aExpand = "...";
1463  bFull = SwFieldPortion::Format( rInf );
1464  SetLen(TextFrameIndex(0));
1465  if( bFull )
1466  // Third try; we're done: we crush
1467  Width( sal_uInt16(rInf.Width() - rInf.X()) );
1468 
1469  // No multiline Fields for QuoVadis and ErgoSum
1470  if( rInf.GetRest() )
1471  {
1472  delete rInf.GetRest();
1473  rInf.SetRest( nullptr );
1474  }
1475  }
1476  return bFull;
1477 }
1478 
1479 bool SwQuoVadisPortion::GetExpText( const SwTextSizeInfo &, OUString &rText ) const
1480 {
1481  rText = m_aExpand;
1482  // if this QuoVadisPortion has a follow, the follow is responsible for
1483  // the ergo text.
1484  if ( ! HasFollow() )
1485  rText += m_aErgo;
1486  return true;
1487 }
1488 
1490 {
1491  rPH.Special( GetLen(), m_aExpand + m_aErgo, GetWhichPor() );
1492 }
1493 
1495 {
1496  // We _always_ want to output per DrawStretchText, because nErgo
1497  // can quickly switch
1498  if( PrtWidth() )
1499  {
1500  rInf.DrawViewOpt( *this, PortionType::QuoVadis );
1501  SwTextSlot aDiffText( &rInf, this, true, false );
1502  SwFontSave aSave( rInf, m_pFont.get() );
1503  rInf.DrawText( *this, rInf.GetLen(), true );
1504  }
1505 }
1506 
1507 SwFieldPortion *SwErgoSumPortion::Clone( const OUString &rExpand ) const
1508 {
1509  return new SwErgoSumPortion( rExpand, std::u16string_view() );
1510 }
1511 
1512 SwErgoSumPortion::SwErgoSumPortion(const OUString &rExp, std::u16string_view rStr)
1513  : SwFieldPortion( rExp )
1514 {
1515  SetLen(TextFrameIndex(0));
1516  m_aExpand += rStr;
1517 
1518  // One blank distance to the text
1519  m_aExpand += " ";
1521 }
1522 
1524 {
1525  return TextFrameIndex(0);
1526 }
1527 
1529 {
1530  const bool bFull = SwFieldPortion::Format( rInf );
1531  SetLen(TextFrameIndex(0));
1532  rInf.SetErgoDone( true );
1533 
1534  // No multiline Fields for QuoVadis and ErgoSum
1535  if( bFull && rInf.GetRest() )
1536  {
1537  delete rInf.GetRest();
1538  rInf.SetRest( nullptr );
1539  }
1540 
1541  // We return false in order to get some text into the current line,
1542  // even if it's full (better than looping)
1543  return false;
1544 }
1545 
1546 void SwParaPortion::SetErgoSumNum( const OUString& rErgo )
1547 {
1548  SwLineLayout *pLay = this;
1549  while( pLay->GetNext() )
1550  {
1551  pLay = pLay->GetNext();
1552  }
1553  SwLinePortion *pPor = pLay;
1554  SwQuoVadisPortion *pQuo = nullptr;
1555  while( pPor && !pQuo )
1556  {
1557  if ( pPor->IsQuoVadisPortion() )
1558  pQuo = static_cast<SwQuoVadisPortion*>(pPor);
1559  pPor = pPor->GetNextPortion();
1560  }
1561  if( pQuo )
1562  pQuo->SetNumber( rErgo );
1563 }
1564 
1568 bool SwParaPortion::UpdateQuoVadis( std::u16string_view rQuo )
1569 {
1570  SwLineLayout *pLay = this;
1571  while( pLay->GetNext() )
1572  {
1573  pLay = pLay->GetNext();
1574  }
1575  SwLinePortion *pPor = pLay;
1576  SwQuoVadisPortion *pQuo = nullptr;
1577  while( pPor && !pQuo )
1578  {
1579  if ( pPor->IsQuoVadisPortion() )
1580  pQuo = static_cast<SwQuoVadisPortion*>(pPor);
1581  pPor = pPor->GetNextPortion();
1582  }
1583 
1584  if( !pQuo )
1585  return false;
1586 
1587  return pQuo->GetQuoText() == rQuo;
1588 }
1589 
1590 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:231
void SetHasRotatedPortions(bool bHasRotatedPortions)
Definition: txtftn.cxx:97
OUString GetNumStr(sal_Int32 nNo) const
virtual bool Format(SwTextFormatInfo &rInf)
Definition: porlin.cxx:238
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
SwTwips PrtWidth() const
Definition: porlin.hxx:83
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:225
Base class of the Writer layout elements.
Definition: frame.hxx:314
void Move(SwTextPaintInfo &rInf)
Definition: porlin.cxx:269
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:159
TextFrameIndex FormatQuoVadis(TextFrameIndex nStart)
Definition: txtftn.cxx:1071
SwCharFormat * GetAnchorCharFormat(SwDoc &rDoc) const
Definition: docftn.cxx:182
constexpr TypedWhichId< SvxCrossedOutItem > RES_CHRATR_CROSSEDOUT(5)
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:878
bool IsLayoutSplitAllowed() const
Definition: tabfrm.cxx:5823
SwViewShell * GetVsh()
Definition: inftxt.hxx:221
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
sal_uInt16 GetLineNr() const
Definition: itrtxt.hxx:87
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:161
virtual SwFieldPortion * Clone(const OUString &rExpand) const override
Definition: txtftn.cxx:1507
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:115
virtual void HandlePortion(SwPortionHandler &rPH) const override
Definition: txtftn.cxx:1489
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1503
bool IsQuick() const
Definition: inftxt.hxx:587
bool IsInSct() const
Definition: frame.hxx:967
void MakeDummyLine()
This function creates a Line that reaches to the other Page Margin.
Definition: txtftn.cxx:1275
SwLineLayout * GetNext()
Definition: porlay.hxx:159
SwFootnoteFrame * ImplFindFootnoteFrame()
Definition: findfrm.cxx:559
bool SeekStartAndChg(SwTextSizeInfo &rInf, const bool bPara=false)
Definition: itrtxt.hxx:323
bool IsSwapped() const
Definition: txtfrm.hxx:536
bool HasPara() const
Definition: txtfrm.hxx:820
bool IsBefore(const SwLayoutFrame *_pCheckRefLayFrame) const
method to check relative position of layout frame to a given layout frame.
Definition: findfrm.cxx:258
static SwFootnoteFrame * FindFootnote(const SwContentFrame *, const SwTextFootnote *)
Definition: ftnfrm.cxx:1694
void SetFootnoteInside(const bool bNew)
Definition: inftxt.hxx:200
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: porexp.cxx:74
bool IsInFootnote() const
Definition: frame.hxx:949
void SetFixWidth(const sal_uInt16 nNew)
Definition: porglue.hxx:38
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:476
long Long
SwTwips mnFootnoteLine
Definition: txtfrm.hxx:186
The SwPortionHandler interface implements a visitor for the layout engine's text portions.
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
void SetFakeLineStart(const bool bNew)
Definition: inftxt.hxx:573
SwTwips Left() const
Definition: inftxt.hxx:542
Definition: doc.hxx:187
bool HasFollow() const
Definition: flowfrm.hxx:165
sal_uInt16 GetTextHeight() const
Definition: inftxt.hxx:713
void UpdateFootnoteNum()
Definition: ftnfrm.cxx:2430
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
void SetErgoSumNum(const OUString &rErgo)
Definition: txtftn.cxx:1546
SwTextAttr const * PrevAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:228
bool IsErgoDone() const
Definition: inftxt.hxx:627
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:77
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
SwFont * m_pFont
Definition: itratr.hxx:39
void CharToLine(TextFrameIndex)
Definition: itrtxt.cxx:193
static void ChangeFootnoteRef(const SwContentFrame *pOld, const SwTextFootnote *, SwContentFrame *pNew)
Definition: ftnfrm.cxx:1762
std::unique_ptr< SwFont > m_pFont
Definition: porfld.hxx:39
bool IsVert() const
Definition: frame.hxx:1366
void DrawText(const OUString &rText, const SwLinePortion &rPor, TextFrameIndex nIdx=TextFrameIndex(0), TextFrameIndex nLen=TextFrameIndex(COMPLETE_STRING), const bool bKern=false) const
Definition: inftxt.hxx:747
const SwLineLayout * Next()
Definition: itrtxt.cxx:107
sal_uInt16 RealWidth() const
Definition: inftxt.hxx:549
const Size & GetSize(SwFontScript nWhich) const
Definition: swfont.hxx:206
bool IsEndNote() const
Definition: fmtftn.hxx:71
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: txtftn.cxx:1397
void RearrangeFootnotes(const SwTwips nDeadLine, const bool bLock, const SwTextFootnote *pAttr=nullptr)
Definition: ftnfrm.cxx:2213
SwTwips Y() const
Definition: itrtxt.hxx:90
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:250
void SetPara(SwParaPortion *pNew, bool bDelete=true)
Definition: txtcache.cxx:129
OUString GetViewNumStr(const SwDoc &rDoc, SwRootFrame const *pLayout, bool bInclStrings=false) const
Returns string to be displayed of footnote / endnote.
Definition: atrftn.cxx:217
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:91
void CalcFootnoteFlag(TextFrameIndex nStop=TextFrameIndex(COMPLETE_STRING))
Does the Frame have a local footnote (in this Frame or Follow)?
Definition: txtftn.cxx:103
const OUString & GetQuoText() const
Definition: porftn.hxx:77
bool mbPreferredScriptTypeSet
Definition: porftn.hxx:35
SwTextFormatInfo & GetInfo()
Definition: itrform2.hxx:213
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
SwSectionFrame * ImplFindSctFrame()
Definition: findfrm.cxx:535
constexpr tools::Long Width() const
bool IsMarginPortion() const
Definition: porlin.hxx:130
void ValidateBodyFrame()
Definition: frmform.cxx:139
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: txtftn.cxx:1494
static bool Collecting(SwDoc *pDoc, SwSectionFrame const *pSect, SwFootnoteFrame *pFootnote)
Definition: layouter.cxx:275
wrapper class for the positioning of Writer fly frames and drawing objects
void SetParaFootnote()
Definition: inftxt.hxx:781
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
LINESTYLE_NONE
const SwRect & getFrameArea() const
Definition: frame.hxx:179
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1036
void CollectEndnote(SwFootnoteFrame *pFootnote)
Definition: layouter.cxx:225
size_t pos
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
sal_Unicode GetChar(TextFrameIndex const nPos) const
Definition: inftxt.hxx:240
bool IsInTab() const
Definition: frame.hxx:955
void SetNumber(const OUString &rStr)
Definition: porftn.hxx:76
SwTextFootnote * m_pFootnote
Definition: porftn.hxx:32
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const override
Definition: txtftn.cxx:1391
SwTwips Right() const
Definition: itrtxt.hxx:181
SwTwips GetFootnoteLine(const SwTextFootnote *pFootnote) const
If we're a Footnote that grows towards its reference ...
Definition: txtftn.cxx:272
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
void DrawViewOpt(const SwLinePortion &rPor, PortionType nWhich, const Color *pColor=nullptr) const
Definition: inftxt.cxx:1304
bool IsSctFrame() const
Definition: frame.hxx:1214
void AppendFootnote(SwContentFrame *, SwTextFootnote *)
Definition: ftnfrm.cxx:1513
void CalcRealHeight(bool bNewLine=false)
Definition: itrform2.cxx:1872
void ChgPhysFnt(SwViewShell const *pSh, OutputDevice &rOut)
Definition: swfont.cxx:893
TextFrameIndex GetLineStart() const
Definition: inftxt.hxx:590
sal_uInt16 GetStackCount() const
Definition: docredln.cxx:1906
SwFontScript GetActual() const
Definition: swfont.hxx:184
virtual SwFieldPortion * Clone(const OUString &rExpand) const override
Definition: txtftn.cxx:1440
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:856
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:439
void SetPreferredScriptType(SwFontScript nPreferredScriptType)
Definition: txtftn.cxx:1434
virtual void Special(TextFrameIndex nLength, const OUString &rText, PortionType nType, sal_Int32 nHeight=0, sal_Int32 nWidth=0, const SwFont *pFont=nullptr)=0
special portion.
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1806
SwQuoVadisPortion(const OUString &rExp, const OUString &rStr)
Definition: txtftn.cxx:1445
void ResetPreps()
Definition: txtfrm.cxx:1354
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1107
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
void CheckScript(const SwTextSizeInfo &rInf)
Definition: porfld.cxx:206
virtual SwLinePortion * Append(SwLinePortion *pPortion)
Definition: porlin.cxx:190
void SetLeft(bool bNew)
Definition: porfld.hxx:86
#define SW_MOD()
Definition: swmodule.hxx:255
SwFootnotePortion * NewFootnotePortion(SwTextFormatInfo &rInf, SwTextAttr *pHt)
The portion for the Footnote Reference in the Text.
Definition: txtftn.cxx:792
void ConnectFootnote(SwTextFootnote *pFootnote, const SwTwips nDeadLine)
We basically only have two possibilities:
Definition: txtftn.cxx:592
SwFrame * GetIndPrev() const
Definition: frame.hxx:724
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:131
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1409
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:78
SwTwips GetRealHeight() const
Definition: porlay.hxx:169
vcl::RenderContext * GetOut()
Definition: inftxt.hxx:224
void SetStop(const bool bNew)
Definition: inftxt.hxx:575
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
void SetWhichPor(const PortionType nNew)
Definition: porlin.hxx:98
bool IsFlyPortion() const
Definition: porlin.hxx:131
bool IsInFootnoteConnect() const
Definition: txtfrm.hxx:524
TextFrameIndex MapModelToView(MergedPara const &, SwTextNode const *pNode, sal_Int32 nIndex)
Definition: txtfrm.cxx:1186
const SwFrame * Lower() const
Definition: layfrm.hxx:101
virtual SwLayouter * GetLayouter()=0
void SetVertical(Degree10 nDir, const bool bVertLayout=false, const bool bVertLayoutLRBT=false)
Definition: swfont.cxx:417
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
void ManipOfst(TextFrameIndex const nNewOfst)
Definition: txtfrm.hxx:442
vector_type::size_type size_type
Definition: docary.hxx:222
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:827
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
SwSection * GetSection()
Definition: sectfrm.hxx:97
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(MergedPara const &, TextFrameIndex nIndex)
Definition: txtfrm.cxx:1167
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
WEIGHT_NORMAL
SwFootnoteFrame * FindFirstFootnote()
Definition: ftnfrm.cxx:1082
static SwTwips lcl_GetFootnoteLower(const SwTextFrame *pFrame, SwTwips nLower)
Local helper function.
Definition: txtftn.cxx:179
sal_uInt16 Width() const
Definition: inftxt.hxx:528
bool IsRowFrame() const
Definition: frame.hxx:1222
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:460
Provides access to settings of a document.
const SwRangeRedline * FindAtPosition(const SwPosition &startPosition, size_type &tableIndex, bool next=true) const
Find the redline at the given position.
Definition: docredln.cxx:739
SwFrame * GetPrev()
Definition: frame.hxx:677
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:272
Marks a node in the document model.
Definition: ndindex.hxx:30
SwTwips GetFootnoteFrameHeight_() const
Calculates the maximum reachable height for the TextFrame in the Footnote Area.
Definition: txtftn.cxx:313
OUString m_aExpand
Definition: porfld.hxx:38
bool isFrameAreaPositionValid() const
Definition: frame.hxx:166
void TruncLines(bool bNoteFollow=false)
Definition: itrtxt.cxx:330
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1422
static OUString lcl_GetPageNumber(const SwPageFrame *pPage)
Definition: txtftn.cxx:1035
SwErgoSumPortion(const OUString &rExp, std::u16string_view rStr)
Definition: txtftn.cxx:1512
ITALIC_NONE
SwTwips Height() const
Definition: possiz.hxx:49
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
SwContentFrame * FindLastContent(SwFindMode nMode=SwFindMode::None)
Definition: sectfrm.cxx:918
TextFrameIndex GetLen() const
Definition: porlin.hxx:76
A page of the document layout.
Definition: pagefrm.hxx:57
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const override
Definition: txtftn.cxx:1479
tools::Long SwTwips
Definition: swtypes.hxx:51
SwErgoSumPortion * NewErgoSumPortion(SwTextFormatInfo const &rInf) const
Definition: txtftn.cxx:1043
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:556
const long LONG_MAX
const SwPosition * Start() const
Definition: pam.hxx:213
Used in footnotes if they break across pages, master has this portion at the end. ...
Definition: porftn.hxx:67
const SwAttrSet & GetCharAttr() const
Definition: inftxt.hxx:775
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange,::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1107
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
const SwFootnoteFrame * GetMaster() const
Definition: ftnfrm.hxx:119
void ValidateFrame()
Definition: frmform.cxx:83
SwFrame * FindColFrame()
Definition: findfrm.cxx:584
const SwFrameFormat * GetDfltFrameFormat() const
Definition: doc.hxx:746
SwTwips & GetAscent()
Definition: porlin.hxx:79
bool RemoveFootnote(const SwContentFrame *, const SwTextFootnote *, bool bPrep=true)
Definition: ftnfrm.cxx:1734
SwTwips X() const
Definition: inftxt.hxx:379
bool mbInFootnoteConnect
Definition: txtfrm.hxx:228
constexpr TypedWhichId< SvxColorItem > RES_CHRATR_COLOR(3)
SwTextFrame * m_pFrame
Definition: itrtxt.hxx:34
bool IsFootnoteNumFrame_() const
Definition: txtftn.cxx:70
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:51
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:211
constexpr TypedWhichId< SvxBrushItem > RES_CHRATR_BACKGROUND(21)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual SwPosSize GetTextSize(const SwTextSizeInfo &rInfo) const override
Definition: txtftn.cxx:1425
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: porfld.cxx:303
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
bool Growable() const
checks whether the SectionFrame is still able to grow, as case may be the environment has to be asked...
Definition: sectfrm.cxx:2152
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
void InsertCnt_(SwLayoutFrame *pLay, SwDoc *pDoc, SwNodeOffset nIndex, bool bPages=false, SwNodeOffset nEndIndex=SwNodeOffset(0), SwFrame *pPrv=nullptr, sw::FrameMode eMode=sw::FrameMode::New)
Definition: frmtool.cxx:1485
TextFrameIndex FormatLine(TextFrameIndex nStart)
Definition: itrform2.cxx:1659
void SetRef(SwContentFrame *pNew)
Definition: ftnfrm.hxx:127
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
SwCharFormat * GetCharFormat(SwDoc &rDoc) const
Definition: docftn.cxx:140
SwTwips Width() const
Definition: possiz.hxx:51
Used in footnotes if they break across pages, follow starts with this portion.
Definition: porftn.hxx:93
tools::Long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1403
For the text replacement and restoration of SwTextSizeInfo.
Definition: inftxt.hxx:674
bool IsTabFrame() const
Definition: frame.hxx:1218
bool UpdateQuoVadis(std::u16string_view rQuo)
Is called in SwTextFrame::Prepare()
Definition: txtftn.cxx:1568
void CalcAdjustLine(SwLineLayout *pCurr)
Definition: itrform2.cxx:746
sal_uInt8 & GetTox()
Definition: swfont.hxx:249
std::size_t GetAuthor(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1914
void SetBackColor(std::optional< Color > xNewColor)
Definition: swfont.cxx:64
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:737
constexpr tools::Long Height() const
void SetSize(const Size &rSize, const SwFontScript nWhich)
Definition: swfont.hxx:741
PortionType GetWhichPor() const
Definition: porlin.hxx:99
void SetFootnoteDone(const bool bNew)
Definition: inftxt.hxx:626
void SetFootnote(const bool bNew)
Will be moved soon.
Definition: txtfrm.hxx:600
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: txtftn.cxx:1416
SwLinePortion * GetRest()
Definition: inftxt.hxx:576
SwTextFrame * FindFootnoteRef(const SwTextFootnote *pFootnote)
Looks for the TextFrame matching the SwTextFootnote within a master-follow chain. ...
Definition: txtftn.cxx:83
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1255
SwLinePortion * FindLastPortion()
Definition: porlin.cxx:179
void SetActual(SwFontScript nNew)
Definition: swfont.hxx:751
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
const SwFootnoteFrame * GetFollow() const
Definition: ftnfrm.hxx:116
SvxAdjust GetAdjust() const
Definition: itrtxt.hxx:190
virtual TextFrameIndex GetModelPositionForViewPoint(sal_uInt16 nOfst) const override
the parameter is actually SwTwips apparently?
Definition: txtftn.cxx:1523
bool CalcPrepFootnoteAdjust()
Definition: txtftn.cxx:138
bool IsRightToLeft() const
Definition: frame.hxx:987
TextFrameIndex GetLen() const
Definition: inftxt.hxx:274
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1929
const SwContentFrame * GetRef() const
Definition: ftnfrm.cxx:2906
SwFrame * GetLower()
Definition: findfrm.cxx:194
bool mbFootnote
Definition: txtfrm.hxx:229
void SetErgoDone(const bool bNew)
Definition: inftxt.hxx:628
bool IsFootnoteAllowed() const
Definition: ftnfrm.cxx:887
const SwTextFootnote * GetAttr() const
Definition: ftnfrm.hxx:122
bool HasFollow() const
Definition: porfld.hxx:94
css::uno::Reference< css::text::XTextRange > getAnchor(SwDoc &rDoc) const
Definition: atrftn.cxx:268
void MoveFootnotes(const SwContentFrame *pSrc, SwContentFrame *pDest, SwTextFootnote const *pAttr)
Definition: ftnfrm.cxx:2175
SwFontScript
Definition: swfont.hxx:123
SwFontScript mnPreferredScriptType
Definition: porftn.hxx:36
void SetRealHeight(SwTwips nNew)
Definition: porlay.hxx:168
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
SwNumberPortion * NewFootnoteNumPortion(SwTextFormatInfo const &rInf) const
The portion for the Footnote Numbering in the Footnote Area.
Definition: txtftn.cxx:932
constexpr sal_uInt16 RES_CHRATR_END(46)
void SetNextPortion(SwLinePortion *pNew)
Definition: porlin.hxx:78
void FeedInf(SwTextFormatInfo &rInf) const
Definition: itrform2.cxx:2028
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
OUString m_aQuoVadis
Definition: ftninfo.hxx:95
bool IsVertical() const
Definition: frame.hxx:973
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
void Insert(SwLineLayout *pLine)
Definition: itrform2.cxx:124
short Seek(SwFont &rFnt, SwNodeOffset nNode, sal_Int32 nNew, sal_Int32 nOld)
Definition: redlnitr.cxx:675
SwFootnotePos m_ePos
Definition: ftninfo.hxx:97
SwDoc & GetDoc()
Definition: txtfrm.hxx:461
bool IsFootnoteAtEnd() const
Definition: sectfrm.hxx:160
void SetDiffFnt(const SfxItemSet *pSet, const IDocumentSettingAccess *pIDocumentSettingAccess)
Definition: swfont.cxx:473
bool HasRedline() const
Definition: porlay.hxx:135
constexpr TypedWhichId< SvxCharRotateItem > RES_CHRATR_ROTATE(32)
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
bool IsTest() const
Definition: inftxt.hxx:588
SwTextFrame * GetTextFrame()
Definition: itrtxt.hxx:134
SwLineLayout * m_pCurr
Definition: itrtxt.hxx:36
SwTwips GetLineHeight() const
Definition: itrtxt.hxx:116
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
SwFootnotePortion(const OUString &rExpand, SwTextFootnote *pFootnote, sal_uInt16 nOrig=USHRT_MAX)
Definition: txtftn.cxx:1378
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: txtftn.cxx:1452
bool IsQuoVadisPortion() const
Definition: porlin.hxx:120
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:74
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:70
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
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
void SetRest(SwLinePortion *pNewRest)
Definition: inftxt.hxx:577
sal_uInt16 GetFrameRstHeight() const
Definition: itrform2.cxx:136
virtual SwPosSize GetTextSize(const SwTextSizeInfo &rInfo) const override
Definition: porexp.cxx:51
void RemoveFootnote(TextFrameIndex nStart, TextFrameIndex nLen=TextFrameIndex(COMPLETE_STRING))
Footnote.
Definition: txtftn.cxx:407
SwTextFrame * FindQuoVadisFrame()
Find the page number of ErgoSum and QuoVadis.
Definition: txtftn.cxx:384
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:70
bool mbHasRotatedPortions
Contains rotated portions.
Definition: txtfrm.hxx:232
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:629
SwRedlineItr * GetRedln()
Definition: itratr.hxx:81
TextFrameIndex GetTextStart() const
Definition: inftxt.hxx:123
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
OUString m_aErgo
Definition: porftn.hxx:69
bool IsFootnoteDone() const
Definition: inftxt.hxx:625
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:631
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: txtftn.cxx:1528
OUString m_aErgoSum
Definition: ftninfo.hxx:96
sal_uInt16 nPos
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
sal_uInt16 GetAscent() const
Definition: inftxt.hxx:707
bool m_bDetectedRangeSegmentation false
void SetAscent(const SwTwips nNewAsc)
Definition: porlin.hxx:81
SwFrame * GetNext()
Definition: frame.hxx:676
bool HasFootnote() const
Definition: txtfrm.hxx:523
const SvxNumberType & GetNumType() const
Definition: pagedesc.hxx:202