LibreOffice Module sw (master)  1
itrform2.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <hintids.hxx>
21 
22 #include <memory>
23 #include <com/sun/star/i18n/ScriptType.hpp>
24 #include <editeng/lspcitem.hxx>
25 #include <dcontact.hxx>
26 #include <txtflcnt.hxx>
27 #include <txtftn.hxx>
28 #include <flyfrms.hxx>
29 #include <fmtflcnt.hxx>
30 #include <fmtftn.hxx>
31 #include <ftninfo.hxx>
32 #include <charfmt.hxx>
34 #include <layfrm.hxx>
35 #include <viewsh.hxx>
36 #include <viewopt.hxx>
37 #include <paratr.hxx>
38 #include "itrform2.hxx"
39 #include "porrst.hxx"
40 #include "portab.hxx"
41 #include "porfly.hxx"
42 #include "portox.hxx"
43 #include "porref.hxx"
44 #include "porfld.hxx"
45 #include "porftn.hxx"
46 #include "porhyph.hxx"
47 #include "pordrop.hxx"
48 #include "guess.hxx"
49 #include <blink.hxx>
50 #include <ftnfrm.hxx>
51 #include "redlnitr.hxx"
52 #include <pagefrm.hxx>
53 #include <pagedesc.hxx>
54 #include <tgrditem.hxx>
55 #include <doc.hxx>
56 #include "pormulti.hxx"
57 #include <unotools/charclass.hxx>
58 #include <xmloff/odffields.hxx>
60 #include <IMark.hxx>
61 #include <IDocumentMarkAccess.hxx>
62 #include <svl/zforlist.hxx>
63 
64 #include <vector>
65 
66 using namespace ::com::sun::star;
67 
68 namespace {
70  long lcl_CalcOptRepaint( SwTextFormatter &rThis,
71  SwLineLayout const &rCurr,
72  TextFrameIndex nOldLineEnd,
73  const std::vector<long> &rFlyStarts );
75  bool lcl_BuildHiddenPortion(const SwTextSizeInfo& rInf, TextFrameIndex &rPos);
76 
77  // Check whether the two font has the same border
78  bool lcl_HasSameBorder(const SwFont& rFirst, const SwFont& rSecond);
79 }
80 
81 static void ClearFly( SwTextFormatInfo &rInf )
82 {
83  delete rInf.GetFly();
84  rInf.SetFly(nullptr);
85 }
86 
88 {
89  CtorInitTextPainter( pNewFrame, pNewInf );
90  m_pInf = pNewInf;
92  m_pMulti = nullptr;
93 
94  m_bOnceMore = false;
95  m_bFlyInContentBase = false;
96  m_bTruncLines = false;
101  m_pByEndIter.reset();
102  m_pFirstOfBorderMerge = nullptr;
103 
104  if (m_nStart > TextFrameIndex(GetInfo().GetText().getLength()))
105  {
106  OSL_ENSURE( false, "+SwTextFormatter::CTOR: bad offset" );
107  m_nStart = TextFrameIndex(GetInfo().GetText().getLength());
108  }
109 
110 }
111 
113 {
114  // Extremely unlikely, but still possible
115  // e.g.: field splits up, widows start to matter
116  if( GetInfo().GetRest() )
117  {
118  delete GetInfo().GetRest();
119  GetInfo().SetRest(nullptr);
120  }
121 }
122 
124 {
125  // Insert BEHIND the current element
126  if ( m_pCurr )
127  {
128  pLay->SetNext( m_pCurr->GetNext() );
129  m_pCurr->SetNext( pLay );
130  }
131  else
132  m_pCurr = pLay;
133 }
134 
136 {
137  // We want the rest height relative to the page.
138  // If we're in a table, then pFrame->GetUpper() is not the page.
139 
140  // GetFrameRstHeight() is being called with Footnote.
141  // Wrong: const SwFrame *pUpper = pFrame->GetUpper();
142  const SwFrame *pPage = m_pFrame->FindPageFrame();
143  const SwTwips nHeight = pPage->getFrameArea().Top()
144  + pPage->getFramePrintArea().Top()
145  + pPage->getFramePrintArea().Height() - Y();
146  if( 0 > nHeight )
147  return m_pCurr->Height();
148  else
149  return sal_uInt16( nHeight );
150 }
151 
153 {
154  // Save values and initialize rInf
155  SwLinePortion *pUnderflow = rInf.GetUnderflow();
156  if( !pUnderflow )
157  return nullptr;
158 
159  // We format backwards, i.e. attribute changes can happen the next
160  // line again.
161  // Can be seen in 8081.sdw, if you enter text in the first line
162 
163  TextFrameIndex const nSoftHyphPos = rInf.GetSoftHyphPos();
164  TextFrameIndex const nUnderScorePos = rInf.GetUnderScorePos();
165 
166  // Save flys and set to 0, or else segmentation fault
167  // Not ClearFly(rInf) !
168  SwFlyPortion *pFly = rInf.GetFly();
169  rInf.SetFly( nullptr );
170 
171  FeedInf( rInf );
172  rInf.SetLast( m_pCurr );
173  // pUnderflow does not need to be deleted, because it will drown in the following
174  // Truncate()
175  rInf.SetUnderflow(nullptr);
176  rInf.SetSoftHyphPos( nSoftHyphPos );
177  rInf.SetUnderScorePos( nUnderScorePos );
178  rInf.SetPaintOfst( GetLeftMargin() );
179 
180  // We look for the portion with the under-flow position
182  if( pPor != pUnderflow )
183  {
184  // pPrev will be the last portion before pUnderflow,
185  // which still has a real width.
186  // Exception: SoftHyphPortion must not be forgotten, of course!
187  // Although they don't have a width.
188  SwLinePortion *pTmpPrev = pPor;
189  while( pPor && pPor != pUnderflow )
190  {
191  if( !pPor->IsKernPortion() &&
192  ( pPor->Width() || pPor->IsSoftHyphPortion() ) )
193  {
194  while( pTmpPrev != pPor )
195  {
196  pTmpPrev->Move( rInf );
197  rInf.SetLast( pTmpPrev );
198  pTmpPrev = pTmpPrev->GetNextPortion();
199  OSL_ENSURE( pTmpPrev, "Underflow: losing control!" );
200  };
201  }
202  pPor = pPor->GetNextPortion();
203  }
204  pPor = pTmpPrev;
205  if( pPor && // Skip flys and initials when underflow.
206  ( pPor->IsFlyPortion() || pPor->IsDropPortion() ||
207  pPor->IsFlyCntPortion() ) )
208  {
209  pPor->Move( rInf );
210  rInf.SetLast( pPor );
211  rInf.SetStopUnderflow( true );
212  pPor = pUnderflow;
213  }
214  }
215 
216  // What? The under-flow portion is not in the portion chain?
217  OSL_ENSURE( pPor, "SwTextFormatter::Underflow: overflow but underflow" );
218 
219  // Snapshot
220  if ( pPor==rInf.GetLast() )
221  {
222  // We end up here, if the portion triggering the under-flow
223  // spans over the whole line. E.g. if a word spans across
224  // multiple lines and flows into a fly in the second line.
225  rInf.SetFly( pFly );
226  pPor->Truncate();
227  return pPor; // Is that enough?
228  }
229  // End the snapshot
230 
231  // X + Width == 0 with SoftHyph > Line?!
232  if( !pPor || !(rInf.X() + pPor->Width()) )
233  {
234  delete pFly;
235  return nullptr;
236  }
237 
238  // Preparing for Format()
239  // We need to chip off the chain behind pLast, because we Insert after the Format()
240  SeekAndChg( rInf );
241 
242  // line width is adjusted, so that pPor does not fit to current
243  // line anymore
244  rInf.Width( static_cast<sal_uInt16>(rInf.X() + (pPor->Width() ? pPor->Width() - 1 : 0)) );
245  rInf.SetLen( pPor->GetLen() );
246  rInf.SetFull( false );
247  if( pFly )
248  {
249  // We need to recalculate the FlyPortion due to the following reason:
250  // If the base line is lowered by a big font in the middle of the line,
251  // causing overlapping with a fly, the FlyPortion has a wrong size/fixed
252  // size.
253  rInf.SetFly( pFly );
254  CalcFlyWidth( rInf );
255  }
256  rInf.GetLast()->SetNextPortion(nullptr);
257 
258  // The SwLineLayout is an exception to this, which splits at the first
259  // portion change.
260  // Here only the other way around:
261  if( rInf.GetLast() == m_pCurr )
262  {
263  if( pPor->InTextGrp() && !pPor->InExpGrp() )
264  {
265  const PortionType nOldWhich = m_pCurr->GetWhichPor();
266  *static_cast<SwLinePortion*>(m_pCurr) = *pPor;
268  m_pCurr->SetWhichPor( nOldWhich );
269  pPor->SetNextPortion( nullptr );
270  delete pPor;
271  pPor = m_pCurr;
272  }
273  }
274 
275  // Make sure that m_pFirstOfBorderMerge does not point to a portion which
276  // will be deleted by Truncate() below.
277  SwLinePortion* pNext = pPor->GetNextPortion();
278  while (pNext)
279  {
280  if (pNext == m_pFirstOfBorderMerge)
281  {
282  m_pFirstOfBorderMerge = nullptr;
283  break;
284  }
285  pNext = pNext->GetNextPortion();
286  }
287  pPor->Truncate();
288  SwLinePortion *const pRest( rInf.GetRest() );
289  if (pRest && pRest->InFieldGrp() &&
290  static_cast<SwFieldPortion*>(pRest)->IsNoLength())
291  {
292  // HACK: decrement again, so we pick up the suffix in next line!
293  m_pByEndIter->PrevAttr();
294  }
295  delete pRest;
296  rInf.SetRest(nullptr);
297  return pPor;
298 }
299 
301  SwLinePortion *pPor )
302 {
303  SwLinePortion *pLast = nullptr;
304  // The new portion is inserted, but everything's different for
305  // LineLayout...
306  if( pPor == m_pCurr )
307  {
308  if ( m_pCurr->GetNextPortion() )
309  {
310  pLast = pPor;
311  pPor = m_pCurr->GetNextPortion();
312  }
313 
314  // i#112181 - Prevent footnote anchor being wrapped to next line
315  // without preceding word
317  }
318  else
319  {
320  pLast = rInf.GetLast();
321  if( pLast->GetNextPortion() )
322  {
323  while( pLast->GetNextPortion() )
324  pLast = pLast->GetNextPortion();
325  rInf.SetLast( pLast );
326  }
327  pLast->Insert( pPor );
328 
330 
331  // Adjust maxima
332  if( m_pCurr->Height() < pPor->Height() )
333  m_pCurr->Height( pPor->Height() );
334  if( m_pCurr->GetAscent() < pPor->GetAscent() )
335  m_pCurr->SetAscent( pPor->GetAscent() );
336  }
337 
338  // Sometimes chains are constructed (e.g. by hyphenate)
339  rInf.SetLast( pPor );
340  while( pPor )
341  {
342  if (!pPor->IsDropPortion())
343  MergeCharacterBorder(*pPor, pLast, rInf);
344 
345  pPor->Move( rInf );
346  rInf.SetLast( pPor );
347  pLast = pPor;
348  pPor = pPor->GetNextPortion();
349  }
350 }
351 
353 {
354  OSL_ENSURE( rInf.GetText().getLength() < COMPLETE_STRING,
355  "SwTextFormatter::BuildPortions: bad text length in info" );
356 
357  rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
358 
359  // First NewTextPortion() decides whether pCurr ends up in pPor.
360  // We need to make sure that the font is being set in any case.
361  // This is done automatically in CalcAscent.
362  rInf.SetLast( m_pCurr );
363  rInf.ForcedLeftMargin( 0 );
364 
365  OSL_ENSURE( m_pCurr->FindLastPortion() == m_pCurr, "pLast supposed to equal pCurr" );
366 
367  if( !m_pCurr->GetAscent() && !m_pCurr->Height() )
368  CalcAscent( rInf, m_pCurr );
369 
370  SeekAndChg( rInf );
371 
372  // Width() is shortened in CalcFlyWidth if we have a FlyPortion
373  OSL_ENSURE( !rInf.X() || m_pMulti, "SwTextFormatter::BuildPortion X=0?" );
374  CalcFlyWidth( rInf );
375  SwFlyPortion *pFly = rInf.GetFly();
376  if( pFly )
377  {
378  if ( 0 < pFly->GetFix() )
379  ClearFly( rInf );
380  else
381  rInf.SetFull(true);
382  }
383 
384  SwLinePortion *pPor = NewPortion( rInf );
385 
386  // Asian grid stuff
387  SwTextGridItem const*const pGrid(GetGridItem(m_pFrame->FindPageFrame()));
388  const bool bHasGrid = pGrid && rInf.SnapToGrid() &&
389  GRID_LINES_CHARS == pGrid->GetGridType();
390 
391 
392  const SwDoc & rDoc = rInf.GetTextFrame()->GetDoc();
393  const sal_uInt16 nGridWidth = bHasGrid ? GetGridWidth(*pGrid, rDoc) : 0;
394 
395  // used for grid mode only:
396  // the pointer is stored, because after formatting of non-asian text,
397  // the width of the kerning portion has to be adjusted
398  // Inserting a SwKernPortion before a SwTabPortion isn't necessary
399  // and will break the SwTabPortion.
400  SwKernPortion* pGridKernPortion = nullptr;
401 
402  bool bFull = false;
403  SwTwips nUnderLineStart = 0;
404  rInf.Y( Y() );
405 
406  while( pPor && !rInf.IsStop() )
407  {
408  OSL_ENSURE(rInf.GetLen() < TextFrameIndex(COMPLETE_STRING) &&
409  rInf.GetIdx() <= TextFrameIndex(rInf.GetText().getLength()),
410  "SwTextFormatter::BuildPortions: bad length in info" );
411 
412  // We have to check the script for fields in order to set the
413  // correct nActual value for the font.
414  if( pPor->InFieldGrp() )
415  static_cast<SwFieldPortion*>(pPor)->CheckScript( rInf );
416 
417  if( ! bHasGrid && rInf.HasScriptSpace() &&
418  rInf.GetLast() && rInf.GetLast()->InTextGrp() &&
419  rInf.GetLast()->Width() && !rInf.GetLast()->InNumberGrp() )
420  {
421  SwFontScript nNxtActual = rInf.GetFont()->GetActual();
422  SwFontScript nLstActual = nNxtActual;
423  sal_uInt16 nLstHeight = static_cast<sal_uInt16>(rInf.GetFont()->GetHeight());
424  bool bAllowBehind = false;
425  const CharClass& rCC = GetAppCharClass();
426 
427  // are there any punctuation characters on both sides
428  // of the kerning portion?
429  if ( pPor->InFieldGrp() )
430  {
431  OUString aAltText;
432  if ( static_cast<SwFieldPortion*>(pPor)->GetExpText( rInf, aAltText ) &&
433  !aAltText.isEmpty() )
434  {
435  bAllowBehind = rCC.isLetterNumeric( aAltText, 0 );
436 
437  const SwFont* pTmpFnt = static_cast<SwFieldPortion*>(pPor)->GetFont();
438  if ( pTmpFnt )
439  nNxtActual = pTmpFnt->GetActual();
440  }
441  }
442  else
443  {
444  const OUString& rText = rInf.GetText();
445  sal_Int32 nIdx = sal_Int32(rInf.GetIdx());
446  bAllowBehind = nIdx < rText.getLength() && rCC.isLetterNumeric(rText, nIdx);
447  }
448 
449  const SwLinePortion* pLast = rInf.GetLast();
450  if ( bAllowBehind && pLast )
451  {
452  bool bAllowBefore = false;
453 
454  if ( pLast->InFieldGrp() )
455  {
456  OUString aAltText;
457  if ( static_cast<const SwFieldPortion*>(pLast)->GetExpText( rInf, aAltText ) &&
458  !aAltText.isEmpty() )
459  {
460  bAllowBefore = rCC.isLetterNumeric( aAltText, aAltText.getLength() - 1 );
461 
462  const SwFont* pTmpFnt = static_cast<const SwFieldPortion*>(pLast)->GetFont();
463  if ( pTmpFnt )
464  {
465  nLstActual = pTmpFnt->GetActual();
466  nLstHeight = static_cast<sal_uInt16>(pTmpFnt->GetHeight());
467  }
468  }
469  }
470  else if ( rInf.GetIdx() )
471  {
472  bAllowBefore = rCC.isLetterNumeric(rInf.GetText(), sal_Int32(rInf.GetIdx()) - 1);
473  // Note: ScriptType returns values in [1,4]
474  if ( bAllowBefore )
475  nLstActual = SwFontScript(m_pScriptInfo->ScriptType(rInf.GetIdx() - TextFrameIndex(1)) - 1);
476  }
477 
478  nLstHeight /= 5;
479  // does the kerning portion still fit into the line?
480  if( bAllowBefore && ( nLstActual != nNxtActual ) &&
481  nLstHeight && rInf.X() + nLstHeight <= rInf.Width() &&
482  ! pPor->InTabGrp() )
483  {
484  SwKernPortion* pKrn =
485  new SwKernPortion( *rInf.GetLast(), nLstHeight,
486  pLast->InFieldGrp() && pPor->InFieldGrp() );
487  rInf.GetLast()->SetNextPortion( nullptr );
488  InsertPortion( rInf, pKrn );
489  }
490  }
491  }
492  else if ( bHasGrid && pGrid->IsSnapToChars() && ! pGridKernPortion && ! m_pMulti && ! pPor->InTabGrp() )
493  {
494  // insert a grid kerning portion
495  pGridKernPortion = pPor->IsKernPortion() ?
496  static_cast<SwKernPortion*>(pPor) :
497  new SwKernPortion( *m_pCurr );
498 
499  // if we have a new GridKernPortion, we initially calculate
500  // its size so that its ends on the grid
501  const SwPageFrame* pPageFrame = m_pFrame->FindPageFrame();
502  const SwLayoutFrame* pBody = pPageFrame->FindBodyCont();
503  SwRectFnSet aRectFnSet(pPageFrame);
504 
505  const long nGridOrigin = pBody ?
506  aRectFnSet.GetPrtLeft(*pBody) :
507  aRectFnSet.GetPrtLeft(*pPageFrame);
508 
509  SwTwips nStartX = rInf.X() + GetLeftMargin();
510  if ( aRectFnSet.IsVert() )
511  {
512  Point aPoint( nStartX, 0 );
514  nStartX = aPoint.Y();
515  }
516 
517  const SwTwips nOfst = nStartX - nGridOrigin;
518  if ( nOfst )
519  {
520  const sal_uLong i = ( nOfst > 0 ) ?
521  ( ( nOfst - 1 ) / nGridWidth + 1 ) :
522  0;
523  const SwTwips nKernWidth = i * nGridWidth - nOfst;
524  const SwTwips nRestWidth = rInf.Width() - rInf.X();
525 
526  if ( nKernWidth <= nRestWidth )
527  pGridKernPortion->Width( static_cast<sal_uInt16>(nKernWidth) );
528  }
529 
530  if ( pGridKernPortion != pPor )
531  InsertPortion( rInf, pGridKernPortion );
532  }
533 
534  if( pPor->IsDropPortion() )
535  MergeCharacterBorder(*static_cast<SwDropPortion*>(pPor));
536 
537  // the multi-portion has its own format function
538  if( pPor->IsMultiPortion() && ( !m_pMulti || m_pMulti->IsBidi() ) )
539  bFull = BuildMultiPortion( rInf, *static_cast<SwMultiPortion*>(pPor) );
540  else
541  bFull = pPor->Format( rInf );
542 
543  if( rInf.IsRuby() && !rInf.GetRest() )
544  bFull = true;
545 
546  // if we are underlined, we store the beginning of this underlined
547  // segment for repaint optimization
548  if ( LINESTYLE_NONE != m_pFont->GetUnderline() && ! nUnderLineStart )
549  nUnderLineStart = GetLeftMargin() + rInf.X();
550 
551  if ( pPor->IsFlyPortion() )
552  m_pCurr->SetFly( true );
553  // some special cases, where we have to take care for the repaint
554  // offset:
555  // 1. Underlined portions due to special underline feature
556  // 2. Right Tab
557  // 3. BidiPortions
558  // 4. other Multiportions
559  // 5. DropCaps
560  // 6. Grid Mode
561  else if ( ( ! rInf.GetPaintOfst() || nUnderLineStart < rInf.GetPaintOfst() ) &&
562  // 1. Underlined portions
563  nUnderLineStart &&
564  // reformat is at end of an underlined portion and next portion
565  // is not underlined
566  ( ( rInf.GetReformatStart() == rInf.GetIdx() &&
568  ) ||
569  // reformat is inside portion and portion is underlined
570  ( rInf.GetReformatStart() >= rInf.GetIdx() &&
571  rInf.GetReformatStart() <= rInf.GetIdx() + pPor->GetLen() &&
573  rInf.SetPaintOfst( nUnderLineStart );
574  else if ( ! rInf.GetPaintOfst() &&
575  // 2. Right Tab
576  ( ( pPor->InTabGrp() && !pPor->IsTabLeftPortion() ) ||
577  // 3. BidiPortions
578  ( pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->IsBidi() ) ||
579  // 4. Multi Portion and 5. Drop Caps
580  ( ( pPor->IsDropPortion() || pPor->IsMultiPortion() ) &&
581  rInf.GetReformatStart() >= rInf.GetIdx() &&
582  rInf.GetReformatStart() <= rInf.GetIdx() + pPor->GetLen() )
583  // 6. Grid Mode
584  || ( bHasGrid && SwFontScript::CJK != m_pFont->GetActual() )
585  )
586  )
587  // we store the beginning of the critical portion as our
588  // paint offset
589  rInf.SetPaintOfst( GetLeftMargin() + rInf.X() );
590 
591  // under one of these conditions we are allowed to delete the
592  // start of the underline portion
593  if ( IsUnderlineBreak( *pPor, *m_pFont ) )
594  nUnderLineStart = 0;
595 
596  if( pPor->IsFlyCntPortion() || ( pPor->IsMultiPortion() &&
597  static_cast<SwMultiPortion*>(pPor)->HasFlyInContent() ) )
598  SetFlyInCntBase();
599  // bUnderflow needs to be reset or we wrap again at the next softhyphen
600  if ( !bFull )
601  {
602  rInf.ClrUnderflow();
603  if( ! bHasGrid && rInf.HasScriptSpace() && pPor->InTextGrp() &&
604  pPor->GetLen() && !pPor->InFieldGrp() )
605  {
606  // The distance between two different scripts is set
607  // to 20% of the fontheight.
608  TextFrameIndex const nTmp = rInf.GetIdx() + pPor->GetLen();
609  if (nTmp == m_pScriptInfo->NextScriptChg(nTmp - TextFrameIndex(1)) &&
610  nTmp != TextFrameIndex(rInf.GetText().getLength()) &&
611  (m_pScriptInfo->ScriptType(nTmp - TextFrameIndex(1)) == css::i18n::ScriptType::ASIAN ||
612  m_pScriptInfo->ScriptType(nTmp) == css::i18n::ScriptType::ASIAN) )
613  {
614  const sal_uInt16 nDist = static_cast<sal_uInt16>(rInf.GetFont()->GetHeight()/5);
615 
616  if( nDist )
617  {
618  // we do not want a kerning portion if any end
619  // would be a punctuation character
620  const CharClass& rCC = GetAppCharClass();
621  if (rCC.isLetterNumeric(rInf.GetText(), sal_Int32(nTmp) - 1)
622  && rCC.isLetterNumeric(rInf.GetText(), sal_Int32(nTmp)))
623  {
624  // does the kerning portion still fit into the line?
625  if ( rInf.X() + pPor->Width() + nDist <= rInf.Width() )
626  new SwKernPortion( *pPor, nDist );
627  else
628  bFull = true;
629  }
630  }
631  }
632  }
633  }
634 
635  if ( bHasGrid && pGrid->IsSnapToChars() && pPor != pGridKernPortion && ! m_pMulti && ! pPor->InTabGrp() )
636  {
637  TextFrameIndex const nTmp = rInf.GetIdx() + pPor->GetLen();
638  const SwTwips nRestWidth = rInf.Width() - rInf.X() - pPor->Width();
639 
640  const SwFontScript nCurrScript = m_pFont->GetActual(); // pScriptInfo->ScriptType( rInf.GetIdx() );
641  const SwFontScript nNextScript =
642  nTmp >= TextFrameIndex(rInf.GetText().getLength())
644  : m_pScriptInfo->WhichFont(nTmp);
645 
646  // snap non-asian text to grid if next portion is ASIAN or
647  // there are no more portions in this line
648  // be careful when handling an underflow event: the gridkernportion
649  // could have been deleted
650  if ( nRestWidth > 0 && SwFontScript::CJK != nCurrScript &&
651  ! rInf.IsUnderflow() && ( bFull || SwFontScript::CJK == nNextScript ) )
652  {
653  OSL_ENSURE( pGridKernPortion, "No GridKernPortion available" );
654 
655  // calculate size
656  SwLinePortion* pTmpPor = pGridKernPortion->GetNextPortion();
657  sal_uInt16 nSumWidth = pPor->Width();
658  while ( pTmpPor )
659  {
660  nSumWidth = nSumWidth + pTmpPor->Width();
661  pTmpPor = pTmpPor->GetNextPortion();
662  }
663 
664  const SwTwips i = nSumWidth ?
665  ( nSumWidth - 1 ) / nGridWidth + 1 :
666  0;
667  const SwTwips nTmpWidth = i * nGridWidth;
668  const SwTwips nKernWidth = std::min(nTmpWidth - nSumWidth, nRestWidth);
669  const sal_uInt16 nKernWidth_1 = static_cast<sal_uInt16>(nKernWidth / 2);
670 
671  OSL_ENSURE( nKernWidth <= nRestWidth,
672  "Not enough space left for adjusting non-asian text in grid mode" );
673 
674  pGridKernPortion->Width( pGridKernPortion->Width() + nKernWidth_1 );
675  rInf.X( rInf.X() + nKernWidth_1 );
676 
677  if ( ! bFull )
678  new SwKernPortion( *pPor, static_cast<short>(nKernWidth - nKernWidth_1),
679  false, true );
680 
681  pGridKernPortion = nullptr;
682  }
683  else if ( pPor->IsMultiPortion() || pPor->InFixMargGrp() ||
684  pPor->IsFlyCntPortion() || pPor->InNumberGrp() ||
685  pPor->InFieldGrp() || nCurrScript != nNextScript )
686  // next portion should snap to grid
687  pGridKernPortion = nullptr;
688  }
689 
690  rInf.SetFull( bFull );
691 
692  // Restportions from fields with multiple lines don't yet have the right ascent
693  if ( !pPor->GetLen() && !pPor->IsFlyPortion()
694  && !pPor->IsGrfNumPortion() && ! pPor->InNumberGrp()
695  && !pPor->IsMultiPortion() )
696  CalcAscent( rInf, pPor );
697 
698  InsertPortion( rInf, pPor );
699  pPor = NewPortion( rInf );
700  }
701 
702  if( !rInf.IsStop() )
703  {
704  // The last right centered, decimal tab
705  SwTabPortion *pLastTab = rInf.GetLastTab();
706  if( pLastTab )
707  pLastTab->FormatEOL( rInf );
708  else if( rInf.GetLast() && rInf.LastKernPortion() )
709  rInf.GetLast()->FormatEOL( rInf );
710  }
712  && static_cast<SwNumberPortion*>(m_pCurr->GetNextPortion())->IsHide() )
713  rInf.SetNumDone( false );
714 
715  // Delete fly in any case
716  ClearFly( rInf );
717 
718  // Reinit the tab overflow flag after the line
719  rInf.SetTabOverflow( false );
720 }
721 
723 {
724  if( SvxAdjust::Left != GetAdjust() && !m_pMulti)
725  {
726  pCurrent->SetFormatAdj(true);
727  if( IsFlyInCntBase() )
728  {
729  CalcAdjLine( pCurrent );
730  // For e.g. centered fly we need to switch the RefPoint
731  // That's why bAlways = true
732  UpdatePos( pCurrent, GetTopLeft(), GetStart(), true );
733  }
734  }
735 }
736 
738 {
739  bool bCalc = false;
740  if ( pPor->InFieldGrp() && static_cast<SwFieldPortion*>(pPor)->GetFont() )
741  {
742  // Numbering + InterNetFields can keep an own font, then their size is
743  // independent from hard attribute values
744  SwFont* pFieldFnt = static_cast<SwFieldPortion*>(pPor)->m_pFont.get();
745  SwFontSave aSave( rInf, pFieldFnt );
746  pPor->Height( rInf.GetTextHeight() );
747  pPor->SetAscent( rInf.GetAscent() );
748  bCalc = true;
749  }
750  // i#89179
751  // tab portion representing the list tab of a list label gets the
752  // same height and ascent as the corresponding number portion
753  else if ( pPor->InTabGrp() && pPor->GetLen() == TextFrameIndex(0) &&
754  rInf.GetLast() && rInf.GetLast()->InNumberGrp() &&
755  static_cast<const SwNumberPortion*>(rInf.GetLast())->HasFont() )
756  {
757  const SwLinePortion* pLast = rInf.GetLast();
758  pPor->Height( pLast->Height() );
759  pPor->SetAscent( pLast->GetAscent() );
760  }
761  else
762  {
763  const SwLinePortion *pLast = rInf.GetLast();
764  bool bChg = false;
765 
766  // In empty lines the attributes are switched on via SeekStart
767  const bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
768  if ( pPor->IsQuoVadisPortion() )
769  bChg = SeekStartAndChg( rInf, true );
770  else
771  {
772  if( bFirstPor )
773  {
774  if( !rInf.GetText().isEmpty() )
775  {
776  if ( pPor->GetLen() || !rInf.GetIdx()
777  || ( m_pCurr != pLast && !pLast->IsFlyPortion() )
778  || !m_pCurr->IsRest() ) // instead of !rInf.GetRest()
779  bChg = SeekAndChg( rInf );
780  else
781  bChg = SeekAndChgBefore( rInf );
782  }
783  else if ( m_pMulti )
784  // do not open attributes starting at 0 in empty multi
785  // portions (rotated numbering followed by a footnote
786  // can cause trouble, because the footnote attribute
787  // starts at 0, but if we open it, the attribute handler
788  // cannot handle it.
789  bChg = false;
790  else
791  bChg = SeekStartAndChg( rInf );
792  }
793  else
794  bChg = SeekAndChg( rInf );
795  }
796  if( bChg || bFirstPor || !pPor->GetAscent()
797  || !rInf.GetLast()->InTextGrp() )
798  {
799  pPor->SetAscent( rInf.GetAscent() );
800  pPor->Height( rInf.GetTextHeight() );
801  bCalc = true;
802  }
803  else
804  {
805  pPor->Height( pLast->Height() );
806  pPor->SetAscent( pLast->GetAscent() );
807  }
808  }
809 
810  if( pPor->InTextGrp() && bCalc )
811  {
812  pPor->SetAscent(pPor->GetAscent() +
813  rInf.GetFont()->GetTopBorderSpace());
814  pPor->Height(pPor->Height() +
815  rInf.GetFont()->GetTopBorderSpace() +
816  rInf.GetFont()->GetBottomBorderSpace() );
817  }
818 }
819 
821 {
822 public:
824  virtual void Paint( const SwTextPaintInfo &rInf ) const override;
825 };
826 
827 void SwMetaPortion::Paint( const SwTextPaintInfo &rInf ) const
828 {
829  if ( Width() )
830  {
831  rInf.DrawViewOpt( *this, PortionType::Meta );
832  SwTextPortion::Paint( rInf );
833  }
834 }
835 
836 namespace sw { namespace mark {
838  {
839  const IFieldmark::parameter_map_t* const pParameters = pBM->GetParameters();
840  sal_Int32 nCurrentIdx = 0;
841  const IFieldmark::parameter_map_t::const_iterator pResult = pParameters->find(OUString(ODF_FORMDROPDOWN_RESULT));
842  if(pResult != pParameters->end())
843  pResult->second >>= nCurrentIdx;
844 
845  const IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find(OUString(ODF_FORMDROPDOWN_LISTENTRY));
846  if (pListEntries != pParameters->end())
847  {
848  uno::Sequence< OUString > vListEntries;
849  pListEntries->second >>= vListEntries;
850  if (nCurrentIdx < vListEntries.getLength())
851  return vListEntries[nCurrentIdx];
852  }
853 
854  static const sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194};
855  return OUString(vEnSpaces, ODF_FORMFIELD_DEFAULT_LENGTH);
856  }
857 } }
858 
860 {
861  SwTextPortion *pPor = nullptr;
862  if( GetFnt()->IsTox() )
863  {
864  pPor = new SwToxPortion;
865  }
866  else if ( GetFnt()->IsInputField() )
867  {
868  pPor = new SwTextInputFieldPortion();
869  }
870  else
871  {
872  if( GetFnt()->IsRef() )
873  pPor = new SwRefPortion;
874  else if (GetFnt()->IsMeta())
875  {
876  pPor = new SwMetaPortion;
877  }
878  else
879  {
880  // Only at the End!
881  // If pCurr does not have a width, it can however already have content.
882  // E.g. for non-displayable characters
883 
884  auto const ch(rInf.GetText()[sal_Int32(rInf.GetIdx())]);
885  SwTextFrame const*const pFrame(rInf.GetTextFrame());
886  SwPosition aPosition(pFrame->MapViewToModelPos(rInf.GetIdx()));
887  sw::mark::IFieldmark *pBM = pFrame->GetDoc().getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
888  if(pBM != nullptr && pBM->GetFieldname( ) == ODF_FORMDATE)
889  {
890  if (ch == CH_TXT_ATR_FIELDSTART)
891  pPor = new SwFieldFormDatePortion(pBM, true);
892  else if (ch == CH_TXT_ATR_FIELDSEP)
893  pPor = new SwFieldMarkPortion(); // it's added in DateFieldmark?
894  else if (ch == CH_TXT_ATR_FIELDEND)
895  pPor = new SwFieldFormDatePortion(pBM, false);
896  }
897  else if (ch == CH_TXT_ATR_FIELDSTART)
898  pPor = new SwFieldMarkPortion();
899  else if (ch == CH_TXT_ATR_FIELDSEP)
900  pPor = new SwFieldMarkPortion();
901  else if (ch == CH_TXT_ATR_FIELDEND)
902  pPor = new SwFieldMarkPortion();
903  else if (ch == CH_TXT_ATR_FORMELEMENT)
904  {
905  OSL_ENSURE(pBM != nullptr, "Where is my form field bookmark???");
906  if (pBM != nullptr)
907  {
908  if (pBM->GetFieldname( ) == ODF_FORMCHECKBOX)
909  {
910  pPor = new SwFieldFormCheckboxPortion();
911  }
912  else if (pBM->GetFieldname( ) == ODF_FORMDROPDOWN)
913  {
915  }
916  /* we need to check for ODF_FORMTEXT for scenario having FormFields inside FORMTEXT.
917  * Otherwise file will crash on open.
918  */
919  else if (pBM->GetFieldname( ) == ODF_FORMTEXT)
920  {
921  pPor = new SwFieldMarkPortion();
922  }
923  }
924  }
925  if( !pPor )
926  {
927  if( !rInf.X() && !m_pCurr->GetNextPortion() && !m_pCurr->GetLen() )
928  pPor = m_pCurr;
929  else
930  pPor = new SwTextPortion;
931  }
932  }
933  }
934  return pPor;
935 }
936 
937 // We calculate the length, the following portion limits are defined:
938 // 1) Tabs
939 // 2) Linebreaks
940 // 3) CH_TXTATR_BREAKWORD / CH_TXTATR_INWORD
941 // 4) next attribute change
942 
944 {
945  // If we're at the line's beginning, we take pCurr
946  // If pCurr is not derived from SwTextPortion, we need to duplicate
947  Seek( rInf.GetIdx() );
948  SwTextPortion *pPor = WhichTextPor( rInf );
949 
950  // until next attribute change:
951  const TextFrameIndex nNextAttr = GetNextAttr();
952  TextFrameIndex nNextChg = std::min(nNextAttr, TextFrameIndex(rInf.GetText().getLength()));
953 
954  // end of script type:
955  const TextFrameIndex nNextScript = m_pScriptInfo->NextScriptChg(rInf.GetIdx());
956  nNextChg = std::min( nNextChg, nNextScript );
957 
958  // end of direction:
959  const TextFrameIndex nNextDir = m_pScriptInfo->NextDirChg(rInf.GetIdx());
960  nNextChg = std::min( nNextChg, nNextDir );
961 
962  // hidden change (potentially via bookmark):
963  const TextFrameIndex nNextHidden = m_pScriptInfo->NextHiddenChg(rInf.GetIdx());
964  nNextChg = std::min( nNextChg, nNextHidden );
965 
966  // Turbo boost:
967  // We assume that font characters are not larger than twice
968  // as wide as height.
969  // Very crazy: we need to take the ascent into account.
970 
971  // Mind the trap! GetSize() contains the wished-for height, the real height
972  // is only known in CalcAscent!
973 
974  // The ratio is even crazier: a blank in Times New Roman has an ascent of
975  // 182, a height of 200 and a width of 53!
976  // It follows that a line with a lot of blanks is processed incorrectly.
977  // Therefore we increase from factor 2 to 8 (due to negative kerning).
978 
979  pPor->SetLen(TextFrameIndex(1));
980  CalcAscent( rInf, pPor );
981 
982  const SwFont* pTmpFnt = rInf.GetFont();
983  sal_Int32 nExpect = std::min( sal_Int32( pTmpFnt->GetHeight() ),
984  sal_Int32( pPor->GetAscent() ) ) / 8;
985  if ( !nExpect )
986  nExpect = 1;
987  nExpect = sal_Int32(rInf.GetIdx()) + (rInf.GetLineWidth() / nExpect);
988  if (TextFrameIndex(nExpect) > rInf.GetIdx() && nNextChg > TextFrameIndex(nExpect))
989  nNextChg = TextFrameIndex(std::min(nExpect, rInf.GetText().getLength()));
990 
991  // we keep an invariant during method calls:
992  // there are no portion ending characters like hard spaces
993  // or tabs in [ nLeftScanIdx, nRightScanIdx ]
994  if ( m_nLeftScanIdx <= rInf.GetIdx() && rInf.GetIdx() <= m_nRightScanIdx )
995  {
996  if ( nNextChg > m_nRightScanIdx )
997  nNextChg = m_nRightScanIdx =
998  rInf.ScanPortionEnd( m_nRightScanIdx, nNextChg );
999  }
1000  else
1001  {
1002  m_nLeftScanIdx = rInf.GetIdx();
1003  nNextChg = m_nRightScanIdx =
1004  rInf.ScanPortionEnd( rInf.GetIdx(), nNextChg );
1005  }
1006 
1007  pPor->SetLen( nNextChg - rInf.GetIdx() );
1008  rInf.SetLen( pPor->GetLen() );
1009  return pPor;
1010 }
1011 
1013 {
1014  SwLinePortion *pPor = nullptr;
1015 
1016  if( rInf.GetRest() )
1017  {
1018  // Tabs and fields
1019  if( '\0' != rInf.GetHookChar() )
1020  return nullptr;
1021 
1022  pPor = rInf.GetRest();
1023  if( pPor->IsErgoSumPortion() )
1024  rInf.SetErgoDone(true);
1025  else
1026  if( pPor->IsFootnoteNumPortion() )
1027  rInf.SetFootnoteDone(true);
1028  else
1029  if( pPor->InNumberGrp() )
1030  rInf.SetNumDone(true);
1031 
1032  rInf.SetRest(nullptr);
1033  m_pCurr->SetRest( true );
1034  return pPor;
1035  }
1036 
1037  // We can stand in the follow, it's crucial that
1038  // pFrame->GetOfst() == 0!
1039  if( rInf.GetIdx() )
1040  {
1041  // We now too can elongate FootnotePortions and ErgoSumPortions
1042 
1043  // 1. The ErgoSumTexts
1044  if( !rInf.IsErgoDone() )
1045  {
1046  if( m_pFrame->IsInFootnote() && !m_pFrame->GetIndPrev() )
1047  pPor = NewErgoSumPortion( rInf );
1048  rInf.SetErgoDone( true );
1049  }
1050 
1051  // 2. Arrow portions
1052  if( !pPor && !rInf.IsArrowDone() )
1053  {
1054  if( m_pFrame->GetOfst() && !m_pFrame->IsFollow() &&
1055  rInf.GetIdx() == m_pFrame->GetOfst() )
1056  pPor = new SwArrowPortion( *m_pCurr );
1057  rInf.SetArrowDone( true );
1058  }
1059 
1060  // 3. Kerning portions at beginning of line in grid mode
1061  if ( ! pPor && ! m_pCurr->GetNextPortion() )
1062  {
1063  SwTextGridItem const*const pGrid(
1064  GetGridItem(GetTextFrame()->FindPageFrame()));
1065  if ( pGrid )
1066  pPor = new SwKernPortion( *m_pCurr );
1067  }
1068 
1069  // 4. The line rests (multiline fields)
1070  if( !pPor )
1071  {
1072  pPor = rInf.GetRest();
1073  // Only for pPor of course
1074  if( pPor )
1075  {
1076  m_pCurr->SetRest( true );
1077  rInf.SetRest(nullptr);
1078  }
1079  }
1080  }
1081  else
1082  {
1083  // 5. The foot note count
1084  if( !rInf.IsFootnoteDone() )
1085  {
1086  OSL_ENSURE( ( ! rInf.IsMulti() && ! m_pMulti ) || m_pMulti->HasRotation(),
1087  "Rotated number portion trouble" );
1088 
1089  const bool bFootnoteNum = m_pFrame->IsFootnoteNumFrame();
1090  rInf.GetParaPortion()->SetFootnoteNum( bFootnoteNum );
1091  if( bFootnoteNum )
1092  pPor = NewFootnoteNumPortion( rInf );
1093  rInf.SetFootnoteDone( true );
1094  }
1095 
1096  // 6. The ErgoSumTexts of course also exist in the TextMaster,
1097  // it's crucial whether the SwFootnoteFrame is aFollow
1098  if( !rInf.IsErgoDone() && !pPor && ! rInf.IsMulti() )
1099  {
1100  if( m_pFrame->IsInFootnote() && !m_pFrame->GetIndPrev() )
1101  pPor = NewErgoSumPortion( rInf );
1102  rInf.SetErgoDone( true );
1103  }
1104 
1105  // 7. The numbering
1106  if( !rInf.IsNumDone() && !pPor )
1107  {
1108  OSL_ENSURE( ( ! rInf.IsMulti() && ! m_pMulti ) || m_pMulti->HasRotation(),
1109  "Rotated number portion trouble" );
1110 
1111  // If we're in the follow, then of course not
1113  pPor = NewNumberPortion( rInf );
1114  rInf.SetNumDone( true );
1115  }
1116  // 8. The DropCaps
1117  if( !pPor && GetDropFormat() && ! rInf.IsMulti() )
1118  pPor = NewDropPortion( rInf );
1119 
1120  // 9. Kerning portions at beginning of line in grid mode
1121  if ( !pPor && !m_pCurr->GetNextPortion() )
1122  {
1123  SwTextGridItem const*const pGrid(
1124  GetGridItem(GetTextFrame()->FindPageFrame()));
1125  if ( pGrid )
1126  pPor = new SwKernPortion( *m_pCurr );
1127  }
1128  }
1129 
1130  // 10. Decimal tab portion at the beginning of each line in table cells
1131  if ( !pPor && !m_pCurr->GetNextPortion() &&
1132  GetTextFrame()->IsInTab() &&
1134  {
1135  pPor = NewTabPortion( rInf, true );
1136  }
1137 
1138  // 11. suffix of meta-field
1139  if (!pPor)
1140  {
1141  pPor = TryNewNoLengthPortion(rInf);
1142  }
1143 
1144  return pPor;
1145 }
1146 
1147 static bool lcl_OldFieldRest( const SwLineLayout* pCurr )
1148 {
1149  if( !pCurr->GetNext() )
1150  return false;
1151  const SwLinePortion *pPor = pCurr->GetNext()->GetNextPortion();
1152  bool bRet = false;
1153  while( pPor && !bRet )
1154  {
1155  bRet = (pPor->InFieldGrp() && static_cast<const SwFieldPortion*>(pPor)->IsFollow()) ||
1156  (pPor->IsMultiPortion() && static_cast<const SwMultiPortion*>(pPor)->IsFollowField());
1157  if( !pPor->GetLen() )
1158  break;
1159  pPor = pPor->GetNextPortion();
1160  }
1161  return bRet;
1162 }
1163 
1164 /* NewPortion sets rInf.nLen
1165  * A SwTextPortion is limited by a tab, break, txtatr or attr change
1166  * We can have three cases:
1167  * 1) The line is full and the wrap was not emulated
1168  * -> return 0;
1169  * 2) The line is full and a wrap was emulated
1170  * -> Reset width and return new FlyPortion
1171  * 3) We need to construct a new portion
1172  * -> CalcFlyWidth emulates the width and return portion, if needed
1173  */
1174 
1176 {
1177  // Underflow takes precedence
1178  rInf.SetStopUnderflow( false );
1179  if( rInf.GetUnderflow() )
1180  {
1181  OSL_ENSURE( rInf.IsFull(), "SwTextFormatter::NewPortion: underflow but not full" );
1182  return Underflow( rInf );
1183  }
1184 
1185  // If the line is full, flys and Underflow portions could be waiting ...
1186  if( rInf.IsFull() )
1187  {
1188  // LineBreaks and Flys (bug05.sdw)
1189  // IsDummy()
1190  if( rInf.IsNewLine() && (!rInf.GetFly() || !m_pCurr->IsDummy()) )
1191  return nullptr;
1192 
1193  // When the text bumps into the Fly, or when the Fly comes first because
1194  // it juts out over the left edge, GetFly() is returned.
1195  // When IsFull() and no GetFly() is available, naturally zero is returned.
1196  if( rInf.GetFly() )
1197  {
1198  if( rInf.GetLast()->IsBreakPortion() )
1199  {
1200  delete rInf.GetFly();
1201  rInf.SetFly( nullptr );
1202  }
1203 
1204  return rInf.GetFly();
1205  }
1206 
1207  // A nasty special case: A frame without wrap overlaps the Footnote area.
1208  // We must declare the Footnote portion as rest of line, so that
1209  // SwTextFrame::Format doesn't abort (the text mass already was formatted).
1210  if( rInf.GetRest() )
1211  rInf.SetNewLine( true );
1212  else
1213  {
1214  // When the next line begins with a rest of a field, but now no
1215  // rest remains, the line must definitely be formatted anew!
1216  if( lcl_OldFieldRest( GetCurr() ) )
1217  rInf.SetNewLine( true );
1218  else
1219  {
1220  SwLinePortion *pFirst = WhichFirstPortion( rInf );
1221  if( pFirst )
1222  {
1223  rInf.SetNewLine( true );
1224  if( pFirst->InNumberGrp() )
1225  rInf.SetNumDone( false) ;
1226  delete pFirst;
1227  }
1228  }
1229  }
1230 
1231  return nullptr;
1232  }
1233 
1234  SwLinePortion *pPor = WhichFirstPortion( rInf );
1235 
1236  // Check for Hidden Portion:
1237  if ( !pPor )
1238  {
1239  TextFrameIndex nEnd = rInf.GetIdx();
1240  if ( ::lcl_BuildHiddenPortion( rInf, nEnd ) )
1241  pPor = new SwHiddenTextPortion( nEnd - rInf.GetIdx() );
1242  }
1243 
1244  if( !pPor )
1245  {
1246  if( ( !m_pMulti || m_pMulti->IsBidi() ) &&
1247  // i#42734
1248  // No multi portion if there is a hook character waiting:
1249  ( !rInf.GetRest() || '\0' == rInf.GetHookChar() ) )
1250  {
1251  // We open a multiportion part, if we enter a multi-line part
1252  // of the paragraph.
1253  TextFrameIndex nEnd = rInf.GetIdx();
1254  std::unique_ptr<SwMultiCreator> pCreate = rInf.GetMultiCreator( nEnd, m_pMulti );
1255  if( pCreate )
1256  {
1257  SwMultiPortion* pTmp = nullptr;
1258 
1259  if ( SwMultiCreatorId::Bidi == pCreate->nId )
1260  pTmp = new SwBidiPortion( nEnd, pCreate->nLevel );
1261  else if ( SwMultiCreatorId::Ruby == pCreate->nId )
1262  {
1263  pTmp = new SwRubyPortion( *pCreate, *rInf.GetFont(),
1265  nEnd, TextFrameIndex(0), rInf );
1266  }
1267  else if( SwMultiCreatorId::Rotate == pCreate->nId )
1268  pTmp = new SwRotatedPortion( *pCreate, nEnd,
1269  GetTextFrame()->IsRightToLeft() );
1270  else
1271  pTmp = new SwDoubleLinePortion( *pCreate, nEnd );
1272 
1273  pCreate.reset();
1274  CalcFlyWidth( rInf );
1275 
1276  return pTmp;
1277  }
1278  }
1279  // Tabs and Fields
1280  sal_Unicode cChar = rInf.GetHookChar();
1281 
1282  if( cChar )
1283  {
1284  /* We fetch cChar again to be sure that the tab is pending now and
1285  * didn't move to the next line (as happens behind frames).
1286  * However, when a FieldPortion is in the rest, we must naturally fetch
1287  * the cChar from the field content, e.g. DecimalTabs and fields (22615)
1288  */
1289  if( !rInf.GetRest() || !rInf.GetRest()->InFieldGrp() )
1290  cChar = rInf.GetChar( rInf.GetIdx() );
1291  rInf.ClearHookChar();
1292  }
1293  else
1294  {
1295  if (rInf.GetIdx() >= TextFrameIndex(rInf.GetText().getLength()))
1296  {
1297  rInf.SetFull(true);
1298  CalcFlyWidth( rInf );
1299  return pPor;
1300  }
1301  cChar = rInf.GetChar( rInf.GetIdx() );
1302  }
1303 
1304  switch( cChar )
1305  {
1306  case CH_TAB:
1307  pPor = NewTabPortion( rInf, false ); break;
1308 
1309  case CH_BREAK:
1310  pPor = new SwBreakPortion( *rInf.GetLast() ); break;
1311 
1312  case CHAR_SOFTHYPHEN: // soft hyphen
1313  pPor = new SwSoftHyphPortion; break;
1314 
1315  case CHAR_HARDBLANK: // no-break space
1316  // Please check tdf#115067 if you want to edit the char
1317  pPor = new SwBlankPortion( cChar ); break;
1318 
1319  case CHAR_HARDHYPHEN: // non-breaking hyphen
1320  pPor = new SwBlankPortion( '-' ); break;
1321 
1322  case CHAR_ZWSP: // zero width space
1323  case CHAR_ZWNBSP : // word joiner
1324  pPor = new SwControlCharPortion( cChar ); break;
1325 
1326  case CH_TXTATR_BREAKWORD:
1327  case CH_TXTATR_INWORD:
1328  if( rInf.HasHint( rInf.GetIdx() ) )
1329  {
1330  pPor = NewExtraPortion( rInf );
1331  break;
1332  }
1333  [[fallthrough]];
1334  default :
1335  {
1336  SwTabPortion* pLastTabPortion = rInf.GetLastTab();
1337  if ( pLastTabPortion && cChar == rInf.GetTabDecimal() )
1338  {
1339  // Abandon dec. tab position if line is full
1340  // We have a decimal tab portion in the line and the next character has to be
1341  // aligned at the tab stop position. We store the width from the beginning of
1342  // the tab stop portion up to the portion containing the decimal separator:
1343  if (GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::TAB_COMPAT) /*rInf.GetVsh()->IsTabCompat();*/ &&
1344  PortionType::TabDecimal == pLastTabPortion->GetWhichPor() )
1345  {
1346  OSL_ENSURE( rInf.X() >= pLastTabPortion->GetFix(), "Decimal tab stop position cannot be calculated" );
1347  const sal_uInt16 nWidthOfPortionsUpToDecimalPosition = static_cast<sal_uInt16>(rInf.X() - pLastTabPortion->GetFix() );
1348  static_cast<SwTabDecimalPortion*>(pLastTabPortion)->SetWidthOfPortionsUpToDecimalPosition( nWidthOfPortionsUpToDecimalPosition );
1349  rInf.SetTabDecimal( 0 );
1350  }
1351  else
1352  rInf.SetFull( rInf.GetLastTab()->Format( rInf ) );
1353  }
1354 
1355  if( rInf.GetRest() )
1356  {
1357  if( rInf.IsFull() )
1358  {
1359  rInf.SetNewLine(true);
1360  return nullptr;
1361  }
1362  pPor = rInf.GetRest();
1363  rInf.SetRest(nullptr);
1364  }
1365  else
1366  {
1367  if( rInf.IsFull() )
1368  return nullptr;
1369  pPor = NewTextPortion( rInf );
1370  }
1371  break;
1372  }
1373  }
1374 
1375  // if a portion is created despite there being a pending RestPortion,
1376  // then it is a field which has been split (e.g. because it contains a Tab)
1377  if( pPor && rInf.GetRest() )
1378  pPor->SetLen(TextFrameIndex(0));
1379 
1380  // robust:
1381  if( !pPor || rInf.IsStop() )
1382  {
1383  delete pPor;
1384  return nullptr;
1385  }
1386  }
1387 
1388  assert(pPor && "can only reach here with pPor existing");
1389 
1390  // Special portions containing numbers (footnote anchor, footnote number,
1391  // numbering) can be contained in a rotated portion, if the user
1392  // choose a rotated character attribute.
1393  if (!m_pMulti)
1394  {
1395  if ( pPor->IsFootnotePortion() )
1396  {
1397  const SwTextFootnote* pTextFootnote = static_cast<SwFootnotePortion*>(pPor)->GetTextFootnote();
1398 
1399  if ( pTextFootnote )
1400  {
1401  SwFormatFootnote& rFootnote = const_cast<SwFormatFootnote&>(pTextFootnote->GetFootnote());
1402  const SwDoc *const pDoc = &rInf.GetTextFrame()->GetDoc();
1403  const SwEndNoteInfo* pInfo;
1404  if( rFootnote.IsEndNote() )
1405  pInfo = &pDoc->GetEndNoteInfo();
1406  else
1407  pInfo = &pDoc->GetFootnoteInfo();
1408  const SwAttrSet& rSet = pInfo->GetAnchorCharFormat(const_cast<SwDoc&>(*pDoc))->GetAttrSet();
1409 
1410  const SfxPoolItem* pItem;
1411  sal_uInt16 nDir = 0;
1412  if( SfxItemState::SET == rSet.GetItemState( RES_CHRATR_ROTATE,
1413  true, &pItem ))
1414  nDir = static_cast<const SvxCharRotateItem*>(pItem)->GetValue();
1415 
1416  if ( 0 != nDir )
1417  {
1418  delete pPor;
1419  pPor = new SwRotatedPortion(rInf.GetIdx() + TextFrameIndex(1),
1420  900 == nDir
1421  ? DIR_BOTTOM2TOP
1422  : DIR_TOP2BOTTOM );
1423  }
1424  }
1425  }
1426  else if ( pPor->InNumberGrp() )
1427  {
1428  const SwFont* pNumFnt = static_cast<SwFieldPortion*>(pPor)->GetFont();
1429 
1430  if ( pNumFnt )
1431  {
1432  sal_uInt16 nDir = pNumFnt->GetOrientation( rInf.GetTextFrame()->IsVertical() );
1433  if ( 0 != nDir )
1434  {
1435  delete pPor;
1436  pPor = new SwRotatedPortion(TextFrameIndex(0), 900 == nDir
1437  ? DIR_BOTTOM2TOP
1438  : DIR_TOP2BOTTOM );
1439 
1440  rInf.SetNumDone( false );
1441  rInf.SetFootnoteDone( false );
1442  }
1443  }
1444  }
1445  }
1446 
1447  // The font is set in output device,
1448  // the ascent and the height will be calculated.
1449  if( !pPor->GetAscent() && !pPor->Height() )
1450  CalcAscent( rInf, pPor );
1451  rInf.SetLen( pPor->GetLen() );
1452 
1453  // In CalcFlyWidth Width() will be shortened if a FlyPortion is present.
1454  CalcFlyWidth( rInf );
1455 
1456  // One must not forget that pCurr as GetLast() must provide reasonable values:
1457  if( !m_pCurr->Height() )
1458  {
1459  OSL_ENSURE( m_pCurr->Height(), "SwTextFormatter::NewPortion: limbo dance" );
1460  m_pCurr->Height( pPor->Height() );
1461  m_pCurr->SetAscent( pPor->GetAscent() );
1462  }
1463 
1464  OSL_ENSURE(pPor->Height(), "SwTextFormatter::NewPortion: something went wrong");
1465  if( pPor->IsPostItsPortion() && rInf.X() >= rInf.Width() && rInf.GetFly() )
1466  {
1467  delete pPor;
1468  pPor = rInf.GetFly();
1469  }
1470  return pPor;
1471 }
1472 
1474 {
1475  OSL_ENSURE( ! m_pFrame->IsVertical() || m_pFrame->IsSwapped(),
1476  "SwTextFormatter::FormatLine( nStartPos ) with unswapped frame" );
1477 
1478  // For the formatting routines, we set pOut to the reference device.
1479  SwHookOut aHook( GetInfo() );
1480  if (GetInfo().GetLen() < TextFrameIndex(GetInfo().GetText().getLength()))
1481  GetInfo().SetLen(TextFrameIndex(GetInfo().GetText().getLength()));
1482 
1483  bool bBuild = true;
1484  SetFlyInCntBase( false );
1485  GetInfo().SetLineHeight( 0 );
1486  GetInfo().SetLineNetHeight( 0 );
1487 
1488  // Recycling must be suppressed by changed line height and also
1489  // by changed ascent (lowering of baseline).
1490  const sal_uInt16 nOldHeight = m_pCurr->Height();
1491  const sal_uInt16 nOldAscent = m_pCurr->GetAscent();
1492 
1493  m_pCurr->SetEndHyph( false );
1494  m_pCurr->SetMidHyph( false );
1495 
1496  // fly positioning can make it necessary format a line several times
1497  // for this, we have to keep a copy of our rest portion
1498  SwLinePortion* pField = GetInfo().GetRest();
1499  std::unique_ptr<SwFieldPortion> xSaveField;
1500 
1501  if ( pField && pField->InFieldGrp() && !pField->IsFootnotePortion() )
1502  xSaveField.reset(new SwFieldPortion( *static_cast<SwFieldPortion*>(pField) ));
1503 
1504  // for an optimal repaint rectangle, we want to compare fly portions
1505  // before and after the BuildPortions call
1506  const bool bOptimizeRepaint = AllowRepaintOpt();
1507  TextFrameIndex const nOldLineEnd = nStartPos + m_pCurr->GetLen();
1508  std::vector<long> flyStarts;
1509 
1510  // these are the conditions for a fly position comparison
1511  if ( bOptimizeRepaint && m_pCurr->IsFly() )
1512  {
1514  long nPOfst = 0;
1515  while ( pPor )
1516  {
1517  if ( pPor->IsFlyPortion() )
1518  // insert start value of fly portion
1519  flyStarts.push_back( nPOfst );
1520 
1521  nPOfst += pPor->Width();
1522  pPor = pPor->GetNextPortion();
1523  }
1524  }
1525 
1526  // Here soon the underflow check follows.
1527  while( bBuild )
1528  {
1529  GetInfo().SetFootnoteInside( false );
1531 
1532  // These values must not be reset by FormatReset();
1533  const bool bOldNumDone = GetInfo().IsNumDone();
1534  const bool bOldArrowDone = GetInfo().IsArrowDone();
1535  const bool bOldErgoDone = GetInfo().IsErgoDone();
1536 
1537  // besides other things, this sets the repaint offset to 0
1538  FormatReset( GetInfo() );
1539 
1540  GetInfo().SetNumDone( bOldNumDone );
1541  GetInfo().SetArrowDone( bOldArrowDone );
1542  GetInfo().SetErgoDone( bOldErgoDone );
1543 
1544  // build new portions for this line
1545  BuildPortions( GetInfo() );
1546 
1547  if( GetInfo().IsStop() )
1548  {
1550  m_pCurr->Height( GetFrameRstHeight() + 1 );
1552  m_pCurr->Width(0);
1553  m_pCurr->Truncate();
1554  return nStartPos;
1555  }
1556  else if( GetInfo().IsDropInit() )
1557  {
1558  DropInit();
1559  GetInfo().SetDropInit( false );
1560  }
1561 
1562  m_pCurr->CalcLine( *this, GetInfo() );
1564 
1565  //i#120864 For Special case that at the first calculation couldn't get
1566  //correct height. And need to recalculate for the right height.
1567  SwLinePortion* pPorTmp = m_pCurr->GetNextPortion();
1568  if ( IsFlyInCntBase() && (!IsQuick() || (pPorTmp && pPorTmp->IsFlyCntPortion() && !pPorTmp->GetNextPortion() &&
1569  m_pCurr->Height() > pPorTmp->Height())))
1570  {
1571  sal_uInt16 nTmpAscent, nTmpHeight;
1572  CalcAscentAndHeight( nTmpAscent, nTmpHeight );
1573  AlignFlyInCntBase( Y() + long( nTmpAscent ) );
1574  m_pCurr->CalcLine( *this, GetInfo() );
1575  CalcRealHeight();
1576  }
1577 
1578  // bBuild decides if another lap of honor is done
1579  if ( m_pCurr->GetRealHeight() <= GetInfo().GetLineHeight() )
1580  {
1582  bBuild = false;
1583  }
1584  else
1585  {
1586  bBuild = ( GetInfo().GetTextFly().IsOn() && ChkFlyUnderflow(GetInfo()) )
1588  if( bBuild )
1589  {
1590  GetInfo().SetNumDone( bOldNumDone );
1592 
1593  // delete old rest
1594  if ( GetInfo().GetRest() )
1595  {
1596  delete GetInfo().GetRest();
1597  GetInfo().SetRest( nullptr );
1598  }
1599 
1600  // set original rest portion
1601  if ( xSaveField )
1602  GetInfo().SetRest( new SwFieldPortion( *xSaveField ) );
1603 
1605  m_pCurr->Width(0);
1606  m_pCurr->Truncate();
1607  }
1608  }
1609  }
1610 
1611  // In case of compat mode, it's possible that a tab portion is wider after
1612  // formatting than before. If this is the case, we also have to make sure
1613  // the SwLineLayout is wider as well.
1614  if (GetInfo().GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::TAB_OVER_MARGIN))
1615  {
1616  sal_uInt16 nSum = 0;
1618 
1619  while (pPor)
1620  {
1621  nSum += pPor->Width();
1622  pPor = pPor->GetNextPortion();
1623  }
1624 
1625  if (nSum > m_pCurr->Width())
1626  m_pCurr->Width(nSum);
1627  }
1628 
1629  // calculate optimal repaint rectangle
1630  if ( bOptimizeRepaint )
1631  {
1632  GetInfo().SetPaintOfst( ::lcl_CalcOptRepaint( *this, *m_pCurr, nOldLineEnd, flyStarts ) );
1633  flyStarts.clear();
1634  }
1635  else
1636  // Special case: we do not allow an optimization of the repaint
1637  // area, but during formatting the repaint offset is set to indicate
1638  // a maximum value for the offset. This value has to be reset:
1639  GetInfo().SetPaintOfst( 0 );
1640 
1641  // This corrects the start of the reformat range if something has
1642  // moved to the next line. Otherwise IsFirstReformat in AllowRepaintOpt
1643  // will give us a wrong result if we have to reformat another line
1644  GetInfo().GetParaPortion()->GetReformat().LeftMove( GetInfo().GetIdx() );
1645 
1646  // delete master copy of rest portion
1647  xSaveField.reset();
1648 
1649  TextFrameIndex const nNewStart = nStartPos + m_pCurr->GetLen();
1650 
1651  // adjust text if kana compression is enabled
1652  if ( GetInfo().CompressLine() )
1653  {
1654  SwTwips nRepaintOfst = CalcKanaAdj( m_pCurr );
1655 
1656  // adjust repaint offset
1657  if ( nRepaintOfst < GetInfo().GetPaintOfst() )
1658  GetInfo().SetPaintOfst( nRepaintOfst );
1659  }
1660 
1662 
1663  if( nOldHeight != m_pCurr->Height() || nOldAscent != m_pCurr->GetAscent() )
1664  {
1665  SetFlyInCntBase();
1666  GetInfo().SetPaintOfst( 0 ); // changed line height => no recycling
1667  // all following line must be painted and when Flys are around,
1668  // also formatted
1669  GetInfo().SetShift( true );
1670  }
1671 
1672  if ( IsFlyInCntBase() && !IsQuick() )
1674 
1675  return nNewStart;
1676 }
1677 
1679 {
1680  do
1681  {
1682  CalcRealHeight();
1683  } while (Next());
1684 }
1685 
1686 void SwTextFormatter::CalcRealHeight( bool bNewLine )
1687 {
1688  sal_uInt16 nLineHeight = m_pCurr->Height();
1689  m_pCurr->SetClipping( false );
1690 
1691  SwTextGridItem const*const pGrid(GetGridItem(m_pFrame->FindPageFrame()));
1692  if ( pGrid && GetInfo().SnapToGrid() )
1693  {
1694  const sal_uInt16 nGridWidth = pGrid->GetBaseHeight();
1695  const sal_uInt16 nRubyHeight = pGrid->GetRubyHeight();
1696  const bool bRubyTop = ! pGrid->GetRubyTextBelow();
1697 
1698  nLineHeight = nGridWidth + nRubyHeight;
1699  const sal_uInt16 nAmpRatio = (m_pCurr->Height() + nLineHeight - 1)/nLineHeight;
1700  nLineHeight *= nAmpRatio;
1701 
1702  const sal_uInt16 nAsc = m_pCurr->GetAscent() +
1703  ( bRubyTop ?
1704  ( nLineHeight - m_pCurr->Height() + nRubyHeight ) / 2 :
1705  ( nLineHeight - m_pCurr->Height() - nRubyHeight ) / 2 );
1706 
1707  m_pCurr->Height( nLineHeight );
1708  m_pCurr->SetAscent( nAsc );
1710 
1711  // we ignore any line spacing options except from ...
1712  const SvxLineSpacingItem* pSpace = m_aLineInf.GetLineSpacing();
1713  if ( ! IsParaLine() && pSpace &&
1714  SvxInterLineSpaceRule::Prop == pSpace->GetInterLineSpaceRule() )
1715  {
1716  sal_uLong nTmp = pSpace->GetPropLineSpace();
1717 
1718  if( nTmp < 100 )
1719  nTmp = 100;
1720 
1721  nTmp *= nLineHeight;
1722  nLineHeight = static_cast<sal_uInt16>(nTmp / 100);
1723  }
1724 
1725  m_pCurr->SetRealHeight( nLineHeight );
1726  return;
1727  }
1728 
1729  // The dummy flag is set on lines that only contain flyportions, these shouldn't
1730  // consider register-true and so on. Unfortunately an empty line can be at
1731  // the end of a paragraph (empty paragraphs or behind a Shift-Return),
1732  // which should consider the register.
1733  if (!m_pCurr->IsDummy() || (!m_pCurr->GetNext()
1734  && GetStart() >= TextFrameIndex(GetTextFrame()->GetText().getLength())
1735  && !bNewLine))
1736  {
1737  const SvxLineSpacingItem *pSpace = m_aLineInf.GetLineSpacing();
1738  if( pSpace )
1739  {
1740  switch( pSpace->GetLineSpaceRule() )
1741  {
1742  case SvxLineSpaceRule::Auto:
1743  // shrink first line of paragraph too on spacing < 100%
1744  if (IsParaLine() &&
1745  pSpace->GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop
1747  {
1748  long nTmp = pSpace->GetPropLineSpace();
1749  // Word will render < 50% too but it's just not readable
1750  if( nTmp < 50 )
1751  nTmp = nTmp ? 50 : 100;
1752  if (nTmp<100) { // code adapted from fixed line height
1753  nTmp *= nLineHeight;
1754  nTmp /= 100;
1755  if( !nTmp )
1756  ++nTmp;
1757  nLineHeight = static_cast<sal_uInt16>(nTmp);
1758  sal_uInt16 nAsc = ( 4 * nLineHeight ) / 5; // 80%
1759 #if 0
1760  // could do clipping here (like Word does)
1761  // but at 0.5 its unreadable either way...
1762  if( nAsc < pCurr->GetAscent() ||
1763  nLineHeight - nAsc < pCurr->Height() -
1764  pCurr->GetAscent() )
1765  pCurr->SetClipping( true );
1766 #endif
1767  m_pCurr->SetAscent( nAsc );
1768  m_pCurr->Height( nLineHeight );
1770  }
1771  }
1772  break;
1773  case SvxLineSpaceRule::Min:
1774  {
1775  if( nLineHeight < pSpace->GetLineHeight() )
1776  nLineHeight = pSpace->GetLineHeight();
1777  break;
1778  }
1779  case SvxLineSpaceRule::Fix:
1780  {
1781  nLineHeight = pSpace->GetLineHeight();
1782  const sal_uInt16 nAsc = ( 4 * nLineHeight ) / 5; // 80%
1783  if( nAsc < m_pCurr->GetAscent() ||
1784  nLineHeight - nAsc < m_pCurr->Height() - m_pCurr->GetAscent() )
1785  m_pCurr->SetClipping( true );
1786  m_pCurr->Height( nLineHeight );
1787  m_pCurr->SetAscent( nAsc );
1789  }
1790  break;
1791  default: OSL_FAIL( ": unknown LineSpaceRule" );
1792  }
1793  // Note: for the _first_ line the line spacing of the previous
1794  // paragraph is applied in SwFlowFrame::CalcUpperSpace()
1795  if( !IsParaLine() )
1796  switch( pSpace->GetInterLineSpaceRule() )
1797  {
1798  case SvxInterLineSpaceRule::Off:
1799  break;
1800  case SvxInterLineSpaceRule::Prop:
1801  {
1802  long nTmp = pSpace->GetPropLineSpace();
1803  // 50% is the minimum, if 0% we switch to the
1804  // default value 100% ...
1805  if( nTmp < 50 )
1806  nTmp = nTmp ? 50 : 100;
1807 
1808  nTmp *= nLineHeight;
1809  nTmp /= 100;
1810  if( !nTmp )
1811  ++nTmp;
1812  nLineHeight = static_cast<sal_uInt16>(nTmp);
1813  break;
1814  }
1815  case SvxInterLineSpaceRule::Fix:
1816  {
1817  nLineHeight = nLineHeight + pSpace->GetInterLineSpace();
1818  break;
1819  }
1820  default: OSL_FAIL( ": unknown InterLineSpaceRule" );
1821  }
1822  }
1823 
1824  if( IsRegisterOn() )
1825  {
1826  SwTwips nTmpY = Y() + m_pCurr->GetAscent() + nLineHeight - m_pCurr->Height();
1827  SwRectFnSet aRectFnSet(m_pFrame);
1828  if ( aRectFnSet.IsVert() )
1829  nTmpY = m_pFrame->SwitchHorizontalToVertical( nTmpY );
1830  nTmpY = aRectFnSet.YDiff( nTmpY, RegStart() );
1831  const sal_uInt16 nDiff = sal_uInt16( nTmpY % RegDiff() );
1832  if( nDiff )
1833  nLineHeight += RegDiff() - nDiff;
1834  }
1835  }
1836  m_pCurr->SetRealHeight( nLineHeight );
1837 }
1838 
1840 {
1841  // delete Fly in any case!
1842  ClearFly( rInf );
1843  rInf.Init();
1844 
1845  rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() );
1846  rInf.SetRoot( m_pCurr );
1847  rInf.SetLineStart( m_nStart );
1848  rInf.SetIdx( m_nStart );
1849  rInf.Left( Left() );
1850  rInf.Right( Right() );
1851  rInf.First( FirstLeft() );
1852  rInf.LeftMargin(GetLeftMargin());
1853 
1854  rInf.RealWidth( sal_uInt16(rInf.Right() - GetLeftMargin()) );
1855  rInf.Width( rInf.RealWidth() );
1856  if( const_cast<SwTextFormatter*>(this)->GetRedln() )
1857  {
1858  const_cast<SwTextFormatter*>(this)->GetRedln()->Clear( const_cast<SwTextFormatter*>(this)->GetFnt() );
1859  const_cast<SwTextFormatter*>(this)->GetRedln()->Reset();
1860  }
1861 }
1862 
1864 {
1865  m_pFirstOfBorderMerge = nullptr;
1866  m_pCurr->Truncate();
1867  m_pCurr->Init();
1868  if( pBlink && m_pCurr->IsBlinking() )
1869  pBlink->Delete( m_pCurr );
1870 
1871  // delete pSpaceAdd and pKanaComp
1874  m_pCurr->ResetFlags();
1875  FeedInf( rInf );
1876 }
1877 
1879 {
1880  if( m_pDropFormat )
1881  {
1882  const sal_uInt16 nOldDrop = GetDropHeight();
1884  m_bOnceMore = nOldDrop != GetDropHeight();
1885  }
1886  else
1887  m_bOnceMore = false;
1888  return m_bOnceMore;
1889 }
1890 
1892 {
1893  SwTwips nRet = Y() + GetLineHeight();
1894  SwTwips nMin = GetInfo().GetTextFly().GetMinBottom();
1895  if( nMin && ++nMin > nRet )
1896  {
1899  if( nRet + nDist < nMin )
1900  {
1901  const bool bRepaint = HasTruncLines() &&
1902  GetInfo().GetParaPortion()->GetRepaint().Bottom() == nRet-1;
1903  nRet = nMin - nDist;
1904  if( bRepaint )
1905  {
1906  const_cast<SwRepaint&>(GetInfo().GetParaPortion()
1907  ->GetRepaint()).Bottom( nRet-1 );
1908  const_cast<SwTextFormatInfo&>(GetInfo()).SetPaintOfst( 0 );
1909  }
1910  }
1911  }
1912  return nRet;
1913 }
1914 
1915 // FME/OD: This routine does a limited text formatting.
1917 {
1918  FormatReset( GetInfo() );
1919  BuildPortions( GetInfo() );
1920  m_pCurr->CalcLine( *this, GetInfo() );
1921  return m_pCurr->Width();
1922 }
1923 
1924 // determines if the calculation of a repaint offset is allowed
1925 // otherwise each line is painted from 0 (this is a copy of the beginning
1926 // of the former SwTextFormatter::Recycle() function
1928 {
1929  // reformat position in front of current line? Only in this case
1930  // we want to set the repaint offset
1931  bool bOptimizeRepaint = m_nStart < GetInfo().GetReformatStart() &&
1932  m_pCurr->GetLen();
1933 
1934  // a special case is the last line of a block adjusted paragraph:
1935  if ( bOptimizeRepaint )
1936  {
1937  switch( GetAdjust() )
1938  {
1939  case SvxAdjust::Block:
1940  {
1941  if( IsLastBlock() || IsLastCenter() )
1942  bOptimizeRepaint = false;
1943  else
1944  {
1945  // ????: blank in the last master line (blocksat.sdw)
1946  bOptimizeRepaint = nullptr == m_pCurr->GetNext() && !m_pFrame->GetFollow();
1947  if ( bOptimizeRepaint )
1948  {
1950  while ( pPos && !pPos->IsFlyPortion() )
1951  pPos = pPos->GetNextPortion();
1952  bOptimizeRepaint = !pPos;
1953  }
1954  }
1955  break;
1956  }
1957  case SvxAdjust::Center:
1958  case SvxAdjust::Right:
1959  bOptimizeRepaint = false;
1960  break;
1961  default: ;
1962  }
1963  }
1964 
1965  // Again another special case: invisible SoftHyphs
1966  const TextFrameIndex nReformat = GetInfo().GetReformatStart();
1967  if (bOptimizeRepaint && TextFrameIndex(COMPLETE_STRING) != nReformat)
1968  {
1969  const sal_Unicode cCh = nReformat >= TextFrameIndex(GetInfo().GetText().getLength())
1970  ? 0
1971  : GetInfo().GetText()[ sal_Int32(nReformat) ];
1972  bOptimizeRepaint = ( CH_TXTATR_BREAKWORD != cCh && CH_TXTATR_INWORD != cCh )
1973  || ! GetInfo().HasHint( nReformat );
1974  }
1975 
1976  return bOptimizeRepaint;
1977 }
1978 
1980 {
1981  OSL_ENSURE( ! m_pFrame->IsVertical() || m_pFrame->IsSwapped(),
1982  "SwTextFormatter::CalcUnclipped with unswapped frame" );
1983 
1984  long nFlyAsc, nFlyDesc;
1985  m_pCurr->MaxAscentDescent( rTop, rBottom, nFlyAsc, nFlyDesc );
1986  rTop = Y() + GetCurr()->GetAscent();
1987  rBottom = rTop + nFlyDesc;
1988  rTop -= nFlyAsc;
1989 }
1990 
1992  TextFrameIndex const nStartIdx, bool bAlways) const
1993 {
1994  OSL_ENSURE( ! m_pFrame->IsVertical() || m_pFrame->IsSwapped(),
1995  "SwTextFormatter::UpdatePos with unswapped frame" );
1996 
1997  if( GetInfo().IsTest() )
1998  return;
1999  SwLinePortion *pFirst = pCurrent->GetFirstPortion();
2000  SwLinePortion *pPos = pFirst;
2001  SwTextPaintInfo aTmpInf( GetInfo() );
2002  aTmpInf.SetpSpaceAdd( pCurrent->GetpLLSpaceAdd() );
2003  aTmpInf.ResetSpaceIdx();
2004  aTmpInf.SetKanaComp( pCurrent->GetpKanaComp() );
2005  aTmpInf.ResetKanaIdx();
2006 
2007  // The frame's size
2008  aTmpInf.SetIdx( nStartIdx );
2009  aTmpInf.SetPos( aStart );
2010 
2011  long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
2012  pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
2013 
2014  const sal_uInt16 nTmpHeight = pCurrent->GetRealHeight();
2015  sal_uInt16 nAscent = pCurrent->GetAscent() + nTmpHeight - pCurrent->Height();
2017  if( GetMulti() )
2018  {
2019  aTmpInf.SetDirection( GetMulti()->GetDirection() );
2020  if( GetMulti()->HasRotation() )
2021  {
2022  nFlags |= AsCharFlags::Rotate;
2023  if( GetMulti()->IsRevers() )
2024  {
2025  nFlags |= AsCharFlags::Reverse;
2026  aTmpInf.X( aTmpInf.X() - nAscent );
2027  }
2028  else
2029  aTmpInf.X( aTmpInf.X() + nAscent );
2030  }
2031  else
2032  {
2033  if ( GetMulti()->IsBidi() )
2034  nFlags |= AsCharFlags::Bidi;
2035  aTmpInf.Y( aTmpInf.Y() + nAscent );
2036  }
2037  }
2038  else
2039  aTmpInf.Y( aTmpInf.Y() + nAscent );
2040 
2041  while( pPos )
2042  {
2043  // We only know one case where changing the position (caused by the
2044  // adjustment) could be relevant for a portion: We need to SetRefPoint
2045  // for FlyCntPortions.
2046  if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
2047  && ( bAlways || !IsQuick() ) )
2048  {
2049  pCurrent->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
2050 
2051  if( pPos->IsGrfNumPortion() )
2052  {
2053  if( !nFlyAsc && !nFlyDesc )
2054  {
2055  nTmpAscent = nAscent;
2056  nFlyAsc = nAscent;
2057  nTmpDescent = nTmpHeight - nAscent;
2058  nFlyDesc = nTmpDescent;
2059  }
2060  static_cast<SwGrfNumPortion*>(pPos)->SetBase( nTmpAscent, nTmpDescent,
2061  nFlyAsc, nFlyDesc );
2062  }
2063  else
2064  {
2065  Point aBase( aTmpInf.GetPos() );
2066  if ( GetInfo().GetTextFrame()->IsVertical() )
2068 
2069  static_cast<SwFlyCntPortion*>(pPos)->SetBase( *aTmpInf.GetTextFrame(),
2070  aBase, nTmpAscent, nTmpDescent, nFlyAsc,
2071  nFlyDesc, nFlags );
2072  }
2073  }
2074  if( pPos->IsMultiPortion() && static_cast<SwMultiPortion*>(pPos)->HasFlyInContent() )
2075  {
2076  OSL_ENSURE( !GetMulti(), "Too much multi" );
2077  const_cast<SwTextFormatter*>(this)->m_pMulti = static_cast<SwMultiPortion*>(pPos);
2078  SwLineLayout *pLay = &GetMulti()->GetRoot();
2079  Point aSt( aTmpInf.X(), aStart.Y() );
2080 
2081  if ( GetMulti()->HasBrackets() )
2082  {
2083  OSL_ENSURE( GetMulti()->IsDouble(), "Brackets only for doubles");
2084  aSt.AdjustX(static_cast<SwDoubleLinePortion*>(GetMulti())->PreWidth() );
2085  }
2086  else if( GetMulti()->HasRotation() )
2087  {
2088  aSt.AdjustY(pCurrent->GetAscent() - GetMulti()->GetAscent() );
2089  if( GetMulti()->IsRevers() )
2090  aSt.AdjustX(GetMulti()->Width() );
2091  else
2092  aSt.AdjustY(GetMulti()->Height() );
2093  }
2094  else if ( GetMulti()->IsBidi() )
2095  // jump to end of the bidi portion
2096  aSt.AdjustX(pLay->Width() );
2097 
2098  TextFrameIndex nStIdx = aTmpInf.GetIdx();
2099  do
2100  {
2101  UpdatePos( pLay, aSt, nStIdx, bAlways );
2102  nStIdx = nStIdx + pLay->GetLen();
2103  aSt.AdjustY(pLay->Height() );
2104  pLay = pLay->GetNext();
2105  } while ( pLay );
2106  const_cast<SwTextFormatter*>(this)->m_pMulti = nullptr;
2107  }
2108  pPos->Move( aTmpInf );
2109  pPos = pPos->GetNextPortion();
2110  }
2111 }
2112 
2113 void SwTextFormatter::AlignFlyInCntBase( long nBaseLine ) const
2114 {
2115  OSL_ENSURE( ! m_pFrame->IsVertical() || m_pFrame->IsSwapped(),
2116  "SwTextFormatter::AlignFlyInCntBase with unswapped frame" );
2117 
2118  if( GetInfo().IsTest() )
2119  return;
2120  SwLinePortion *pFirst = m_pCurr->GetFirstPortion();
2121  SwLinePortion *pPos = pFirst;
2122  AsCharFlags nFlags = AsCharFlags::None;
2123  if( GetMulti() && GetMulti()->HasRotation() )
2124  {
2125  nFlags |= AsCharFlags::Rotate;
2126  if( GetMulti()->IsRevers() )
2127  nFlags |= AsCharFlags::Reverse;
2128  }
2129 
2130  long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
2131 
2132  while( pPos )
2133  {
2134  if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() )
2135  {
2136  m_pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, pPos );
2137 
2138  if( pPos->IsGrfNumPortion() )
2139  static_cast<SwGrfNumPortion*>(pPos)->SetBase( nTmpAscent, nTmpDescent,
2140  nFlyAsc, nFlyDesc );
2141  else
2142  {
2143  Point aBase;
2144  if ( GetInfo().GetTextFrame()->IsVertical() )
2145  {
2146  nBaseLine = GetInfo().GetTextFrame()->SwitchHorizontalToVertical( nBaseLine );
2147  aBase = Point( nBaseLine, static_cast<SwFlyCntPortion*>(pPos)->GetRefPoint().Y() );
2148  }
2149  else
2150  aBase = Point( static_cast<SwFlyCntPortion*>(pPos)->GetRefPoint().X(), nBaseLine );
2151 
2152  static_cast<SwFlyCntPortion*>(pPos)->SetBase( *GetInfo().GetTextFrame(), aBase, nTmpAscent, nTmpDescent,
2153  nFlyAsc, nFlyDesc, nFlags );
2154  }
2155  }
2156  pPos = pPos->GetNextPortion();
2157  }
2158 }
2159 
2161 {
2162  OSL_ENSURE( rInf.GetTextFly().IsOn(), "SwTextFormatter::ChkFlyUnderflow: why?" );
2163  if( GetCurr() )
2164  {
2165  // First we check, whether a fly overlaps with the line.
2166  // = GetLineHeight()
2167  const sal_uInt16 nHeight = GetCurr()->GetRealHeight();
2168  SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight );
2169 
2170  SwRect aLineVert( aLine );
2171  if ( m_pFrame->IsVertical() )
2172  m_pFrame->SwitchHorizontalToVertical( aLineVert );
2173  SwRect aInter( rInf.GetTextFly().GetFrame( aLineVert ) );
2174  if ( m_pFrame->IsVertical() )
2176 
2177  if( !aInter.HasArea() )
2178  return false;
2179 
2180  // We now check every portion that could have lowered for overlapping
2181  // with the fly.
2182  const SwLinePortion *pPos = GetCurr()->GetFirstPortion();
2183  aLine.Pos().setY( Y() + GetCurr()->GetRealHeight() - GetCurr()->Height() );
2184  aLine.Height( GetCurr()->Height() );
2185 
2186  while( pPos )
2187  {
2188  aLine.Width( pPos->Width() );
2189 
2190  aLineVert = aLine;
2191  if ( m_pFrame->IsVertical() )
2192  m_pFrame->SwitchHorizontalToVertical( aLineVert );
2193  aInter = rInf.GetTextFly().GetFrame( aLineVert );
2194  if ( m_pFrame->IsVertical() )
2196 
2197  // New flys from below?
2198  if( !pPos->IsFlyPortion() )
2199  {
2200  if( aInter.IsOver( aLine ) )
2201  {
2202  aInter.Intersection_( aLine );
2203  if( aInter.HasArea() )
2204  {
2205  // To be evaluated during reformat of this line:
2206  // RealHeight including spacing
2207  rInf.SetLineHeight( nHeight );
2208  // Height without extra spacing
2209  rInf.SetLineNetHeight( m_pCurr->Height() );
2210  return true;
2211  }
2212  }
2213  }
2214  else
2215  {
2216  // The fly portion is not intersected by a fly anymore
2217  if ( ! aInter.IsOver( aLine ) )
2218  {
2219  rInf.SetLineHeight( nHeight );
2220  rInf.SetLineNetHeight( m_pCurr->Height() );
2221  return true;
2222  }
2223  else
2224  {
2225  aInter.Intersection_( aLine );
2226 
2227  // No area means a fly has become invalid because of
2228  // lowering the line => reformat the line
2229  // we also have to reformat the line, if the fly size
2230  // differs from the intersection interval's size.
2231  if( ! aInter.HasArea() ||
2232  static_cast<const SwFlyPortion*>(pPos)->GetFixWidth() != aInter.Width() )
2233  {
2234  rInf.SetLineHeight( nHeight );
2235  rInf.SetLineNetHeight( m_pCurr->Height() );
2236  return true;
2237  }
2238  }
2239  }
2240 
2241  aLine.Left( aLine.Left() + pPos->Width() );
2242  pPos = pPos->GetNextPortion();
2243  }
2244  }
2245  return false;
2246 }
2247 
2249 {
2250  if( GetMulti() || rInf.GetFly() )
2251  return;
2252 
2253  SwTextFly& rTextFly = rInf.GetTextFly();
2254  if( !rTextFly.IsOn() || rInf.IsIgnoreFly() )
2255  return;
2256 
2257  const SwLinePortion *pLast = rInf.GetLast();
2258 
2259  long nAscent;
2260  long nTop = Y();
2261  long nHeight;
2262 
2263  if( rInf.GetLineHeight() )
2264  {
2265  // Real line height has already been calculated, we only have to
2266  // search for intersections in the lower part of the strip
2267  nAscent = m_pCurr->GetAscent();
2268  nHeight = rInf.GetLineNetHeight();
2269  nTop += rInf.GetLineHeight() - nHeight;
2270  }
2271  else
2272  {
2273  // We make a first guess for the lines real height
2274  if ( ! m_pCurr->GetRealHeight() )
2275  CalcRealHeight();
2276 
2277  nAscent = pLast->GetAscent();
2278  nHeight = pLast->Height();
2279 
2280  if ( m_pCurr->GetRealHeight() > nHeight )
2281  nTop += m_pCurr->GetRealHeight() - nHeight;
2282  else
2283  // Important for fixed space between lines
2284  nHeight = m_pCurr->GetRealHeight();
2285  }
2286 
2287  const long nLeftMar = GetLeftMargin();
2288  const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin();
2289 
2290  SwRect aLine( rInf.X() + nLeftMin, nTop, rInf.RealWidth() - rInf.X()
2291  + nLeftMar - nLeftMin , nHeight );
2292 
2293  // tdf#116486: consider also the upper margin from getFramePrintArea because intersections
2294  // with this additional space should lead to repositioning of paragraphs
2295  // For compatibility we grab a related compat flag:
2297  {
2298  const long nUpper = m_pFrame->getFramePrintArea().Top();
2299  // Increase the rectangle
2300  if( nUpper > 0 && nTop >= nUpper )
2301  aLine.SubTop( nUpper );
2302  }
2303  SwRect aLineVert( aLine );
2304  if ( m_pFrame->IsRightToLeft() )
2305  m_pFrame->SwitchLTRtoRTL( aLineVert );
2306 
2307  if ( m_pFrame->IsVertical() )
2308  m_pFrame->SwitchHorizontalToVertical( aLineVert );
2309 
2310  // GetFrame(...) determines and returns the intersection rectangle
2311  SwRect aInter( rTextFly.GetFrame( aLineVert ) );
2312 
2313  if ( m_pFrame->IsRightToLeft() )
2314  m_pFrame->SwitchRTLtoLTR( aInter );
2315 
2316  if ( m_pFrame->IsVertical() )
2318 
2319  if (!aInter.IsEmpty() && aInter.Bottom() < nTop)
2320  {
2321  // Intersects with the frame area (with upper margin), but not with the print area (without
2322  // upper margin). Don't reserve space for the fly portion in this case, text is allowed to
2323  // flow there.
2324  aInter.Height(0);
2325  }
2326 
2327  if( !aInter.IsOver( aLine ) )
2328  return;
2329 
2330  aLine.Left( rInf.X() + nLeftMar );
2331  bool bForced = false;
2332  if( aInter.Left() <= nLeftMin )
2333  {
2334  SwTwips nFrameLeft = GetTextFrame()->getFrameArea().Left();
2335  if( GetTextFrame()->getFramePrintArea().Left() < 0 )
2336  nFrameLeft += GetTextFrame()->getFramePrintArea().Left();
2337  if( aInter.Left() < nFrameLeft )
2338  aInter.Left( nFrameLeft );
2339 
2340  long nAddMar = 0;
2341  if ( m_pFrame->IsRightToLeft() )
2342  {
2343  nAddMar = m_pFrame->getFrameArea().Right() - Right();
2344  if ( nAddMar < 0 )
2345  nAddMar = 0;
2346  }
2347  else
2348  nAddMar = nLeftMar - nFrameLeft;
2349 
2350  aInter.Width( aInter.Width() + nAddMar );
2351  // For a negative first line indent, we set this flag to show
2352  // that the indentation/margin has been moved.
2353  // This needs to be respected by the DefaultTab at the zero position.
2354  if( IsFirstTextLine() && HasNegFirst() )
2355  bForced = true;
2356  }
2357  aInter.Intersection( aLine );
2358  if( !aInter.HasArea() )
2359  return;
2360 
2361  const bool bFullLine = aLine.Left() == aInter.Left() &&
2362  aLine.Right() == aInter.Right();
2363 
2364  // Although no text is left, we need to format another line,
2365  // because also empty lines need to avoid a Fly with no wrapping.
2366  if (bFullLine && rInf.GetIdx() == TextFrameIndex(rInf.GetText().getLength()))
2367  {
2368  rInf.SetNewLine( true );
2369  // We know that for dummies, it holds ascent == height
2370  m_pCurr->SetDummy(true);
2371  }
2372 
2373  // aInter becomes frame-local
2374  aInter.Pos().AdjustX( -nLeftMar );
2375  SwFlyPortion *pFly = new SwFlyPortion( aInter );
2376  if( bForced )
2377  {
2379  rInf.ForcedLeftMargin( static_cast<sal_uInt16>(aInter.Width()) );
2380  }
2381 
2382  if( bFullLine )
2383  {
2384  // In order to properly flow around Flys with different
2385  // wrapping attributes, we need to increase by units of line height.
2386  // The last avoiding line should be adjusted in height, so that
2387  // we don't get a frame spacing effect.
2388  // It is important that ascent == height, because the FlyPortion
2389  // values are transferred to pCurr in CalcLine and IsDummy() relies
2390  // on this behaviour.
2391  // To my knowledge we only have two places where DummyLines can be
2392  // created: here and in MakeFlyDummies.
2393  // IsDummy() is evaluated in IsFirstTextLine(), when moving lines
2394  // and in relation with DropCaps.
2395  pFly->Height( sal_uInt16(aInter.Height()) );
2396 
2397  // nNextTop now contains the margin's bottom edge, which we avoid
2398  // or the next margin's top edge, which we need to respect.
2399  // That means we can comfortably grow up to this value; that's how
2400  // we save a few empty lines.
2401  long nNextTop = rTextFly.GetNextTop();
2402  if ( m_pFrame->IsVertical() )
2403  nNextTop = m_pFrame->SwitchVerticalToHorizontal( nNextTop );
2404  if( nNextTop > aInter.Bottom() )
2405  {
2406  SwTwips nH = nNextTop - aInter.Top();
2407  if( nH < SAL_MAX_UINT16 )
2408  pFly->Height( sal_uInt16( nH ) );
2409  }
2410  if( nAscent < pFly->Height() )
2411  pFly->SetAscent( sal_uInt16(nAscent) );
2412  else
2413  pFly->SetAscent( pFly->Height() );
2414  }
2415  else
2416  {
2417  if (rInf.GetIdx() == TextFrameIndex(rInf.GetText().getLength()))
2418  {
2419  // Don't use nHeight, or we have a huge descent
2420  pFly->Height( pLast->Height() );
2421  pFly->SetAscent( pLast->GetAscent() );
2422  }
2423  else
2424  {
2425  pFly->Height( sal_uInt16(aInter.Height()) );
2426  if( nAscent < pFly->Height() )
2427  pFly->SetAscent( sal_uInt16(nAscent) );
2428  else
2429  pFly->SetAscent( pFly->Height() );
2430  }
2431  }
2432 
2433  rInf.SetFly( pFly );
2434 
2435  if( pFly->GetFix() < rInf.Width() )
2436  rInf.Width( pFly->GetFix() );
2437 
2438  SwTextGridItem const*const pGrid(GetGridItem(m_pFrame->FindPageFrame()));
2439  if ( !pGrid )
2440  return;
2441 
2442  const SwPageFrame* pPageFrame = m_pFrame->FindPageFrame();
2443  const SwLayoutFrame* pBody = pPageFrame->FindBodyCont();
2444 
2445  SwRectFnSet aRectFnSet(pPageFrame);
2446 
2447  const long nGridOrigin = pBody ?
2448  aRectFnSet.GetPrtLeft(*pBody) :
2449  aRectFnSet.GetPrtLeft(*pPageFrame);
2450 
2451  const SwDoc & rDoc = rInf.GetTextFrame()->GetDoc();
2452  const sal_uInt16 nGridWidth = GetGridWidth(*pGrid, rDoc);
2453 
2454  SwTwips nStartX = GetLeftMargin();
2455  if ( aRectFnSet.IsVert() )
2456  {
2457  Point aPoint( nStartX, 0 );
2459  nStartX = aPoint.Y();
2460  }
2461 
2462  const SwTwips nOfst = nStartX - nGridOrigin;
2463  const SwTwips nTmpWidth = rInf.Width() + nOfst;
2464 
2465  const sal_uLong i = nTmpWidth / nGridWidth + 1;
2466 
2467  const long nNewWidth = ( i - 1 ) * nGridWidth - nOfst;
2468  if ( nNewWidth > 0 )
2469  rInf.Width( static_cast<sal_uInt16>(nNewWidth) );
2470  else
2471  rInf.Width( 0 );
2472 
2473 
2474 }
2475 
2477  SwTextAttr *pHint ) const
2478 {
2479  const SwFrame *pFrame = m_pFrame;
2480 
2481  SwFlyInContentFrame *pFly;
2482  SwFrameFormat* pFrameFormat = static_cast<SwTextFlyCnt*>(pHint)->GetFlyCnt().GetFrameFormat();
2483  if( RES_FLYFRMFMT == pFrameFormat->Which() )
2484  pFly = static_cast<SwTextFlyCnt*>(pHint)->GetFlyFrame(pFrame);
2485  else
2486  pFly = nullptr;
2487  // aBase is the document-global position, from which the new extra portion is placed
2488  // aBase.X() = Offset in the line after the current position
2489  // aBase.Y() = LineIter.Y() + Ascent of the current position
2490 
2491  long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc;
2492  // i#11859 - use new method <SwLineLayout::MaxAscentDescent(..)>
2493  // to change line spacing behaviour at paragraph - Compatibility to MS Word
2494  //SwLinePortion *pPos = pCurr->GetFirstPortion();
2495  //lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
2496  m_pCurr->MaxAscentDescent( nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc );
2497 
2498  // If the ascent of the frame is larger than the ascent of the current position,
2499  // we use this one when calculating the base, or the frame would be positioned
2500  // too much to the top, sliding down after all causing a repaint in an area
2501  // he actually never was in.
2502  sal_uInt16 nAscent = 0;
2503 
2504  const bool bTextFrameVertical = GetInfo().GetTextFrame()->IsVertical();
2505 
2506  const bool bUseFlyAscent = pFly && pFly->isFrameAreaPositionValid() &&
2507  0 != ( bTextFrameVertical ?
2508  pFly->GetRefPoint().X() :
2509  pFly->GetRefPoint().Y() );
2510 
2511  if ( bUseFlyAscent )
2512  nAscent = static_cast<sal_uInt16>( std::abs( int( bTextFrameVertical ?
2513  pFly->GetRelPos().X() :
2514  pFly->GetRelPos().Y() ) ) );
2515 
2516  // Check if be prefer to use the ascent of the last portion:
2517  if ( IsQuick() ||
2518  !bUseFlyAscent ||
2519  nAscent < rInf.GetLast()->GetAscent() )
2520  {
2521  nAscent = rInf.GetLast()->GetAscent();
2522  }
2523  else if( nAscent > nFlyAsc )
2524  nFlyAsc = nAscent;
2525 
2526  Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent );
2528  if( GetMulti() && GetMulti()->HasRotation() )
2529  {
2530  nMode |= AsCharFlags::Rotate;
2531  if( GetMulti()->IsRevers() )
2532  nMode |= AsCharFlags::Reverse;
2533  }
2534 
2535  Point aTmpBase( aBase );
2536  if ( GetInfo().GetTextFrame()->IsVertical() )
2538 
2539  SwFlyCntPortion* pRet(nullptr);
2540  if( pFly )
2541  {
2542  pRet = sw::FlyContentPortion::Create(*GetInfo().GetTextFrame(), pFly, aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode);
2543  // We need to make sure that our font is set again in the OutputDevice
2544  // It could be that the FlyInCnt was added anew and GetFlyFrame() would
2545  // in turn cause, that it'd be created anew again.
2546  // This one's frames get formatted right away, which change the font.
2547  rInf.SelectFont();
2548  if( pRet->GetAscent() > nAscent )
2549  {
2550  aBase.setY( Y() + pRet->GetAscent() );
2551  nMode |= AsCharFlags::UlSpace;
2552  if( !rInf.IsTest() )
2553  {
2554  aTmpBase = aBase;
2555  if ( GetInfo().GetTextFrame()->IsVertical() )
2557 
2558  pRet->SetBase( *rInf.GetTextFrame(), aTmpBase, nTmpAscent,
2559  nTmpDescent, nFlyAsc, nFlyDesc, nMode );
2560  }
2561  }
2562  }
2563  else
2564  {
2565  pRet = sw::DrawFlyCntPortion::Create(*rInf.GetTextFrame(), *pFrameFormat, aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode);
2566  }
2567  return pRet;
2568 }
2569 
2570 /* Drop portion is a special case, because it has parts which aren't portions
2571  but we have handle them just like portions */
2573 {
2574  if( rPortion.GetLines() > 1 )
2575  {
2576  SwDropPortionPart* pCurrPart = rPortion.GetPart();
2577  while( pCurrPart )
2578  {
2579  if( pCurrPart->GetFollow() &&
2580  ::lcl_HasSameBorder(pCurrPart->GetFont(), pCurrPart->GetFollow()->GetFont()) )
2581  {
2582  pCurrPart->SetJoinBorderWithNext(true);
2583  pCurrPart->GetFollow()->SetJoinBorderWithPrev(true);
2584  }
2585  pCurrPart = pCurrPart->GetFollow();
2586  }
2587  }
2588 }
2589 
2591 {
2592  const SwFont aCurFont = *rInf.GetFont();
2593  if( aCurFont.HasBorder() )
2594  {
2595  if (pPrev && pPrev->GetJoinBorderWithNext() )
2596  {
2597  // In some case border merge is called twice to the portion
2598  if( !rPortion.GetJoinBorderWithPrev() )
2599  {
2600  rPortion.SetJoinBorderWithPrev(true);
2601  if( rPortion.InTextGrp() && rPortion.Width() > aCurFont.GetLeftBorderSpace() )
2602  rPortion.Width(rPortion.Width() - aCurFont.GetLeftBorderSpace());
2603  }
2604  }
2605  else
2606  {
2607  rPortion.SetJoinBorderWithPrev(false);
2608  m_pFirstOfBorderMerge = &rPortion;
2609  }
2610 
2611  // Get next portion's font
2612  bool bSeek = false;
2613  if (!rInf.IsFull() && // Not the last portion of the line (in case of line break)
2614  rInf.GetIdx() + rPortion.GetLen() != TextFrameIndex(rInf.GetText().getLength())) // Not the last portion of the paragraph
2615  {
2616  bSeek = Seek(rInf.GetIdx() + rPortion.GetLen());
2617  }
2618  // Don't join the next portion if SwKernPortion sits between two different boxes.
2619  bool bDisconnect = rPortion.IsKernPortion() && !rPortion.GetJoinBorderWithPrev();
2620  // If next portion has the same border then merge
2621  if( bSeek && GetFnt()->HasBorder() && ::lcl_HasSameBorder(aCurFont, *GetFnt()) && !bDisconnect )
2622  {
2623  // In some case border merge is called twice to the portion
2624  if( !rPortion.GetJoinBorderWithNext() )
2625  {
2626  rPortion.SetJoinBorderWithNext(true);
2627  if( rPortion.InTextGrp() && rPortion.Width() > aCurFont.GetRightBorderSpace() )
2628  rPortion.Width(rPortion.Width() - aCurFont.GetRightBorderSpace());
2629  }
2630  }
2631  // If this is the last portion of the merge group then make the real height merge
2632  else
2633  {
2634  rPortion.SetJoinBorderWithNext(false);
2635  if( m_pFirstOfBorderMerge != &rPortion )
2636  {
2637  // Calculate maximum height and ascent
2639  sal_uInt16 nMaxAscent = 0;
2640  sal_uInt16 nMaxHeight = 0;
2641  bool bReachCurrent = false;
2642  while( pActPor )
2643  {
2644  if( nMaxHeight < pActPor->Height() )
2645  nMaxHeight = pActPor->Height();
2646  if( nMaxAscent < pActPor->GetAscent() )
2647  nMaxAscent = pActPor->GetAscent();
2648 
2649  pActPor = pActPor->GetNextPortion();
2650  if( !pActPor && !bReachCurrent )
2651  {
2652  pActPor = &rPortion;
2653  bReachCurrent = true;
2654  }
2655  }
2656 
2657  // Change all portion's height and ascent
2658  pActPor = m_pFirstOfBorderMerge;
2659  bReachCurrent = false;
2660  while( pActPor )
2661  {
2662  if( nMaxHeight > pActPor->Height() )
2663  pActPor->Height(nMaxHeight);
2664  if( nMaxAscent > pActPor->GetAscent() )
2665  pActPor->SetAscent(nMaxAscent);
2666 
2667  pActPor = pActPor->GetNextPortion();
2668  if( !pActPor && !bReachCurrent )
2669  {
2670  pActPor = &rPortion;
2671  bReachCurrent = true;
2672  }
2673  }
2674  m_pFirstOfBorderMerge = nullptr;
2675  }
2676  }
2677  Seek(rInf.GetIdx());
2678  }
2679 }
2680 
2681 namespace {
2682  // calculates and sets optimal repaint offset for the current line
2683  long lcl_CalcOptRepaint( SwTextFormatter &rThis,
2684  SwLineLayout const &rCurr,
2685  TextFrameIndex const nOldLineEnd,
2686  const std::vector<long> &rFlyStarts )
2687  {
2688  SwTextFormatInfo& txtFormatInfo = rThis.GetInfo();
2689  if ( txtFormatInfo.GetIdx() < txtFormatInfo.GetReformatStart() )
2690  // the reformat position is behind our new line, that means
2691  // something of our text has moved to the next line
2692  return 0;
2693 
2694  TextFrameIndex nReformat = std::min(txtFormatInfo.GetReformatStart(), nOldLineEnd);
2695 
2696  // in case we do not have any fly in our line, our repaint position
2697  // is the changed position - 1
2698  if ( rFlyStarts.empty() && ! rCurr.IsFly() )
2699  {
2700  // this is the maximum repaint offset determined during formatting
2701  // for example: the beginning of the first right tab stop
2702  // if this value is 0, this means that we do not have an upper
2703  // limit for the repaint offset
2704  const long nFormatRepaint = txtFormatInfo.GetPaintOfst();
2705 
2706  if (nReformat < txtFormatInfo.GetLineStart() + TextFrameIndex(3))
2707  return 0;
2708 
2709  // step back two positions for smoother repaint
2710  nReformat -= TextFrameIndex(2);
2711 
2712  // i#28795, i#34607, i#38388
2713  // step back more characters, this is required by complex scripts
2714  // e.g., for Khmer (thank you, Javier!)
2715  static const TextFrameIndex nMaxContext(10);
2716  if (nReformat > txtFormatInfo.GetLineStart() + nMaxContext)
2717  nReformat = nReformat - nMaxContext;
2718  else
2719  {
2720  nReformat = txtFormatInfo.GetLineStart();
2721  //reset the margin flag - prevent loops
2723  }
2724 
2725  // Weird situation: Our line used to end with a hole portion
2726  // and we delete some characters at the end of our line. We have
2727  // to take care for repainting the blanks which are not anymore
2728  // covered by the hole portion
2729  while ( nReformat > txtFormatInfo.GetLineStart() &&
2730  CH_BLANK == txtFormatInfo.GetChar( nReformat ) )
2731  --nReformat;
2732 
2733  OSL_ENSURE( nReformat < txtFormatInfo.GetIdx(), "Reformat too small for me!" );
2734  SwRect aRect;
2735 
2736  // Note: GetChareRect is not const. It definitely changes the
2737  // bMulti flag. We have to save and restore the old value.
2738  bool bOldMulti = txtFormatInfo.IsMulti();
2739  rThis.GetCharRect( &aRect, nReformat );
2740  txtFormatInfo.SetMulti( bOldMulti );
2741 
2742  return nFormatRepaint ? std::min( aRect.Left(), nFormatRepaint ) :
2743  aRect.Left();
2744  }
2745  else
2746  {
2747  // nReformat may be wrong, if something around flys has changed:
2748  // we compare the former and the new fly positions in this line
2749  // if anything has changed, we carefully have to adjust the right
2750  // repaint position
2751  long nPOfst = 0;
2752  size_t nCnt = 0;
2753  long nX = 0;
2754  TextFrameIndex nIdx = rThis.GetInfo().GetLineStart();
2755  SwLinePortion* pPor = rCurr.GetFirstPortion();
2756 
2757  while ( pPor )
2758  {
2759  if ( pPor->IsFlyPortion() )
2760  {
2761  // compare start of fly with former start of fly
2762  if (nCnt < rFlyStarts.size() &&
2763  nX == rFlyStarts[ nCnt ] &&
2764  nIdx < nReformat
2765  )
2766  // found fix position, nothing has changed left from nX
2767  nPOfst = nX + pPor->Width();
2768  else
2769  break;
2770 
2771  nCnt++;
2772  }
2773  nX = nX + pPor->Width();
2774  nIdx = nIdx + pPor->GetLen();
2775  pPor = pPor->GetNextPortion();
2776  }
2777 
2778  return nPOfst + rThis.GetLeftMargin();
2779  }
2780  }
2781 
2782  // Determine if we need to build hidden portions
2783  bool lcl_BuildHiddenPortion(const SwTextSizeInfo& rInf, TextFrameIndex & rPos)
2784  {
2785  // Only if hidden text should not be shown:
2786  // if ( rInf.GetVsh() && rInf.GetVsh()->GetWin() && rInf.GetOpt().IsShowHiddenChar() )
2787  const bool bShowInDocView = rInf.GetVsh() && rInf.GetVsh()->GetWin() && rInf.GetOpt().IsShowHiddenChar();
2788  const bool bShowForPrinting = rInf.GetOpt().IsShowHiddenChar( true ) && rInf.GetOpt().IsPrinting();
2789  if (bShowInDocView || bShowForPrinting)
2790  return false;
2791 
2792  const SwScriptInfo& rSI = rInf.GetParaPortion()->GetScriptInfo();
2793  TextFrameIndex nHiddenStart;
2794  TextFrameIndex nHiddenEnd;
2795  rSI.GetBoundsOfHiddenRange( rPos, nHiddenStart, nHiddenEnd );
2796  if ( nHiddenEnd )
2797  {
2798  rPos = nHiddenEnd;
2799  return true;
2800  }
2801 
2802  return false;
2803  }
2804 
2805  bool lcl_HasSameBorder(const SwFont& rFirst, const SwFont& rSecond)
2806  {
2807  return
2808  rFirst.GetTopBorder() == rSecond.GetTopBorder() &&
2809  rFirst.GetBottomBorder() == rSecond.GetBottomBorder() &&
2810  rFirst.GetLeftBorder() == rSecond.GetLeftBorder() &&
2811  rFirst.GetRightBorder() == rSecond.GetRightBorder() &&
2812  rFirst.GetTopBorderDist() == rSecond.GetTopBorderDist() &&
2813  rFirst.GetBottomBorderDist() == rSecond.GetBottomBorderDist() &&
2814  rFirst.GetLeftBorderDist() == rSecond.GetLeftBorderDist() &&
2815  rFirst.GetRightBorderDist() == rSecond.GetRightBorderDist() &&
2816  rFirst.GetOrientation() == rSecond.GetOrientation() &&
2817  rFirst.GetShadowColor() == rSecond.GetShadowColor() &&
2818  rFirst.GetShadowWidth() == rSecond.GetShadowWidth() &&
2819  rFirst.GetShadowLocation() == rSecond.GetShadowLocation();
2820  }
2821 
2822 } //end unnamed namespace
2823 
2824 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool Format(SwTextFormatInfo &rInf)
Definition: porlin.cxx:241
void SetLineNetHeight(const sal_uInt16 nNew)
Definition: inftxt.hxx:602
bool IsParaLine() const
Definition: itrtxt.hxx:125
SwScriptInfo * m_pScriptInfo
Definition: itratr.hxx:40
std::deque< sal_uInt16 > * GetpKanaComp() const
Definition: porlay.hxx:184
Base class of the Writer layout elements.
Definition: frame.hxx:295
void Move(SwTextPaintInfo &rInf)
Definition: porlin.cxx:272
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
bool LastKernPortion()
Definition: inftxt.cxx:1680
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
bool IsArrowDone() const
Definition: inftxt.hxx:636
SwTwips GetMinBottom() const
Definition: txtfly.hxx:336
SwCharFormat * GetAnchorCharFormat(SwDoc &rDoc) const
Definition: docftn.cxx:183
const SwFormatDrop * m_pDropFormat
Definition: itrform2.hxx:35
void SetRest(const bool bNew)
Definition: porlay.hxx:118
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout...
Definition: txtfrm.cxx:590
bool IsRegisterOn() const
Definition: itrtxt.hxx:94
sal_uInt16 GetLeftBorderSpace() const
Definition: swfont.hxx:908
sal_uInt16 GetShadowWidth() const
Definition: swfont.hxx:378
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:724
void FormatReset(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:1863
SwViewShell * GetVsh()
Definition: inftxt.hxx:228
bool IsFollow() const
Definition: flowfrm.hxx:166
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
void SetArrowDone(const bool bNew)
Definition: inftxt.hxx:637
void SetFormatAdj(const bool bNew)
Definition: porlay.hxx:110
sal_uInt16 GetPropLineSpace() const
bool IsGrfNumPortion() const
Definition: porlin.hxx:111
Marks a position in the document model.
Definition: pam.hxx:35
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1426
static FlyContentPortion * Create(const SwTextFrame &rFrame, SwFlyInContentFrame *pFly, const Point &rBase, long nAscent, long nDescent, long nFlyAsc, long nFlyDesc, AsCharFlags nFlags)
Definition: porfly.cxx:275
sal_uInt16 GetLines() const
Definition: pordrop.hxx:88
bool IsUnderflow() const
Definition: inftxt.hxx:588
void SetFly(const bool bNew)
Definition: porlay.hxx:116
SwFlyCntPortion * NewFlyCntPortion(SwTextFormatInfo &rInf, SwTextAttr *pHt) const
Sets a new portion for an object anchored as character.
Definition: itrform2.cxx:2476
bool IsRest() const
Definition: porlay.hxx:119
sal_uInt16 Height() const
Definition: possiz.hxx:44
SwTwips GetPaintOfst() const
Definition: inftxt.hxx:736
SwFont * GetFont()
Definition: inftxt.hxx:238
SwLineLayout * GetNext()
Definition: porlay.hxx:143
bool IsSwapped() const
Definition: txtfrm.hxx:524
bool SeekStartAndChg(SwTextSizeInfo &rInf, const bool bPara=false)
Definition: itrtxt.hxx:323
bool InNumberGrp() const
Definition: porlin.hxx:102
const SwFormatDrop * GetDropFormat() const
Definition: itrform2.hxx:196
bool IsUnderlineBreak(const SwLinePortion &rPor, const SwFont &rFnt)
Definition: itrpaint.cxx:62
void InsertPortion(SwTextFormatInfo &rInf, SwLinePortion *pPor)
Definition: itrform2.cxx:300
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
bool IsPrinting() const
Definition: viewopt.hxx:384
bool IsNewLine() const
Definition: itrform2.hxx:177
void SetPos(const Point &rNew)
Definition: inftxt.hxx:436
void SetFootnoteInside(const bool bNew)
Definition: inftxt.hxx:207
TextFrameIndex NextHiddenChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1479
bool IsInFootnote() const
Definition: frame.hxx:925
sal_uInt16 GetTopBorderDist() const
Definition: swfont.hxx:359
bool GetJoinBorderWithPrev() const
Definition: porlin.hxx:168
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:483
sal_uInt16 GetRightBorderSpace() const
Definition: swfont.hxx:893
bool IsRuby() const
Definition: inftxt.hxx:214
static void MergeCharacterBorder(SwDropPortion const &rPortion)
Merge border of the drop portion with modifying the font of the portions' part.
Definition: itrform2.cxx:2572
sal_Unicode GetTabDecimal() const
Definition: inftxt.hxx:622
void CtorInitTextPainter(SwTextFrame *pFrame, SwTextPaintInfo *pInf)
Definition: itrpaint.cxx:79
sal_uInt8 GetLines() const
Definition: paratr.hxx:86
sal_uIntPtr sal_uLong
void SetFootnoteNum(const bool bNew)
Definition: porlay.hxx:297
const SwRect & getFramePrintArea() const
Definition: frame.hxx:176
bool IsStop() const
Definition: itrform2.hxx:174
bool IsFirstTextLine() const
Definition: itrtxt.hxx:120
SwTabPortion * NewTabPortion(SwTextFormatInfo &rInf, bool bAuto) const
Definition: txttab.cxx:65
The purpose of this class is to be the universal interface between formatting/text output and the pos...
Definition: txtfly.hxx:119
void SetLast(SwLinePortion *pNewLast)
Definition: inftxt.hxx:567
SwTabPortion * GetLastTab()
Definition: inftxt.hxx:620
TextFrameIndex GetUnderScorePos() const
Definition: inftxt.hxx:644
SwTwips Left() const
Definition: inftxt.hxx:547
TextFrameIndex ScanPortionEnd(TextFrameIndex nStart, TextFrameIndex nEnd)
Definition: inftxt.cxx:1587
Definition: doc.hxx:185
#define ODF_FORMCHECKBOX
void CalcLine(SwTextFormatter &rLine, SwTextFormatInfo &rInf)
Definition: porlay.cxx:332
sal_uInt16 GetDropHeight() const
Definition: itrtxt.hxx:205
const SwLineLayout & GetRoot() const
Definition: pormulti.hxx:121
bool IsNumDone() const
Definition: inftxt.hxx:634
sal_uInt16 GetTextHeight() const
Definition: inftxt.hxx:717
void Height(long nNew)
Definition: swrect.hxx:189
bool IsErgoDone() const
Definition: inftxt.hxx:632
TextFrameIndex GetOfst() const
Definition: txtfrm.hxx:426
sal_uInt16 GetLineNetHeight() const
Definition: inftxt.hxx:601
#define CHAR_HARDBLANK
Definition: swtypes.hxx:172
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:75
bool GetRubyTextBelow() const
Definition: tgrditem.hxx:85
TextFrameIndex GetNextAttr() const
Definition: itratr.cxx:732
#define DIR_TOP2BOTTOM
Definition: inftxt.hxx:57
SwFont * m_pFont
Definition: itratr.hxx:39
bool SeekAndChg(SwTextSizeInfo &rInf)
Definition: itrtxt.hxx:310
long SwTwips
Definition: swtypes.hxx:49
void LeftMargin(const SwTwips nNew)
Definition: inftxt.hxx:553
bool HasBorder() const
Check whether font has any border on any side.
Definition: swfont.hxx:923
SwDropPortionPart * GetPart() const
Definition: pordrop.hxx:94
void SetFlyInCntBase(bool bNew=true)
Definition: itrform2.hxx:211
bool IsVert() const
Definition: frame.hxx:1343
static void SetRightMargin(const bool bNew)
Definition: itrtxt.hxx:294
const SwLineLayout * Next()
Definition: itrtxt.cxx:109
sal_uInt16 RealWidth() const
Definition: inftxt.hxx:554
SwLineInfo m_aLineInf
Definition: itrtxt.hxx:33
SwTwips FirstLeft() const
Definition: itrtxt.hxx:182
bool IsEndNote() const
Definition: fmtftn.hxx:74
Dialog to specify the properties of date form field.
SwTwips CalcKanaAdj(SwLineLayout *pCurr)
Definition: itradj.cxx:397
void SetKanaComp(std::deque< sal_uInt16 > *pNew)
Definition: inftxt.hxx:329
sal_uInt16 GetFix() const
Definition: porglue.hxx:56
void SetJoinBorderWithPrev(const bool bJoinPrev)
Definition: porlin.hxx:170
void MaxAscentDescent(SwTwips &_orAscent, SwTwips &_orDescent, SwTwips &_orObjAscent, SwTwips &_orObjDescent, const SwLinePortion *_pDontConsiderPortion=nullptr, const bool _bNoFlyCntPorAndLinePor=false) const
determine ascent and descent for positioning of as-character anchored object
Definition: porlay.cxx:609
void SetMulti(const bool bNew)
Definition: inftxt.hxx:211
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
bool InFieldGrp() const
Definition: porlin.hxx:104
bool HasHint(TextFrameIndex nPos) const
Definition: inftxt.cxx:478
SwTwips Y() const
Definition: itrtxt.hxx:90
sal_uInt16 GetOrientation(const bool bVertLayout=false, const bool bVertFormatLRBT=false) const
Definition: swfont.cxx:436
OUString ExpandFieldmark(IFieldmark *pBM)
Definition: itrform2.cxx:837
const boost::optional< editeng::SvxBorderLine > & GetRightBorder() const
Definition: swfont.hxx:341
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:50
SwTwips RegStart() const
Definition: itrtxt.hxx:92
bool IsMulti() const
Definition: inftxt.hxx:210
sal_uInt16 ForcedLeftMargin() const
Definition: inftxt.hxx:556
#define ODF_FORMDROPDOWN_RESULT
bool IsFull() const
Definition: inftxt.hxx:568
const SvxLineSpacingItem * GetLineSpacing() const
Definition: inftxt.hxx:86
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: portxt.cxx:529
bool Seek(TextFrameIndex nPos)
Enables the attributes used at char pos nPos in the logical font.
Definition: itratr.cxx:305
SvxLineSpaceRule GetLineSpaceRule() const
std::vector< long > * GetpLLSpaceAdd() const
Definition: porlay.hxx:179
bool IsLastBlock() const
Definition: itrtxt.hxx:188
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:174
long GetLen(const Point &rPnt)
SwTextFormatInfo & GetInfo()
Definition: itrform2.hxx:213
void CalcUnclipped(SwTwips &rTop, SwTwips &rBottom)
Definition: itrform2.cxx:1979
long YDiff(long n1, long n2) const
Definition: frame.hxx:1399
sal_uInt16 RegDiff() const
Definition: itrtxt.hxx:93
void SetFull(const bool bNew)
Definition: inftxt.hxx:569
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:43
SwRect GetFrame(const SwRect &rPortion) const
Definition: txtfly.hxx:356
bool isLetterNumeric(const OUString &rStr, sal_Int32 nPos) const
sal_uInt16 sal_Unicode
Point const & GetRelPos() const
Definition: flyincnt.cxx:193
#define CH_TXTATR_INWORD
Definition: hintids.hxx:44
SwExpandPortion * TryNewNoLengthPortion(SwTextFormatInfo const &rInfo)
Try to create a new portion with zero length, for an end of a hint (where there is no CH_TXTATR)...
Definition: txtfld.cxx:322
sal_uInt16 GetLineHeight() const
void Top(const long nTop)
Definition: swrect.hxx:202
void CalcAdjLine(SwLineLayout *pCurr)
Definition: itradj.cxx:655
bool BuildMultiPortion(SwTextFormatInfo &rInf, SwMultiPortion &rMulti)
Definition: pormulti.cxx:1882
LINESTYLE_NONE
bool IsBreakPortion() const
Definition: porlin.hxx:114
const SwRect & getFrameArea() const
Definition: frame.hxx:175
#define SAL_MAX_UINT16
sal_Unicode GetChar(TextFrameIndex const nPos) const
Definition: inftxt.hxx:247
#define X
virtual ~SwTextFormatter() override
Definition: itrform2.cxx:112
sal_uInt16 GetRightBorderDist() const
Definition: swfont.hxx:361
bool IsInTab() const
Definition: frame.hxx:931
bool HasRotation() const
Definition: pormulti.hxx:147
void SetRoot(SwLineLayout *pNew)
Definition: inftxt.hxx:565
SwTwips Right() const
Definition: itrtxt.hxx:181
void SetClipping(const bool bNew)
Definition: porlay.hxx:137
#define DIR_BOTTOM2TOP
Definition: inftxt.hxx:55
void ResetFlags()
Definition: porlay.cxx:658
virtual parameter_map_t * GetParameters()=0
const Point & GetRefPoint() const
Definition: flyfrms.hxx:218
void Right(const long nRight)
Definition: swrect.hxx:198
bool IsNewLine() const
Definition: inftxt.hxx:583
void CalcRealHeight(bool bNewLine=false)
Definition: itrform2.cxx:1686
bool AllowRepaintOpt() const
Definition: itrform2.cxx:1927
sal_uInt8 m_nContentEndHyph
Definition: itrform2.hxx:37
TextFrameIndex GetLineStart() const
Definition: inftxt.hxx:595
void CalcFlyWidth(SwTextFormatInfo &rInf)
Calculation of the emulated right side.
Definition: itrform2.cxx:2248
This portion represents an as-character anchored fly (shape, frame, etc.)
Definition: porfly.hxx:44
SwFontScript GetActual() const
Definition: swfont.hxx:183
void SetPaintOfst(const SwTwips nNew)
Definition: inftxt.hxx:741
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:844
void SetNumDone(const bool bNew)
Definition: inftxt.hxx:635
bool InFixMargGrp() const
Definition: porlin.hxx:108
bool IsIgnoreFly() const
Definition: inftxt.hxx:575
bool IsBidi() const
Definition: pormulti.hxx:133
This portion represents a part of the paragraph string.
Definition: portxt.hxx:27
SwTwips Y() const
Definition: inftxt.hxx:387
bool IsSoftHyphPortion() const
Definition: porlin.hxx:127
SwTwips First() const
Definition: inftxt.hxx:551
static bool lcl_OldFieldRest(const SwLineLayout *pCurr)
Definition: itrform2.cxx:1147
std::unique_ptr< SwMultiCreator > GetMultiCreator(TextFrameIndex &rPos, SwMultiPortion const *pM) const
Definition: pormulti.cxx:908
TextFrameIndex NextDirChg(const TextFrameIndex nPos, const sal_uInt8 *pLevel=nullptr) const
Definition: porlay.cxx:1452
#define RES_FLYFRMFMT
Definition: hintids.hxx:276
bool IsBlinking() const
Definition: porlay.hxx:121
void CalcAscentAndHeight(sal_uInt16 &rAscent, sal_uInt16 &rHeight) const
Definition: itrtxt.cxx:66
void SetEndHyph(const bool bNew)
Definition: porlay.hxx:112
bool HasScriptSpace() const
Definition: inftxt.hxx:218
void SetRealHeight(sal_uInt16 nNew)
Definition: porlay.hxx:152
const SwViewOption & GetOpt() const
Definition: inftxt.hxx:245
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1300
void UpdatePos(SwLineLayout *pCurr, Point aStart, TextFrameIndex nStartIdx, bool bAlways=false) const
The position of the portions changes with the adjustment.
Definition: itrform2.cxx:1991
bool IsFootnoteNumPortion() const
Definition: porlin.hxx:119
bool m_bFlyInContentBase
Definition: itrform2.hxx:42
TextFrameIndex m_nRightScanIdx
Definition: itrform2.hxx:40
Style of a layout element.
Definition: frmfmt.hxx:57
SwTextInfo * m_pInf
Definition: itrtxt.hxx:35
SwTwips CalcFitToContent_()
Definition: itrform2.cxx:1916
void Bottom()
Definition: itrtxt.cxx:186
bool IsDummy() const
Definition: porlay.hxx:135
void SetBase(const SwTextFrame &rFrame, const Point &rBase, long nLnAscent, long nLnDescent, long nFlyAscent, long nFlyDescent, AsCharFlags nFlags)
After setting the RefPoints, the ascent needs to be recalculated because it is dependent on RelPos...
Definition: porfly.cxx:322
SwFrame * GetIndPrev() const
Definition: frame.hxx:702
bool m_bTruncLines
Definition: itrform2.hxx:43
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
SwTwips Left() const
Definition: itrtxt.hxx:333
SwLinePortion * NewPortion(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:1175
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:78
void Reset()
Definition: redlnitr.hxx:113
SwMultiPortion * m_pMulti
Definition: itrform2.hxx:36
SwTwips GetLineWidth()
Returns the distance between the current horizontal position and the end of the line.
Definition: inftxt.cxx:1708
SwTextFly & GetTextFly()
Definition: inftxt.hxx:390
const sal_Unicode CH_TAB
Definition: swfont.hxx:44
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
SwParaPortion * GetParaPortion()
Definition: inftxt.hxx:128
void SetWhichPor(const PortionType nNew)
Definition: porlin.hxx:94
SwCharRange & GetReformat()
Definition: porlay.hxx:266
void SetUnderflow(SwLinePortion *pNew)
Definition: inftxt.hxx:606
bool IsFlyPortion() const
Definition: porlin.hxx:125
void RecalcRealHeight()
Definition: itrform2.cxx:1678
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2514
int i
SwNumberPortion * NewNumberPortion(SwTextFormatInfo &rInf) const
Definition: txtfld.cxx:541
sal_uInt16 GetBottomBorderDist() const
Definition: swfont.hxx:360
SwLinePortion * GetFirstPortion() const
Definition: porlay.cxx:673
void CtorInitTextFormatter(SwTextFrame *pFrame, SwTextFormatInfo *pInf)
Definition: itrform2.cxx:87
const sal_Unicode CH_BLANK
Definition: swfont.hxx:42
void SelectFont()
Definition: inftxt.cxx:368
bool IsKernPortion() const
Definition: porlin.hxx:132
long GetHeight() const
Definition: swfont.hxx:283
void FinishKanaComp()
Definition: porlay.hxx:183
SwLinePortion * NewExtraPortion(SwTextFormatInfo &rInf)
Definition: txtfld.cxx:361
sal_uInt16 GetTopBorderSpace() const
Definition: swfont.hxx:863
std::unique_ptr< sw::MergedAttrIterByEnd > m_pByEndIter
Definition: itrform2.hxx:45
void BuildPortions(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:352
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:52
bool HasTruncLines() const
Definition: itrform2.hxx:204
void ResetSpaceIdx()
Definition: inftxt.hxx:443
SwTwips GetLeftMargin() const
Definition: itrtxt.hxx:328
sal_uInt16 Width() const
Definition: inftxt.hxx:533
const boost::optional< editeng::SvxBorderLine > & GetLeftBorder() const
Definition: swfont.hxx:342
void FinishSpaceAdd()
Definition: porlay.hxx:168
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2813
const SwFormatDrop * GetDropFormat() const
Definition: inftxt.cxx:1464
void SetJoinBorderWithNext(const bool bJoinNext)
Definition: porlin.hxx:171
PortionType
Definition: txttypes.hxx:23
SvxInterLineSpaceRule GetInterLineSpaceRule() const
void ResetMaxWidthDiff()
Definition: inftxt.hxx:314
void SetUnderScorePos(TextFrameIndex const nNew)
Definition: inftxt.hxx:645
SwFont * GetFnt()
Definition: itratr.hxx:103
bool IsTabLeftPortion() const
Definition: porlin.hxx:117
#define CHAR_ZWSP
Definition: swtypes.hxx:177
sal_uInt16 GetLineHeight() const
Definition: itrtxt.hxx:116
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:278
bool CheckFootnotePortion(SwLineLayout const *pCurr)
Definition: inftxt.hxx:652
bool IsDropPortion() const
Definition: porlin.hxx:121
void SetTabDecimal(const sal_Unicode cNew)
Definition: inftxt.hxx:623
void ClrUnderflow()
Definition: inftxt.hxx:589
bool isFrameAreaPositionValid() const
Definition: frame.hxx:162
bool IsQuick() const
Definition: itrform2.hxx:180
bool ChkFlyUnderflow(SwTextFormatInfo &rInf) const
This is called after the real height of the line has been calculated Therefore it is possible...
Definition: itrform2.cxx:2160
void SetTabOverflow(bool bOverflow)
Definition: inftxt.hxx:665
sal_Unicode GetHookChar() const
Definition: inftxt.hxx:627
const sal_uInt8 & CntMidHyph() const
Definition: itrform2.hxx:220
const boost::optional< editeng::SvxBorderLine > & GetBottomBorder() const
Definition: swfont.hxx:340
bool SnapToGrid() const
Definition: inftxt.hxx:222
TextFrameIndex GetLen() const
Definition: porlin.hxx:74
void SetFly(SwFlyPortion *pNew)
Definition: inftxt.hxx:615
A page of the document layout.
Definition: pagefrm.hxx:40
bool InTabGrp() const
Definition: porlin.hxx:100
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:200
#define ODF_FORMFIELD_DEFAULT_LENGTH
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:291
long X() const
void LeftMove(TextFrameIndex const nNew)
Definition: porlay.hxx:47
Point GetTopLeft() const
Definition: itrtxt.hxx:186
SwErgoSumPortion * NewErgoSumPortion(SwTextFormatInfo const &rInf) const
Definition: txtftn.cxx:998
const OUString & GetText() const
Definition: inftxt.hxx:246
bool IsStop() const
Definition: inftxt.hxx:579
short GetInterLineSpace() const
const SwLinePortion * GetUnderflow() const
Definition: inftxt.hxx:604
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:42
void ClearHookChar()
Definition: inftxt.hxx:625
void Truncate()
Definition: porlin.hxx:196
bool HasBrackets() const
Definition: pormulti.hxx:249
const Point & GetPos() const
Definition: inftxt.hxx:435
bool IsMultiPortion() const
Definition: porlin.hxx:134
long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1387
FontLineStyle GetUnderline() const
Definition: swfont.hxx:271
bool HasNegFirst() const
Definition: itrtxt.hxx:194
SwTwips X() const
Definition: inftxt.hxx:385
sal_uInt16 GetLeftBorderDist() const
Definition: swfont.hxx:362
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:693
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:78
SwTextFrame * m_pFrame
Definition: itrtxt.hxx:34
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:50
void SetForcedLeftMargin()
Definition: porlay.hxx:126
bool IsFootnoteNumFrame() const
Am I a FootnoteFrame, with a number at the start of the paragraph?
Definition: txtfrm.hxx:611
void CalcAscent(SwTextFormatInfo &rInf, SwLinePortion *pPor)
Definition: itrform2.cxx:737
TextFrameIndex GetReformatStart() const
Definition: inftxt.hxx:769
SwTwips Right() const
Definition: inftxt.hxx:549
void Left(const long nLeft)
Definition: swrect.hxx:193
void SetSoftHyphPos(TextFrameIndex const nNew)
Definition: inftxt.hxx:609
#define RES_CHRATR_ROTATE
Definition: hintids.hxx:101
bool SeekAndChgBefore(SwTextSizeInfo &rInf)
Definition: itrtxt.hxx:315
void Bottom(const long nBottom)
Definition: swrect.hxx:207
#define CHAR_HARDHYPHEN
Definition: swtypes.hxx:173
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
TextFrameIndex FormatLine(TextFrameIndex nStart)
Definition: itrform2.cxx:1473
sal_Int16 ScriptType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1439
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
Definition: txtfrm.hxx:724
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: txttab.cxx:303
SwTwips CalcBottomLine() const
Definition: itrform2.cxx:1891
SwTextPortion * WhichTextPor(SwTextFormatInfo &rInf) const
Definition: itrform2.cxx:859
SwMultiPortion * GetMulti() const
Definition: itrform2.hxx:199
bool IsRevers() const
Definition: pormulti.hxx:148
void SetLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:281
bool InExpGrp() const
Definition: porlin.hxx:107
void SetFixLineHeight()
Definition: porlay.hxx:294
sal_uInt16 GetDropLeft() const
Definition: itrtxt.hxx:204
void CalcAdjustLine(SwLineLayout *pCurr)
Definition: itrform2.cxx:722
void CalcDropHeight(const sal_uInt16 nLines)
Definition: txtdrop.cxx:483
void SetNext(SwLineLayout *pNew)
Definition: porlay.hxx:145
PortionType GetWhichPor() const
Definition: porlin.hxx:95
SvxShadowLocation GetShadowLocation() const
Definition: swfont.hxx:379
SwRepaint & GetRepaint()
Definition: porlay.hxx:264
bool IsFootnotePortion() const
Definition: porlin.hxx:120
void SetFootnoteDone(const bool bNew)
Definition: inftxt.hxx:631
vcl::Window * GetWin() const
Definition: viewsh.hxx:340
SwLinePortion * GetRest()
Definition: inftxt.hxx:581
void SetDummy(const bool bNew)
Definition: porlay.hxx:134
SwLinePortion * FindLastPortion()
Definition: porlin.cxx:182
#define ODF_FORMDROPDOWN_LISTENTRY
bool IsErgoSumPortion() const
Definition: porlin.hxx:115
void ChkNoHyph(const sal_uInt8 bEnd, const sal_uInt8 bMid)
Definition: inftxt.hxx:572
void SetStopUnderflow(const bool bNew)
Definition: inftxt.hxx:205
#define ODF_FORMTEXT
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:175
SvxAdjust GetAdjust() const
Definition: itrtxt.hxx:190
bool IsLastCenter() const
Definition: itrtxt.hxx:189
bool IsFly() const
Definition: porlay.hxx:117
long GetNextTop() const
Definition: txtfly.hxx:346
const sal_uInt8 & CntEndHyph() const
Definition: itrform2.hxx:219
bool IsRightToLeft() const
Definition: frame.hxx:963
const boost::optional< editeng::SvxBorderLine > & GetTopBorder() const
Definition: swfont.hxx:339
TextFrameIndex GetLen() const
Definition: inftxt.hxx:280
SwLinePortion * Underflow(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:152
sal_uInt16 GetBottomBorderSpace() const
Definition: swfont.hxx:878
void SetErgoDone(const bool bNew)
Definition: inftxt.hxx:633
void SetDirection(const sal_uInt8 nNew)
Definition: inftxt.hxx:225
void SetShift(const bool bNew)
Definition: inftxt.hxx:586
sal_uInt8 m_nContentMidHyph
Definition: itrform2.hxx:38
void SetLineStart(TextFrameIndex const nNew)
Definition: inftxt.hxx:596
bool InTextGrp() const
Definition: porlin.hxx:98
sal_uInt16 Width() const
Definition: possiz.hxx:46
SwScriptInfo & GetScriptInfo()
Definition: porlay.hxx:270
SwFontScript
Definition: swfont.hxx:122
double getLength(const B2DPolygon &rCandidate)
void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const long nMax=0)
Definition: itrcrsr.cxx:1174
SwLinePortion * GetLast()
Definition: inftxt.hxx:566
sal_uInt16 GetGridWidth(SwTextGridItem const &, SwDoc const &)
Definition: pagechg.cxx:2528
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:917
const Color & GetShadowColor() const
Definition: swfont.hxx:377
SwTextPortion * NewTextPortion(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:943
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:54
#define CHAR_ZWNBSP
Definition: swtypes.hxx:178
void SetNextPortion(SwLinePortion *pNew)
Definition: porlin.hxx:76
bool IsSnapToChars() const
Definition: tgrditem.hxx:100
static DrawFlyCntPortion * Create(const SwTextFrame &rFrame, SwFrameFormat const &rFormat, const Point &rBase, long nAsc, long nDescent, long nFlyAsc, long nFlyDesc, AsCharFlags nFlags)
Definition: porfly.cxx:282
void SetJoinBorderWithNext(const bool bJoinNext)
Definition: pordrop.hxx:58
void FeedInf(SwTextFormatInfo &rInf) const
Definition: itrform2.cxx:1839
static bool GetBoundsOfHiddenRange(const SwTextNode &rNode, sal_Int32 nPos, sal_Int32 &rnStartPos, sal_Int32 &rnEndPos, std::vector< sal_Int32 > *pList=nullptr)
Hidden text range information - static and non-version.
Definition: porlay.cxx:1546
sal_uInt16 GetRealHeight() const
Definition: porlay.hxx:153
#define ODF_FORMDATE
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
void SetAscent(const sal_uInt16 nNewAsc)
Definition: porlin.hxx:79
bool IsVertical() const
Definition: frame.hxx:949
SwDropPortionPart * GetFollow() const
Definition: pordrop.hxx:48
virtual OUString GetFieldname() const =0
void SetNewLine(const bool bNew)
Definition: inftxt.hxx:584
void Insert(SwLineLayout *pLine)
Definition: itrform2.cxx:123
void SetOtherThanFootnoteInside(const bool bNew)
Definition: inftxt.hxx:209
void SetLineHeight(const sal_uInt16 nNew)
Definition: inftxt.hxx:600
SwDoc & GetDoc()
Definition: txtfrm.hxx:448
bool IsOtherThanFootnoteInside() const
Definition: inftxt.hxx:208
bool IsOn() const
Definition: txtfly.hxx:313
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
SwTextGrid GetGridType() const
Definition: tgrditem.hxx:81
bool IsTest() const
Definition: inftxt.hxx:593
bool IsShowHiddenChar(bool bHard=false) const
Definition: viewopt.hxx:282
SwTextFrame * GetTextFrame()
Definition: itrtxt.hxx:134
bool IsFlyInCntBase() const
Definition: itrform2.hxx:210
void ResetKanaIdx()
Definition: inftxt.hxx:326
SwLineLayout * m_pCurr
Definition: itrtxt.hxx:36
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
static void ClearFly(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:81
void SetJoinBorderWithPrev(const bool bJoinPrev)
Definition: pordrop.hxx:57
virtual void FormatEOL(SwTextFormatInfo &rInf)
Definition: porlin.cxx:269
SwLinePortion * m_pFirstOfBorderMerge
Definition: itrform2.hxx:46
TextFrameIndex m_nLeftScanIdx
Definition: itrform2.hxx:39
bool IsQuoVadisPortion() const
Definition: porlin.hxx:116
sal_uInt16 GetBaseHeight() const
Definition: tgrditem.hxx:75
SwFlyPortion * GetFly()
Definition: inftxt.hxx:614
void SetMidHyph(const bool bNew)
Definition: porlay.hxx:114
void DropInit()
Definition: itrcrsr.cxx:354
bool GetJoinBorderWithNext() const
Definition: porlin.hxx:169
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:72
sal_uInt16 GetLineHeight() const
Definition: inftxt.hxx:599
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:53
void SetIdx(const TextFrameIndex nNew)
Definition: inftxt.hxx:279
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...
void AlignFlyInCntBase(long nBaseLine) const
Set all anchored as character objects to the passed BaseLine (in Y direction).
Definition: itrform2.cxx:2113
void SetRest(SwLinePortion *pNewRest)
Definition: inftxt.hxx:582
CharClass & GetAppCharClass()
Definition: init.cxx:709
sal_uInt16 GetFrameRstHeight() const
Definition: itrform2.cxx:135
void SetDropInit(const bool bNew)
Definition: inftxt.hxx:591
virtual void FormatEOL(SwTextFormatInfo &rInf) override
Definition: txttab.cxx:313
bool IsFlyCntPortion() const
Definition: porlin.hxx:112
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
void Clear(SwFont *pFnt)
Definition: redlnitr.hxx:110
sal_uInt16 & GetAscent()
Definition: porlin.hxx:77
void SetpSpaceAdd(std::vector< long > *pNew)
Definition: inftxt.hxx:451
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:623
virtual SwLinePortion * Insert(SwLinePortion *pPortion)
Definition: porlin.cxx:172
SwRedlineItr * GetRedln()
Definition: itratr.hxx:81
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
TextFrameIndex GetSoftHyphPos() const
Definition: inftxt.hxx:608
void DrawViewOpt(const SwLinePortion &rPor, PortionType nWhich) const
Definition: inftxt.cxx:1282
bool IsFootnoteDone() const
Definition: inftxt.hxx:630
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:625
long Y() const
SwLinePortion * WhichFirstPortion(SwTextFormatInfo &rInf)
Definition: itrform2.cxx:1012
bool IsPostItsPortion() const
Definition: porlin.hxx:128
SwDropPortion * NewDropPortion(SwTextFormatInfo &rInf)
Definition: txtdrop.cxx:560
bool CalcOnceMore()
Definition: itrform2.cxx:1878
#define ODF_FORMDROPDOWN
sal_uInt16 GetAscent() const
Definition: inftxt.hxx:710
SwFont & GetFont() const
Definition: pordrop.hxx:50
SwTwips GetLeftMin() const
Definition: itrtxt.hxx:193
void Init(SwLinePortion *pNextPortion=nullptr)
Definition: porlay.cxx:2192
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: itrform2.cxx:827