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