LibreOffice Module sw (master)  1
portxt.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 <com/sun/star/i18n/ScriptType.hpp>
21 #include <com/sun/star/i18n/XBreakIterator.hpp>
22 #include <i18nlangtag/mslangid.hxx>
23 #include <breakit.hxx>
24 #include <hintids.hxx>
26 #include <SwPortionHandler.hxx>
27 #include "porlay.hxx"
28 #include "inftxt.hxx"
29 #include "guess.hxx"
30 #include "porfld.hxx"
31 #include <pagefrm.hxx>
32 #include <tgrditem.hxx>
34 #include <IDocumentMarkAccess.hxx>
35 
36 #include <IMark.hxx>
37 #include <pam.hxx>
38 #include <doc.hxx>
39 #include <xmloff/odffields.hxx>
40 #include <viewopt.hxx>
41 
42 using namespace ::sw::mark;
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::i18n::ScriptType;
45 
46 // Returns for how many characters an extra space has to be added
47 // (for justified alignment).
49  const OUString* pStr, const SwLinePortion& rPor)
50 {
51  TextFrameIndex nPos, nEnd;
52  const SwScriptInfo* pSI = nullptr;
53 
54  if ( pStr )
55  {
56  // passing a string means we are inside a field
57  nPos = TextFrameIndex(0);
58  nEnd = TextFrameIndex(pStr->getLength());
59  }
60  else
61  {
62  nPos = rInf.GetIdx();
63  nEnd = rInf.GetIdx() + rPor.GetLen();
64  pStr = &rInf.GetText();
65  pSI = &const_cast<SwParaPortion*>(rInf.GetParaPortion())->GetScriptInfo();
66  }
67 
68  TextFrameIndex nCnt(0);
69  sal_uInt8 nScript = 0;
70 
71  // If portion consists of Asian characters and language is not
72  // Korean, we add extra space to each character.
73  // first we get the script type
74  if ( pSI )
75  nScript = pSI->ScriptType( nPos );
76  else
77  nScript = static_cast<sal_uInt8>(
78  g_pBreakIt->GetBreakIter()->getScriptType(*pStr, sal_Int32(nPos)));
79 
80  // Note: rInf.GetIdx() can differ from nPos,
81  // e.g., when rPor is a field portion. nPos refers to the string passed
82  // to the function, rInf.GetIdx() refers to the original string.
83 
84  // We try to find out which justification mode is required. This is done by
85  // evaluating the script type and the language attribute set for this portion
86 
87  // Asian Justification: Each character get some extra space
88  if ( nEnd > nPos && ASIAN == nScript )
89  {
90  LanguageType aLang =
91  rInf.GetTextFrame()->GetLangOfChar(rInf.GetIdx(), nScript);
92 
93  if (!MsLangId::isKorean(aLang))
94  {
95  const SwLinePortion* pPor = rPor.GetNextPortion();
96  if ( pPor && ( pPor->IsKernPortion() ||
97  pPor->IsControlCharPortion() ||
98  pPor->IsPostItsPortion() ) )
99  pPor = pPor->GetNextPortion();
100 
101  nCnt += SwScriptInfo::CountCJKCharacters( *pStr, nPos, nEnd, aLang );
102 
103  if ( !pPor || pPor->IsHolePortion() || pPor->InFixMargGrp() ||
104  pPor->IsBreakPortion() )
105  --nCnt;
106 
107  return nCnt;
108  }
109  }
110 
111  // Kashida Justification: Insert Kashidas
112  if ( nEnd > nPos && pSI && COMPLEX == nScript )
113  {
114  if ( SwScriptInfo::IsArabicText( *pStr, nPos, nEnd - nPos ) && pSI->CountKashida() )
115  {
116  const sal_Int32 nKashRes = pSI->KashidaJustify( nullptr, nullptr, nPos, nEnd - nPos );
117  // i60591: need to check result of KashidaJustify
118  // determine if kashida justification is applicable
119  if (nKashRes != -1)
120  return TextFrameIndex(nKashRes);
121  }
122  }
123 
124  // Thai Justification: Each character cell gets some extra space
125  if ( nEnd > nPos && COMPLEX == nScript )
126  {
127  LanguageType aLang =
128  rInf.GetTextFrame()->GetLangOfChar(rInf.GetIdx(), nScript);
129 
130  if ( LANGUAGE_THAI == aLang )
131  {
132  nCnt = SwScriptInfo::ThaiJustify( *pStr, nullptr, nullptr, nPos, nEnd - nPos );
133 
134  const SwLinePortion* pPor = rPor.GetNextPortion();
135  if ( pPor && ( pPor->IsKernPortion() ||
136  pPor->IsControlCharPortion() ||
137  pPor->IsPostItsPortion() ) )
138  pPor = pPor->GetNextPortion();
139 
140  if ( nCnt && ( ! pPor || pPor->IsHolePortion() || pPor->InFixMargGrp() ) )
141  --nCnt;
142 
143  return nCnt;
144  }
145  }
146 
147  // Here starts the good old "Look for blanks and add space to them" part.
148  // Note: We do not want to add space to an isolated latin blank in front
149  // of some complex characters in RTL environment
150  const bool bDoNotAddSpace =
151  LATIN == nScript && (nEnd == nPos + TextFrameIndex(1)) && pSI &&
152  ( i18n::ScriptType::COMPLEX ==
153  pSI->ScriptType(nPos + TextFrameIndex(1))) &&
154  rInf.GetTextFrame() && rInf.GetTextFrame()->IsRightToLeft();
155 
156  if ( bDoNotAddSpace )
157  return nCnt;
158 
159  TextFrameIndex nTextEnd = std::min(nEnd, TextFrameIndex(pStr->getLength()));
160  for ( ; nPos < nTextEnd; ++nPos )
161  {
162  if (CH_BLANK == (*pStr)[ sal_Int32(nPos) ])
163  ++nCnt;
164  }
165 
166  // We still have to examine the next character:
167  // If the next character is ASIAN and not KOREAN we have
168  // to add an extra space
169  // nPos refers to the original string, even if a field string has
170  // been passed to this function
171  nPos = rInf.GetIdx() + rPor.GetLen();
172  if (nPos < TextFrameIndex(rInf.GetText().getLength()))
173  {
174  sal_uInt8 nNextScript = 0;
175  const SwLinePortion* pPor = rPor.GetNextPortion();
176  if ( pPor && pPor->IsKernPortion() )
177  pPor = pPor->GetNextPortion();
178 
179  if (!pPor || pPor->InFixMargGrp())
180  return nCnt;
181 
182  // next character is inside a field?
183  if ( CH_TXTATR_BREAKWORD == rInf.GetChar( nPos ) && pPor->InExpGrp() )
184  {
185  bool bOldOnWin = rInf.OnWin();
186  const_cast<SwTextSizeInfo &>(rInf).SetOnWin( false );
187 
188  OUString aStr;
189  pPor->GetExpText( rInf, aStr );
190  const_cast<SwTextSizeInfo &>(rInf).SetOnWin( bOldOnWin );
191 
192  nNextScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( aStr, 0 ));
193  }
194  else
195  nNextScript = static_cast<sal_uInt8>(
196  g_pBreakIt->GetBreakIter()->getScriptType(rInf.GetText(), sal_Int32(nPos)));
197 
198  if( ASIAN == nNextScript )
199  {
200  LanguageType aLang =
201  rInf.GetTextFrame()->GetLangOfChar(nPos, nNextScript);
202 
203  if (!MsLangId::isKorean(aLang))
204  ++nCnt;
205  }
206  }
207 
208  return nCnt;
209 }
210 
212 {
213  SwTextPortion *const pNew(new SwTextPortion);
214  static_cast<SwLinePortion&>(*pNew) = rPortion;
215  pNew->SetWhichPor( PortionType::Text ); // overwrite that!
216  return pNew;
217 }
218 
220 {
221  // The word/char is larger than the line
222  // Special case 1: The word is larger than the line
223  // We truncate ...
224  const sal_uInt16 nLineWidth = static_cast<sal_uInt16>(rInf.Width() - rInf.X());
225  TextFrameIndex nLen = rGuess.CutPos() - rInf.GetIdx();
226  if (nLen > TextFrameIndex(0))
227  {
228  // special case: guess does not always provide the correct
229  // width, only in common cases.
230  if ( !rGuess.BreakWidth() )
231  {
232  rInf.SetLen( nLen );
233  SetLen( nLen );
234  CalcTextSize( rInf );
235 
236  // changing these values requires also changing them in
237  // guess.cxx
238  sal_uInt16 nItalic = 0;
239  if( ITALIC_NONE != rInf.GetFont()->GetItalic() && !rInf.NotEOL() )
240  {
241  nItalic = Height() / 12;
242  }
243  Width( Width() + nItalic );
244  }
245  else
246  {
247  Width( rGuess.BreakWidth() );
248  SetLen( nLen );
249  }
250  }
251  // special case: first character does not fit to line
252  else if ( rGuess.CutPos() == rInf.GetLineStart() )
253  {
254  SetLen( TextFrameIndex(1) );
255  Width( nLineWidth );
256  }
257  else
258  {
259  SetLen( TextFrameIndex(0) );
260  Width( 0 );
261  }
262 }
263 
265 {
266  Truncate();
267  Height( 0 );
268  Width( 0 );
269  SetLen( TextFrameIndex(0) );
270  SetAscent( 0 );
271  rInf.SetUnderflow( this );
272 }
273 
274 static bool lcl_HasContent( const SwFieldPortion& rField, SwTextFormatInfo const &rInf )
275 {
276  OUString aText;
277  return rField.GetExpText( rInf, aText ) && !aText.isEmpty();
278 }
279 
281 {
282  // 5744: If only the hyphen does not fit anymore, we still need to wrap
283  // the word, or else return true!
284  if( rInf.IsUnderflow() && rInf.GetSoftHyphPos() )
285  {
286  // soft hyphen portion has triggered an underflow event because
287  // of an alternative spelling position
288  bool bFull = false;
289  const bool bHyph = rInf.ChgHyph( true );
290  if( rInf.IsHyphenate() )
291  {
292  SwTextGuess aGuess;
293  // check for alternative spelling left from the soft hyphen
294  // this should usually be true but
295  aGuess.AlternativeSpelling(rInf, rInf.GetSoftHyphPos() - TextFrameIndex(1));
296  bFull = CreateHyphen( rInf, aGuess );
297  OSL_ENSURE( bFull, "Problem with hyphenation!!!" );
298  }
299  rInf.ChgHyph( bHyph );
300  rInf.SetSoftHyphPos( TextFrameIndex(0) );
301  return bFull;
302  }
303 
304  SwTextGuess aGuess;
305  const bool bFull = !aGuess.Guess( *this, rInf, Height() );
306 
307  // these are the possible cases:
308  // A Portion fits to current line
309  // B Portion does not fit to current line but a possible line break
310  // within the portion has been found by the break iterator, 2 subcases
311  // B1 break is hyphen
312  // B2 break is word end
313  // C Portion does not fit to current line and no possible line break
314  // has been found by break iterator, 2 subcases:
315  // C1 break iterator found a possible line break in portion before us
316  // ==> this break is used (underflow)
317  // C2 break iterator does not found a possible line break at all:
318  // ==> line break
319 
320  // case A: line not yet full
321  if ( !bFull )
322  {
323  Width( aGuess.BreakWidth() );
324  // Caution!
325  if( !InExpGrp() || InFieldGrp() )
326  SetLen( rInf.GetLen() );
327 
328  short nKern = rInf.GetFont()->CheckKerning();
329  if( nKern > 0 && rInf.Width() < rInf.X() + Width() + nKern )
330  {
331  nKern = static_cast<short>(rInf.Width() - rInf.X() - Width() - 1);
332  if( nKern < 0 )
333  nKern = 0;
334  }
335  if( nKern )
336  new SwKernPortion( *this, nKern );
337  }
338  // special case: hanging portion
339  else if( bFull && aGuess.GetHangingPortion() )
340  {
341  Width( aGuess.BreakWidth() );
342  SetLen( aGuess.BreakPos() - rInf.GetIdx() );
343  aGuess.GetHangingPortion()->SetAscent( GetAscent() );
344  Insert( aGuess.ReleaseHangingPortion() );
345  }
346  // breakPos >= index
347  else if (aGuess.BreakPos() >= rInf.GetIdx() && aGuess.BreakPos() != TextFrameIndex(COMPLETE_STRING))
348  {
349  // case B1
350  if( aGuess.HyphWord().is() && aGuess.BreakPos() > rInf.GetLineStart()
351  && ( aGuess.BreakPos() > rInf.GetIdx() ||
352  ( rInf.GetLast() && ! rInf.GetLast()->IsFlyPortion() ) ) )
353  {
354  CreateHyphen( rInf, aGuess );
355  if ( rInf.GetFly() )
356  rInf.GetRoot()->SetMidHyph( true );
357  else
358  rInf.GetRoot()->SetEndHyph( true );
359  }
360  // case C1
361  // - Footnote portions with fake line start (i.e., not at beginning of line)
362  // should keep together with the text portion. (Note: no keep together
363  // with only footnote portions.
364  // - TabPortions not at beginning of line should keep together with the
365  // text portion, if they are not followed by a blank
366  // (work around different definition of tab stop character - breaking or
367  // non breaking character - in compatibility mode)
368  else if ( ( IsFootnotePortion() && rInf.IsFakeLineStart() &&
369 
370  rInf.IsOtherThanFootnoteInside() ) ||
371  ( rInf.GetLast() &&
373  rInf.GetLast()->InTabGrp() &&
374  rInf.GetLineStart() + rInf.GetLast()->GetLen() < rInf.GetIdx() &&
375  aGuess.BreakPos() == rInf.GetIdx() &&
376  CH_BLANK != rInf.GetChar( rInf.GetIdx() ) &&
377  CH_FULL_BLANK != rInf.GetChar( rInf.GetIdx() ) &&
378  CH_SIX_PER_EM != rInf.GetChar( rInf.GetIdx() ) ) )
379  BreakUnderflow( rInf );
380  // case B2
381  else if( rInf.GetIdx() > rInf.GetLineStart() ||
382  aGuess.BreakPos() > rInf.GetIdx() ||
383  // this is weird: during formatting the follow of a field
384  // the values rInf.GetIdx and rInf.GetLineStart are replaced
385  // IsFakeLineStart indicates GetIdx > GetLineStart
386  rInf.IsFakeLineStart() ||
387  rInf.GetFly() ||
388  rInf.IsFirstMulti() ||
389  ( rInf.GetLast() &&
390  ( rInf.GetLast()->IsFlyPortion() ||
391  ( rInf.GetLast()->InFieldGrp() &&
392  ! rInf.GetLast()->InNumberGrp() &&
393  ! rInf.GetLast()->IsErgoSumPortion() &&
394  lcl_HasContent(*static_cast<SwFieldPortion*>(rInf.GetLast()),rInf ) ) ) ) )
395  {
396  // GetLineWidth() takes care of DocumentSettingId::TAB_OVER_MARGIN.
397  if (aGuess.BreakWidth() <= rInf.GetLineWidth())
398  Width( aGuess.BreakWidth() );
399  else
400  // this actually should not happen
401  Width( sal_uInt16(rInf.Width() - rInf.X()) );
402 
403  SetLen( aGuess.BreakPos() - rInf.GetIdx() );
404 
405  OSL_ENSURE( aGuess.BreakStart() >= aGuess.FieldDiff(),
406  "Trouble with expanded field portions during line break" );
407  TextFrameIndex const nRealStart = aGuess.BreakStart() - aGuess.FieldDiff();
408  if( aGuess.BreakPos() < nRealStart && !InExpGrp() )
409  {
410  SwHolePortion *pNew = new SwHolePortion( *this );
411  pNew->SetLen( nRealStart - aGuess.BreakPos() );
412  Insert( pNew );
413  }
414  }
415  else // case C2, last exit
416  BreakCut( rInf, aGuess );
417  }
418  // breakPos < index or no breakpos at all
419  else
420  {
421  bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx();
422  if (aGuess.BreakPos() != TextFrameIndex(COMPLETE_STRING) &&
423  aGuess.BreakPos() != rInf.GetLineStart() &&
424  ( !bFirstPor || rInf.GetFly() || rInf.GetLast()->IsFlyPortion() ||
425  rInf.IsFirstMulti() ) &&
426  ( !rInf.GetLast()->IsBlankPortion() ||
427  SwBlankPortion::MayUnderflow(rInf, rInf.GetIdx() - TextFrameIndex(1), true)))
428  { // case C1 (former BreakUnderflow())
429  BreakUnderflow( rInf );
430  }
431  else
432  // case C2, last exit
433  BreakCut( rInf, aGuess );
434  }
435 
436  return bFull;
437 }
438 
440 {
441  // GetLineWidth() takes care of DocumentSettingId::TAB_OVER_MARGIN.
442  if( rInf.GetLineWidth() < 0 || (!GetLen() && !InExpGrp()) )
443  {
444  Height( 0 );
445  Width( 0 );
446  SetLen( TextFrameIndex(0) );
447  SetAscent( 0 );
448  SetNextPortion( nullptr ); // ????
449  return true;
450  }
451 
452  OSL_ENSURE( rInf.RealWidth() || (rInf.X() == rInf.Width()),
453  "SwTextPortion::Format: missing real width" );
454  OSL_ENSURE( Height(), "SwTextPortion::Format: missing height" );
455 
456  return Format_( rInf );
457 }
458 
459 // Format end of line
460 // 5083: We can have awkward cases e.g.:
461 // "from {Santa}"
462 // Santa wraps, "from " turns into "from" and " " in a justified
463 // paragraph, in which the glue gets expanded instead of merged
464 // with the MarginPortion.
465 
466 // rInf.nIdx points to the next word, nIdx-1 is the portion's last char
468 {
469  if( !(
471  !GetNextPortion()->GetNextPortion() ) ) &&
472  GetLen() &&
473  rInf.GetIdx() < TextFrameIndex(rInf.GetText().getLength()) &&
474  TextFrameIndex(1) < rInf.GetIdx() &&
475  ' ' == rInf.GetChar(rInf.GetIdx() - TextFrameIndex(1)) &&
476  !rInf.GetLast()->IsHolePortion()) )
477  return;
478 
479  // calculate number of blanks
480  TextFrameIndex nX(rInf.GetIdx() - TextFrameIndex(1));
481  TextFrameIndex nHoleLen(1);
482  while( nX && nHoleLen < GetLen() && CH_BLANK == rInf.GetChar( --nX ) )
483  nHoleLen++;
484 
485  // First set ourselves and the insert, because there could be
486  // a SwLineLayout
487  sal_uInt16 nBlankSize;
488  if( nHoleLen == GetLen() )
489  nBlankSize = Width();
490  else
491  nBlankSize = sal_Int32(nHoleLen) * rInf.GetTextSize(OUString(' ')).Width();
492  Width( Width() - nBlankSize );
493  rInf.X( rInf.X() - nBlankSize );
494  SetLen( GetLen() - nHoleLen );
495  SwLinePortion *pHole = new SwHolePortion( *this );
496  static_cast<SwHolePortion *>( pHole )->SetBlankWidth( nBlankSize );
497  static_cast<SwHolePortion *>( pHole )->SetLen( nHoleLen );
498  Insert( pHole );
499 
500 }
501 
503 {
504  OSL_ENSURE( false, "SwTextPortion::GetModelPositionForViewPoint: don't use this method!" );
506 }
507 
508 // The GetTextSize() assumes that the own length is correct
510 {
511  SwPosSize aSize = rInf.GetTextSize();
512  if( !GetJoinBorderWithPrev() )
513  aSize.Width(aSize.Width() + rInf.GetFont()->GetLeftBorderSpace() );
514  if( !GetJoinBorderWithNext() )
515  aSize.Width(aSize.Width() + rInf.GetFont()->GetRightBorderSpace() );
516 
517  aSize.Height(aSize.Height() +
518  rInf.GetFont()->GetTopBorderSpace() +
519  rInf.GetFont()->GetBottomBorderSpace() );
520 
521  return aSize;
522 }
523 
524 void SwTextPortion::Paint( const SwTextPaintInfo &rInf ) const
525 {
526  if (rInf.OnWin() && TextFrameIndex(1) == rInf.GetLen()
527  && CH_TXT_ATR_FIELDEND == rInf.GetText()[sal_Int32(rInf.GetIdx())])
528  {
529  assert(false); // this is some debugging only code
530  rInf.DrawBackBrush( *this );
531  const OUString aText(CH_TXT_ATR_SUBST_FIELDEND);
532  rInf.DrawText(aText, *this, TextFrameIndex(0), TextFrameIndex(aText.getLength()));
533  }
534  else if (rInf.OnWin() && TextFrameIndex(1) == rInf.GetLen()
535  && CH_TXT_ATR_FIELDSTART == rInf.GetText()[sal_Int32(rInf.GetIdx())])
536  {
537  assert(false); // this is some debugging only code
538  rInf.DrawBackBrush( *this );
539  const OUString aText(CH_TXT_ATR_SUBST_FIELDSTART);
540  rInf.DrawText(aText, *this, TextFrameIndex(0), TextFrameIndex(aText.getLength()));
541  }
542  else if( GetLen() )
543  {
544  rInf.DrawBackBrush( *this );
545  rInf.DrawBorder( *this );
546 
547  // do we have to repaint a post it portion?
548  if( rInf.OnWin() && mpNextPortion && !mpNextPortion->Width() )
549  mpNextPortion->PrePaint( rInf, this );
550 
551  auto const* pWrongList = rInf.GetpWrongList();
552  auto const* pGrammarCheckList = rInf.GetGrammarCheckList();
553  auto const* pSmarttags = rInf.GetSmartTags();
554 
555  const bool bWrong = nullptr != pWrongList;
556  const bool bGrammarCheck = nullptr != pGrammarCheckList;
557  const bool bSmartTags = nullptr != pSmarttags;
558 
559  if ( bWrong || bSmartTags || bGrammarCheck )
560  rInf.DrawMarkedText( *this, rInf.GetLen(), bWrong, bSmartTags, bGrammarCheck );
561  else
562  rInf.DrawText( *this, rInf.GetLen() );
563  }
564 }
565 
566 bool SwTextPortion::GetExpText( const SwTextSizeInfo &, OUString & ) const
567 {
568  return false;
569 }
570 
571 // Responsible for the justified paragraph. They calculate the blank
572 // count and the resulting added space.
574  TextFrameIndex& rCharCnt) const
575 {
576  TextFrameIndex nCnt(0);
577  TextFrameIndex nPos(0);
578 
579  if ( rInf.SnapToGrid() )
580  {
581  SwTextGridItem const*const pGrid(GetGridItem(rInf.GetTextFrame()->FindPageFrame()));
582  if (pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && pGrid->IsSnapToChars())
583  return TextFrameIndex(0);
584  }
585 
586  if ( InExpGrp() )
587  {
588  if( !IsBlankPortion() && !InNumberGrp() && !IsCombinedPortion() )
589  {
590  // OnWin() likes to return a blank instead of an empty string from
591  // time to time. We cannot use that here at all, however.
592  bool bOldOnWin = rInf.OnWin();
593  const_cast<SwTextSizeInfo &>(rInf).SetOnWin( false );
594 
595  OUString aStr;
596  GetExpText( rInf, aStr );
597  const_cast<SwTextSizeInfo &>(rInf).SetOnWin( bOldOnWin );
598 
599  nCnt = nCnt + lcl_AddSpace( rInf, &aStr, *this );
600  nPos = TextFrameIndex(aStr.getLength());
601  }
602  }
603  else if( !IsDropPortion() )
604  {
605  nCnt = nCnt + lcl_AddSpace( rInf, nullptr, *this );
606  nPos = GetLen();
607  }
608  rCharCnt = rCharCnt + nPos;
609  return nCnt;
610 }
611 
612 long SwTextPortion::CalcSpacing( long nSpaceAdd, const SwTextSizeInfo &rInf ) const
613 {
614  TextFrameIndex nCnt(0);
615 
616  if ( rInf.SnapToGrid() )
617  {
618  SwTextGridItem const*const pGrid(GetGridItem(rInf.GetTextFrame()->FindPageFrame()));
619  if (pGrid && GRID_LINES_CHARS == pGrid->GetGridType() && pGrid->IsSnapToChars())
620  return 0;
621  }
622 
623  if ( InExpGrp() )
624  {
625  if( !IsBlankPortion() && !InNumberGrp() && !IsCombinedPortion() )
626  {
627  // OnWin() likes to return a blank instead of an empty string from
628  // time to time. We cannot use that here at all, however.
629  bool bOldOnWin = rInf.OnWin();
630  const_cast<SwTextSizeInfo &>(rInf).SetOnWin( false );
631 
632  OUString aStr;
633  GetExpText( rInf, aStr );
634  const_cast<SwTextSizeInfo &>(rInf).SetOnWin( bOldOnWin );
635  if( nSpaceAdd > 0 )
636  nCnt = nCnt + lcl_AddSpace( rInf, &aStr, *this );
637  else
638  {
639  nSpaceAdd = -nSpaceAdd;
640  nCnt = TextFrameIndex(aStr.getLength());
641  }
642  }
643  }
644  else if( !IsDropPortion() )
645  {
646  if( nSpaceAdd > 0 )
647  nCnt = nCnt + lcl_AddSpace( rInf, nullptr, *this );
648  else
649  {
650  nSpaceAdd = -nSpaceAdd;
651  nCnt = GetLen();
652  SwLinePortion* pPor = GetNextPortion();
653 
654  // we do not want an extra space in front of margin portions
655  if ( nCnt )
656  {
657  while ( pPor && !pPor->Width() && ! pPor->IsHolePortion() )
658  pPor = pPor->GetNextPortion();
659 
660  if ( !pPor || pPor->InFixMargGrp() || pPor->IsHolePortion() )
661  --nCnt;
662  }
663  }
664  }
665 
666  return sal_Int32(nCnt) * nSpaceAdd / SPACING_PRECISION_FACTOR;
667 }
668 
670 {
671  rPH.Text( GetLen(), GetWhichPor(), Height(), Width() );
672 }
673 
675  : SwTextPortion()
676 {
678 }
679 
681 {
682  return SwTextPortion::Format(rTextFormatInfo);
683 }
684 
686 {
687  if ( Width() )
688  {
689  rInf.DrawViewOpt( *this, PortionType::InputField );
690  SwTextSlot aPaintText( &rInf, this, true, true, OUString() );
691  SwTextPortion::Paint( rInf );
692  }
693  else
694  {
695  // highlight empty input field, elsewhere they are completely invisible for the user
696  SwRect aIntersect;
697  rInf.CalcRect(*this, &aIntersect);
698  const sal_uInt16 aAreaWidth = rInf.GetTextSize(OUString(' ')).Width();
699  aIntersect.Left(aIntersect.Left() - aAreaWidth/2);
700  aIntersect.Width(aAreaWidth);
701 
702  if (aIntersect.HasArea()
703  && rInf.OnWin()
705  && !rInf.GetOpt().IsPagePreview())
706  {
707  OutputDevice* pOut = const_cast<OutputDevice*>(rInf.GetOut());
708  pOut->Push(PushFlags::LINECOLOR | PushFlags::FILLCOLOR);
710  pOut->SetLineColor();
711  pOut->DrawRect(aIntersect.SVRect());
712  pOut->Pop();
713  }
714  }
715 }
716 
717 bool SwTextInputFieldPortion::GetExpText( const SwTextSizeInfo &rInf, OUString &rText ) const
718 {
719  sal_Int32 nIdx(rInf.GetIdx());
720  sal_Int32 nLen(rInf.GetLen());
721  if ( rInf.GetChar( rInf.GetIdx() ) == CH_TXT_ATR_INPUTFIELDSTART )
722  {
723  ++nIdx;
724  --nLen;
725  }
726  if (rInf.GetChar(rInf.GetIdx() + rInf.GetLen() - TextFrameIndex(1)) == CH_TXT_ATR_INPUTFIELDEND)
727  {
728  --nLen;
729  }
730  rText = rInf.GetText().copy( nIdx, std::min( nLen, rInf.GetText().getLength() - nIdx ) );
731 
732  return true;
733 }
734 
736 {
737  SwTextSlot aFormatText( &rInf, this, true, false );
738  if (rInf.GetLen() == TextFrameIndex(0))
739  {
740  return SwPosSize( 0, 0 );
741  }
742 
743  return rInf.GetTextSize();
744 }
745 
747  : nBlankWidth( 0 )
748 {
749  SetLen( TextFrameIndex(1) );
750  Height( rPor.Height() );
751  SetAscent( rPor.GetAscent() );
753 }
754 
756 
757 void SwHolePortion::Paint( const SwTextPaintInfo &rInf ) const
758 {
759  if( !rInf.GetOut() )
760  return;
761 
762  // #i16816# export stuff only needed for tagged pdf support
764  return;
765 
766  // #i68503# the hole must have no decoration for a consistent visual appearance
767  const SwFont* pOrigFont = rInf.GetFont();
768  std::unique_ptr<SwFont> pHoleFont;
769  std::unique_ptr<SwFontSave> pFontSave;
770  if( pOrigFont->GetUnderline() != LINESTYLE_NONE
771  || pOrigFont->GetOverline() != LINESTYLE_NONE
772  || pOrigFont->GetStrikeout() != STRIKEOUT_NONE )
773  {
774  pHoleFont.reset(new SwFont( *pOrigFont ));
775  pHoleFont->SetUnderline( LINESTYLE_NONE );
776  pHoleFont->SetOverline( LINESTYLE_NONE );
777  pHoleFont->SetStrikeout( STRIKEOUT_NONE );
778  pFontSave.reset(new SwFontSave( rInf, pHoleFont.get() ));
779  }
780 
781  rInf.DrawText(" ", *this, TextFrameIndex(0), TextFrameIndex(1));
782 
783  pFontSave.reset();
784  pHoleFont.reset();
785 }
786 
788 {
789  return rInf.IsFull() || rInf.X() >= rInf.Width();
790 }
791 
793 {
794  rPH.Text( GetLen(), GetWhichPor() );
795 }
796 
797 void SwFieldMarkPortion::Paint( const SwTextPaintInfo & /*rInf*/) const
798 {
799  // These shouldn't be painted!
800  //SwTextPortion::Paint(rInf);
801 }
802 
804 {
805  Width(0);
806  return false;
807 }
808 
810 {
811  SwPosition const aPosition(rInf.GetTextFrame()->MapViewToModelPos(rInf.GetIdx()));
812 
813  IFieldmark const*const pBM = rInf.GetTextFrame()->GetDoc().getIDocumentMarkAccess()->getFieldmarkAt(aPosition);
814 
815  OSL_ENSURE(pBM && pBM->GetFieldname( ) == ODF_FORMCHECKBOX,
816  "Where is my form field bookmark???");
817 
818  if (pBM && pBM->GetFieldname( ) == ODF_FORMCHECKBOX)
819  {
820  const ICheckboxFieldmark* pCheckboxFm = dynamic_cast<ICheckboxFieldmark const*>(pBM);
821  bool bChecked = pCheckboxFm && pCheckboxFm->IsChecked();
822  rInf.DrawCheckBox(*this, bChecked);
823  }
824 }
825 
827 {
828  SwPosition const aPosition(rInf.GetTextFrame()->MapViewToModelPos(rInf.GetIdx()));
829  IFieldmark const*const pBM = rInf.GetTextFrame()->GetDoc().getIDocumentMarkAccess()->getFieldmarkAt(aPosition);
830  OSL_ENSURE(pBM && pBM->GetFieldname( ) == ODF_FORMCHECKBOX, "Where is my form field bookmark???");
831  if (pBM && pBM->GetFieldname( ) == ODF_FORMCHECKBOX)
832  {
833  // the width of the checkbox portion is the same as its height since it's a square
834  // and that size depends on the font size.
835  // See:
836  // http://document-foundation-mail-archive.969070.n3.nabble.com/Wrong-copy-paste-in-SwFieldFormCheckboxPortion-Format-td4269112.html
837  Width( rInf.GetTextHeight( ) );
838  Height( rInf.GetTextHeight( ) );
839  SetAscent( rInf.GetAscent( ) );
840  }
841  return false;
842 }
843 
844 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool IsFirstMulti() const
Definition: inftxt.hxx:212
static Color & GetFieldShadingsColor()
Definition: viewopt.cxx:430
sal_uInt16 GetLeftBorderSpace() const
Definition: swfont.hxx:900
TextFrameIndex FieldDiff() const
Definition: guess.hxx:57
void DrawBackBrush(const SwLinePortion &rPor) const
Definition: inftxt.cxx:1156
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
short CheckKerning()
Definition: swfont.hxx:320
Marks a position in the document model.
Definition: pam.hxx:35
bool IsPagePreview() const
Definition: viewopt.hxx:617
virtual void FormatEOL(SwTextFormatInfo &rInf) override
Definition: portxt.cxx:467
sal_uInt16 BreakWidth() const
Definition: guess.hxx:53
bool IsUnderflow() const
Definition: inftxt.hxx:589
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1333
#define CH_TXT_ATR_SUBST_FIELDSTART
Definition: hintids.hxx:182
sal_uInt16 Height() const
Definition: possiz.hxx:44
SwFont * GetFont()
Definition: inftxt.hxx:238
bool InNumberGrp() const
Definition: porlin.hxx:102
SwHolePortion(const SwTextPortion &rPor)
Definition: portxt.cxx:746
bool GetJoinBorderWithPrev() const
Definition: porlin.hxx:168
void BreakCut(SwTextFormatInfo &rInf, const SwTextGuess &rGuess)
Definition: portxt.cxx:219
void CalcTextSize(const SwTextSizeInfo &rInfo)
Definition: porlin.cxx:138
sal_uInt16 GetRightBorderSpace() const
Definition: swfont.hxx:885
#define CH_TXT_ATR_SUBST_FIELDEND
Definition: hintids.hxx:183
The SwPortionHandler interface implements a visitor for the layout engine's text portions.
#define ODF_FORMCHECKBOX
void DrawBorder(const SwLinePortion &rPor) const
Draw character border around a line portion.
Definition: inftxt.cxx:1303
sal_uInt16 GetTextHeight() const
Definition: inftxt.hxx:719
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: portxt.cxx:685
static TextFrameIndex lcl_AddSpace(const SwTextSizeInfo &rInf, const OUString *pStr, const SwLinePortion &rPor)
Definition: portxt.cxx:48
bool Guess(const SwTextPortion &rPor, SwTextFormatInfo &rInf, const sal_uInt16 nHeight)
Definition: guess.cxx:50
void SetLen(TextFrameIndex const nLen)
Definition: porlin.hxx:75
#define ASIAN
sw::WrongListIterator * GetGrammarCheckList() const
Definition: inftxt.hxx:458
void DrawText(const OUString &rText, const SwLinePortion &rPor, TextFrameIndex nIdx=TextFrameIndex(0), TextFrameIndex nLen=TextFrameIndex(COMPLETE_STRING), const bool bKern=false) const
Definition: inftxt.hxx:747
sal_uInt16 RealWidth() const
Definition: inftxt.hxx:555
FontStrikeout GetStrikeout() const
Definition: swfont.hxx:272
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1682
static bool lcl_HasContent(const SwFieldPortion &rField, SwTextFormatInfo const &rInf)
Definition: portxt.cxx:274
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
bool InFieldGrp() const
Definition: porlin.hxx:104
bool Format_(SwTextFormatInfo &rInf)
Definition: portxt.cxx:280
SwPosSize GetTextSize(OutputDevice *pOut, const SwScriptInfo *pSI, const OUString &rText, TextFrameIndex nIdx, TextFrameIndex nLen) const
Definition: inftxt.cxx:382
virtual void Text(TextFrameIndex nLength, PortionType nType, sal_Int32 nHeight=0, sal_Int32 nWidth=0)=0
(empty) destructor
bool AlternativeSpelling(const SwTextFormatInfo &rInf, const TextFrameIndex nPos)
Definition: guess.cxx:564
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
Definition: porlay.hxx:229
bool ChgHyph(const bool bNew)
Definition: inftxt.cxx:1963
bool IsFull() const
Definition: inftxt.hxx:569
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: portxt.cxx:524
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: portxt.cxx:797
bool IsControlCharPortion() const
Definition: porlin.hxx:136
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:170
sw::WrongListIterator * GetSmartTags() const
Definition: inftxt.hxx:461
LINESTYLE_NONE
bool IsBreakPortion() const
Definition: porlin.hxx:114
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_Unicode GetChar(TextFrameIndex const nPos) const
Definition: inftxt.hxx:247
#define CH_TXT_ATR_INPUTFIELDSTART
Definition: hintids.hxx:174
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
void DrawCheckBox(const SwFieldFormCheckboxPortion &rPor, bool bChecked) const
Definition: inftxt.cxx:1097
oslFileHandle & pOut
TextFrameIndex BreakStart() const
Definition: guess.hxx:55
static sal_uInt16 MayUnderflow(const SwTextFormatInfo &rInf, TextFrameIndex nIdx, bool bUnderflow)
If a Line is full of HardBlanks and overflows, we must not generate underflows! Causes problems with ...
Definition: porexp.cxx:104
void SetUnderline(const FontLineStyle eUnderline)
Definition: swfont.hxx:542
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: portxt.cxx:439
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const override
Definition: porfld.cxx:441
TextFrameIndex GetLineStart() const
Definition: inftxt.hxx:596
TextFrameIndex BreakPos() const
Definition: guess.hxx:56
void DrawRect(const tools::Rectangle &rRect)
bool InFixMargGrp() const
Definition: porlin.hxx:108
This portion represents a part of the paragraph string.
Definition: portxt.hxx:27
static bool IsArabicText(const OUString &rText, TextFrameIndex nStt, TextFrameIndex nLen)
Checks if text is Arabic text.
Definition: porlay.cxx:2128
static SwTextPortion * CopyLinePortion(const SwLinePortion &rPortion)
Definition: portxt.cxx:211
void SetEndHyph(const bool bNew)
Definition: porlay.hxx:112
bool IsCombinedPortion() const
Definition: porlin.hxx:129
const SwViewOption & GetOpt() const
Definition: inftxt.hxx:245
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: portxt.cxx:787
void SetLineColor()
virtual TextFrameIndex GetModelPositionForViewPoint(sal_uInt16 nOfst) const
the parameter is actually SwTwips apparently?
Definition: porlin.cxx:222
SwPosSize(const sal_uInt16 nW=0, const sal_uInt16 nH=0)
Definition: possiz.hxx:31
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const
Definition: porlin.cxx:310
const sal_Unicode CH_FULL_BLANK
Definition: swfont.hxx:47
virtual SwLinePortion * Compress() override
Definition: portxt.cxx:755
SwTwips GetLineWidth()
Returns the distance between the current horizontal position and the end of the line.
Definition: inftxt.cxx:1755
vcl::RenderContext * GetOut()
Definition: inftxt.hxx:231
SwPageFrame * FindPageFrame()
Definition: frame.hxx:660
SwParaPortion * GetParaPortion()
Definition: inftxt.hxx:128
void SetWhichPor(const PortionType nNew)
Definition: porlin.hxx:94
void SetUnderflow(SwLinePortion *pNew)
Definition: inftxt.hxx:607
bool IsFlyPortion() const
Definition: porlin.hxx:125
SwTextGridItem const * GetGridItem(SwPageFrame const *const)
Definition: pagechg.cxx:2545
TextFrameIndex CutPos() const
Definition: guess.hxx:54
FontLineStyle GetOverline() const
Definition: swfont.hxx:270
const sal_Unicode CH_BLANK
Definition: swfont.hxx:42
bool IsKernPortion() const
Definition: porlin.hxx:132
sal_uInt16 GetTopBorderSpace() const
Definition: swfont.hxx:855
bool HasArea() const
Definition: swrect.hxx:288
void SetFillColor()
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:179
void CalcRect(const SwLinePortion &rPor, SwRect *pRect, SwRect *pIntersect=nullptr, const bool bInsideBox=false) const
Calculate the rectangular area where the portion takes place.
Definition: inftxt.cxx:752
sal_uInt16 Width() const
Definition: inftxt.hxx:534
SwLineLayout * GetRoot()
Definition: inftxt.hxx:563
bool NotEOL() const
Definition: inftxt.hxx:201
static bool IsExportTaggedPDF(const OutputDevice &rOut)
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:278
bool IsDropPortion() const
Definition: porlin.hxx:121
ITALIC_NONE
void PrePaint(const SwTextPaintInfo &rInf, const SwLinePortion *pLast) const
Definition: porlin.cxx:76
static bool IsFieldShadings()
Definition: viewopt.hxx:653
bool SnapToGrid() const
Definition: inftxt.hxx:222
TextFrameIndex GetLen() const
Definition: porlin.hxx:74
sw::WrongListIterator * GetpWrongList() const
Definition: inftxt.hxx:455
bool InTabGrp() const
Definition: porlin.hxx:100
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:291
sal_Int32 nLineWidth
const OUString & GetText() const
Definition: inftxt.hxx:246
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const override
Definition: portxt.cxx:717
virtual TextFrameIndex GetModelPositionForViewPoint(sal_uInt16 nOfst) const override
the parameter is actually SwTwips apparently?
Definition: portxt.cxx:502
#define LANGUAGE_THAI
bool IsHolePortion() const
Definition: porlin.hxx:126
void Truncate()
Definition: porlin.hxx:196
SwLinePortion * mpNextPortion
Definition: porlin.hxx:54
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
FontLineStyle GetUnderline() const
Definition: swfont.hxx:268
SwTwips X() const
Definition: inftxt.hxx:385
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: portxt.cxx:803
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:50
virtual long CalcSpacing(long nSpaceAdd, const SwTextSizeInfo &rInf) const override
Definition: portxt.cxx:612
void Left(const long nLeft)
Definition: swrect.hxx:195
void SetSoftHyphPos(TextFrameIndex const nNew)
Definition: inftxt.hxx:610
bool CreateHyphen(SwTextFormatInfo &rInf, SwTextGuess const &rGuess)
Definition: txthyph.cxx:252
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: portxt.cxx:680
#define CH_TXT_ATR_INPUTFIELDEND
Definition: hintids.hxx:175
sal_Int16 ScriptType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1627
bool IsHyphenate() const
If the Hyphenator returns ERROR or the language is set to NOLANGUAGE we do not hyphenate.
Definition: inftxt.cxx:1480
tools::Rectangle SVRect() const
Definition: swrect.hxx:280
void SetLen(const TextFrameIndex nNew)
Definition: inftxt.hxx:281
virtual bool GetExpText(const SwTextSizeInfo &rInf, OUString &rText) const override
Definition: portxt.cxx:566
bool InExpGrp() const
Definition: porlin.hxx:107
For the text replacement and restoration of SwTextSizeInfo.
Definition: inftxt.hxx:680
unsigned char sal_uInt8
PortionType GetWhichPor() const
Definition: porlin.hxx:95
void Width(long nNew)
Definition: swrect.hxx:187
bool IsFootnotePortion() const
Definition: porlin.hxx:120
FontItalic GetItalic() const
Definition: swfont.hxx:278
bool IsErgoSumPortion() const
Definition: porlin.hxx:115
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: portxt.cxx:757
static TextFrameIndex ThaiJustify(const OUString &rText, long *pKernArray, long *pScrArray, TextFrameIndex nIdx, TextFrameIndex nLen, TextFrameIndex nNumberOfBlanks=TextFrameIndex(0), long nSpaceAdd=0)
Performs a thai justification on the kerning array.
Definition: porlay.cxx:2302
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:175
bool OnWin() const
Definition: inftxt.hxx:199
bool IsRightToLeft() const
Definition: frame.hxx:965
SwHangingPortion * GetHangingPortion() const
Definition: guess.hxx:51
TextFrameIndex GetLen() const
Definition: inftxt.hxx:280
sal_uInt16 GetBottomBorderSpace() const
Definition: swfont.hxx:870
virtual bool Format(SwTextFormatInfo &rInf) override
Definition: portxt.cxx:826
static bool isKorean(LanguageType nLang)
sal_uInt16 Width() const
Definition: possiz.hxx:46
TextFrameIndex GetSpaceCnt(const SwTextSizeInfo &rInf, TextFrameIndex &rCnt) const
Definition: portxt.cxx:573
SwLinePortion * GetLast()
Definition: inftxt.hxx:567
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:181
void SetNextPortion(SwLinePortion *pNew)
Definition: porlin.hxx:76
bool IsSnapToChars() const
Definition: tgrditem.hxx:100
SwHangingPortion * ReleaseHangingPortion()
Definition: guess.hxx:52
size_t CountKashida() const
Definition: scriptinfo.hxx:150
bool IsFakeLineStart() const
Definition: inftxt.hxx:578
void SetAscent(const sal_uInt16 nNewAsc)
Definition: porlin.hxx:79
void BreakUnderflow(SwTextFormatInfo &rInf)
Definition: portxt.cxx:264
#define SPACING_PRECISION_FACTOR
Definition: scriptinfo.hxx:39
virtual void HandlePortion(SwPortionHandler &rPH) const override
Definition: portxt.cxx:792
SwDoc & GetDoc()
Definition: txtfrm.hxx:451
bool IsOtherThanFootnoteInside() const
Definition: inftxt.hxx:208
SwTextGrid GetGridType() const
Definition: tgrditem.hxx:81
virtual void Paint(const SwTextPaintInfo &rInf) const override
Definition: portxt.cxx:809
STRIKEOUT_NONE
virtual SwPosSize GetTextSize(const SwTextSizeInfo &rInfo) const override
Definition: portxt.cxx:509
SwFlyPortion * GetFly()
Definition: inftxt.hxx:615
void SetMidHyph(const bool bNew)
Definition: porlay.hxx:114
bool GetJoinBorderWithNext() const
Definition: porlin.hxx:169
SwLinePortion * GetNextPortion() const
Definition: porlin.hxx:72
static TextFrameIndex CountCJKCharacters(const OUString &rText, TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang)
Definition: porlay.cxx:2618
void Push(PushFlags nFlags=PushFlags::ALL)
sal_Int32 KashidaJustify(long *pKernArray, long *pScrArray, TextFrameIndex nStt, TextFrameIndex nLen, long nSpaceAdd=0) const
Performs a kashida justification on the kerning array.
Definition: porlay.cxx:2043
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...
virtual SwPosSize GetTextSize(const SwTextSizeInfo &rInfo) const override
Definition: portxt.cxx:735
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1238
aStr
sal_uInt16 & GetAscent()
Definition: porlin.hxx:77
#define COMPLEX
virtual SwLinePortion * Insert(SwLinePortion *pPortion)
Definition: porlin.cxx:168
void DrawMarkedText(const SwLinePortion &rPor, TextFrameIndex nLen, const bool bWrong, const bool bSmartTags, const bool bGrammarCheck) const
Definition: inftxt.hxx:761
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
TextFrameIndex GetSoftHyphPos() const
Definition: inftxt.hxx:609
void DrawViewOpt(const SwLinePortion &rPor, PortionType nWhich) const
Definition: inftxt.cxx:1315
sal_uInt16 nPos
bool IsPostItsPortion() const
Definition: porlin.hxx:128
virtual void HandlePortion(SwPortionHandler &rPH) const override
Definition: portxt.cxx:669
const css::uno::Reference< css::linguistic2::XHyphenatedWord > & HyphWord() const
Definition: guess.hxx:58
sal_uInt16 GetAscent() const
Definition: inftxt.hxx:713
bool IsBlankPortion() const
Definition: porlin.hxx:113
const sal_Unicode CH_SIX_PER_EM
Definition: swfont.hxx:49