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