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