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