LibreOffice Module sw (master)  1
fntcap.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 #include <editeng/cmapitem.hxx>
22 #include <editeng/svxfont.hxx>
23 
24 #include <vcl/outdev.hxx>
25 #include <com/sun/star/i18n/CharType.hpp>
26 #include <com/sun/star/i18n/WordType.hpp>
27 #include <com/sun/star/i18n/XBreakIterator.hpp>
28 
29 #include <vcl/print.hxx>
30 #include <fntcache.hxx>
31 #include <swfont.hxx>
32 #include <breakit.hxx>
33 #include <txtfrm.hxx>
34 #include <scriptinfo.hxx>
35 #include <fntcap.hxx>
36 
37 using namespace ::com::sun::star::i18n;
38 
39 // The information encapsulated in SwCapitalInfo is required
40 // by the ::Do functions. They contain the information about
41 // the original string, whereas rDo.GetInf() contains information
42 // about the display string.
44 {
45 public:
46  explicit SwCapitalInfo( const OUString& rOrigText ) :
47  rString( rOrigText ), nIdx( 0 ), nLen( 0 ) {};
48  const OUString& rString;
51 };
52 
53 // rFnt: required for CalcCaseMap
54 // rOrigString: The original string
55 // nOfst: Position of the substring in rOrigString
56 // nLen: Length if the substring in rOrigString
57 // nIdx: Referes to a position in the display string and should be mapped
58 // to a position in rOrigString
60  const OUString& rOrigString,
61  TextFrameIndex const nOfst,
62  TextFrameIndex const nLen,
63  TextFrameIndex const nIdx)
64 {
65  int j = 0;
66  const TextFrameIndex nEnd = nOfst + nLen;
67  OSL_ENSURE( sal_Int32(nEnd) <= rOrigString.getLength(), "sw_CalcCaseMap: Wrong parameters" );
68 
69  // special case for title case:
70  const bool bTitle = SvxCaseMap::Capitalize == rFnt.GetCaseMap();
71  for (TextFrameIndex i = nOfst; i < nEnd; ++i)
72  {
73  OUString aTmp(rOrigString.copy(sal_Int32(i), 1));
74 
75  if ( !bTitle ||
76  g_pBreakIt->GetBreakIter()->isBeginWord(
77  rOrigString, sal_Int32(i),
78  g_pBreakIt->GetLocale( rFnt.GetLanguage() ),
79  WordType::ANYWORD_IGNOREWHITESPACES ) )
80  aTmp = rFnt.GetActualFont().CalcCaseMap( aTmp );
81 
82  j += aTmp.getLength();
83 
84  if (TextFrameIndex(j) > nIdx)
85  return i;
86  }
87 
88  return nOfst + nLen;
89 }
90 
92 {
93 protected:
95  SwCapitalInfo* pCapInf; // referes to additional information
96  // required by the ::Do function
97  explicit SwDoCapitals ( SwDrawTextInfo &rInfo ) : rInf( rInfo ), pCapInf( nullptr ) { }
99 public:
100  virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) = 0;
101  virtual void Do() = 0;
102  OutputDevice& GetOut() { return rInf.GetOut(); }
103  SwDrawTextInfo& GetInf() { return rInf; }
104  SwCapitalInfo* GetCapInf() const { return pCapInf; }
105  void SetCapInf( SwCapitalInfo& rNew ) { pCapInf = &rNew; }
106 };
107 
109 {
110 protected:
112 public:
113  explicit SwDoGetCapitalSize( SwDrawTextInfo &rInfo ) : SwDoCapitals ( rInfo ) { }
114  virtual ~SwDoGetCapitalSize() {}
115  virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
116  virtual void Do() override;
117  const Size &GetSize() const { return aTextSize; }
118 };
119 
121 {
122  aTextSize.setHeight( 0 );
123  aTextSize.setWidth( 0 );
124 }
125 
127 {
129  if( rInf.GetUpper() )
131 }
132 
134 {
135  // Start:
136  const long nOldKern = rInf.GetKern();
137  rInf.SetKern( CheckKerning() );
138  rInf.SetPos( Point() );
139  rInf.SetSpace( 0 );
140  rInf.SetDrawSpace( false );
141  SwDoGetCapitalSize aDo( rInf );
142  DoOnCapitals( aDo );
143  Size aTextSize( aDo.GetSize() );
144 
145  // End:
146  if( !aTextSize.Height() )
147  {
148  SV_STAT( nGetTextSize );
149  aTextSize.setHeight( short ( rInf.GetpOut()->GetTextHeight() ) );
150  }
151  rInf.SetKern( nOldKern );
152  return aTextSize;
153 }
154 
156 {
157 protected:
160 
161 public:
162  SwDoGetCapitalBreak( SwDrawTextInfo &rInfo, long const nWidth)
163  : SwDoCapitals ( rInfo )
164  , nTextWidth( nWidth )
165  , m_nBreak( -1 )
166  { }
167  virtual ~SwDoGetCapitalBreak() {}
168  virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
169  virtual void Do() override;
170  TextFrameIndex getBreak() const { return m_nBreak; }
171 };
172 
174 {
175 }
176 
178 {
179  if ( nTextWidth )
180  {
181  if ( rInf.GetSize().Width() < nTextWidth )
182  nTextWidth -= rInf.GetSize().Width();
183  else
184  {
185  TextFrameIndex nEnd = rInf.GetEnd();
186  m_nBreak = TextFrameIndex(GetOut().GetTextBreak(
187  rInf.GetText(), nTextWidth, sal_Int32(rInf.GetIdx()),
188  sal_Int32(rInf.GetLen()), rInf.GetKern()));
189 
190  if (m_nBreak > nEnd || m_nBreak < TextFrameIndex(0))
191  m_nBreak = nEnd;
192 
193  // m_nBreak may be relative to the display string. It has to be
194  // calculated relative to the original string:
195  if ( GetCapInf() )
196  {
197  if ( GetCapInf()->nLen != rInf.GetLen() )
199  GetCapInf()->rString,
200  GetCapInf()->nIdx,
201  GetCapInf()->nLen, m_nBreak );
202  else
204  }
205 
206  nTextWidth = 0;
207  }
208  }
209 }
210 
212  const SwScriptInfo* pScript, const OUString& rText, long const nTextWidth,
213  TextFrameIndex const nIdx, TextFrameIndex const nLen)
214 {
215  // Start:
216  Point aPos( 0, 0 );
217  SwDrawTextInfo aInfo(pSh, *const_cast<OutputDevice*>(pOut), pScript, rText, nIdx, nLen,
218  0, false);
219  aInfo.SetPos( aPos );
220  aInfo.SetSpace( 0 );
221  aInfo.SetWrong( nullptr );
222  aInfo.SetGrammarCheck( nullptr );
223  aInfo.SetSmartTags( nullptr );
224  aInfo.SetDrawSpace( false );
225  aInfo.SetKern( CheckKerning() );
226  aInfo.SetKanaComp( pScript ? 0 : 100 );
227  aInfo.SetFont( this );
228 
229  SwDoGetCapitalBreak aDo(aInfo, nTextWidth);
230  DoOnCapitals( aDo );
231  return aDo.getBreak();
232 }
233 
235 {
236 protected:
239 public:
240  explicit SwDoDrawCapital( SwDrawTextInfo &rInfo ) :
241  SwDoCapitals( rInfo ), pUpperFnt(nullptr), pLowerFnt(nullptr)
242  { }
243  virtual ~SwDoDrawCapital() {}
244  virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
245  virtual void Do() override;
246  void DrawSpace( Point &rPos );
247 };
248 
249 void SwDoDrawCapital::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
250 {
251  pUpperFnt = pUpperFont;
252  pLowerFnt = pLowerFont;
253 }
254 
256 {
257  SV_STAT( nDrawText );
258  const sal_uInt16 nOrgWidth = rInf.GetWidth();
259  rInf.SetWidth( sal_uInt16(rInf.GetSize().Width()) );
260  if ( rInf.GetUpper() )
261  pUpperFnt->DrawText( rInf );
262  else
263  {
264  bool bOldBullet = rInf.GetBullet();
265  rInf.SetBullet( false );
266  pLowerFnt->DrawText( rInf );
267  rInf.SetBullet( bOldBullet );
268  }
269 
270  OSL_ENSURE( pUpperFnt, "No upper font, dying soon!");
272  rInf.SetWidth( nOrgWidth );
273 }
274 
276 {
277  long nDiff = rInf.GetPos().X() - rPos.X();
278 
279  Point aPos( rPos );
280  const bool bSwitchL2R = rInf.GetFrame()->IsRightToLeft() &&
282 
283  if ( bSwitchL2R )
284  rInf.GetFrame()->SwitchLTRtoRTL( aPos );
285 
287  const bool bBidiPor = ( bSwitchL2R !=
288  ( ComplexTextLayoutFlags::Default != ( ComplexTextLayoutFlags::BiDiRtl & nMode ) ) );
289 
290  if ( bBidiPor )
291  nDiff = -nDiff;
292 
293  if ( rInf.GetFrame()->IsVertical() )
295 
296  if ( nDiff )
297  {
299  GetOut().DrawStretchText( aPos, nDiff,
300  " ", 0, 2 );
301  }
302  rPos.setX( rInf.GetPos().X() + rInf.GetWidth() );
303 }
304 
306 {
307  // Precondition: rInf.GetPos() has already been calculated
308 
309  rInf.SetDrawSpace( GetUnderline() != LINESTYLE_NONE ||
310  GetOverline() != LINESTYLE_NONE ||
311  GetStrikeout() != STRIKEOUT_NONE );
312  SwDoDrawCapital aDo( rInf );
313  DoOnCapitals( aDo );
314 }
315 
317 {
318 protected:
322  sal_uInt16 nOfst;
323 public:
324  SwDoCapitalCursorOfst( SwDrawTextInfo &rInfo, const sal_uInt16 nOfs ) :
325  SwDoCapitals( rInfo ), pUpperFnt(nullptr), pLowerFnt(nullptr), nCursor( 0 ), nOfst( nOfs )
326  { }
328  virtual void Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont ) override;
329  virtual void Do() override;
330 
332 };
333 
334 void SwDoCapitalCursorOfst::Init( SwFntObj *pUpperFont, SwFntObj *pLowerFont )
335 {
336  pUpperFnt = pUpperFont;
337  pLowerFnt = pLowerFont;
338 }
339 
341 {
342  if ( nOfst )
343  {
344  if ( static_cast<long>(nOfst) > rInf.GetSize().Width() )
345  {
346  nOfst -= rInf.GetSize().Width();
347  nCursor = nCursor + rInf.GetLen();
348  }
349  else
350  {
351  SwDrawTextInfo aDrawInf( rInf.GetShell(), *rInf.GetpOut(),
353  rInf.GetText(),
354  rInf.GetIdx(),
355  rInf.GetLen(), 0, false );
356  aDrawInf.SetOfst( nOfst );
357  aDrawInf.SetKern( rInf.GetKern() );
358  aDrawInf.SetKanaComp( rInf.GetKanaComp() );
359  aDrawInf.SetFrame( rInf.GetFrame() );
360  aDrawInf.SetFont( rInf.GetFont() );
361 
362  if ( rInf.GetUpper() )
363  {
364  aDrawInf.SetSpace( 0 );
365  nCursor = nCursor + pUpperFnt->GetCursorOfst( aDrawInf );
366  }
367  else
368  {
369  aDrawInf.SetSpace( rInf.GetSpace() );
370  nCursor = nCursor + pLowerFnt->GetCursorOfst( aDrawInf );
371  }
372  nOfst = 0;
373  }
374  }
375 }
376 
378 {
379  const long nOldKern = rInf.GetKern();
380  rInf.SetKern( CheckKerning() );
381  SwDoCapitalCursorOfst aDo( rInf, rInf.GetOfst() );
382  rInf.SetPos( Point() );
383  rInf.SetDrawSpace( false );
384  DoOnCapitals( aDo );
385  rInf.SetKern( nOldKern );
386  return aDo.GetCursor();
387 }
388 
390 {
392  const sal_uInt16 nCapWidth;
393  const sal_uInt16 nOrgWidth;
394 public:
395  virtual void Do() override;
396 
397  SwDoDrawStretchCapital( SwDrawTextInfo &rInfo, const sal_uInt16 nCapitalWidth )
398  : SwDoDrawCapital( rInfo ),
399  nStrLen( rInfo.GetLen() ),
400  nCapWidth( nCapitalWidth ),
401  nOrgWidth( rInfo.GetWidth() )
402  { }
403 };
404 
406 {
407  SV_STAT( nDrawStretchText );
408  long nPartWidth = rInf.GetSize().Width();
409 
410  if( rInf.GetLen() )
411  {
412  // small caps and kerning
413  long nDiff = long(nOrgWidth) - long(nCapWidth);
414  if( nDiff )
415  {
416  nDiff *= sal_Int32(rInf.GetLen());
417  nDiff /= sal_Int32(nStrLen);
418  nDiff += nPartWidth;
419  if( 0 < nDiff )
420  nPartWidth = nDiff;
421  }
422 
424 
425  Point aPos( rInf.GetPos() );
426  const bool bSwitchL2R = rInf.GetFrame()->IsRightToLeft() &&
428 
429  if ( bSwitchL2R )
430  rInf.GetFrame()->SwitchLTRtoRTL( aPos );
431 
432  if ( rInf.GetFrame()->IsVertical() )
434 
435  // Optimise:
436  if (TextFrameIndex(1) >= rInf.GetLen())
437  GetOut().DrawText(aPos, rInf.GetText(), sal_Int32(rInf.GetIdx()),
438  sal_Int32(rInf.GetLen()));
439  else
440  GetOut().DrawStretchText(aPos, nPartWidth, rInf.GetText(),
441  sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
442  }
443  const_cast<Point&>(rInf.GetPos()).AdjustX(nPartWidth );
444 }
445 
447 {
448  // Precondition: rInf.GetPos() has already been calculated
449 
450  if (rInf.GetLen() == TextFrameIndex(COMPLETE_STRING))
451  rInf.SetLen(TextFrameIndex(rInf.GetText().getLength()));
452 
453  const Point aOldPos = rInf.GetPos();
454  const sal_uInt16 nCapWidth = static_cast<sal_uInt16>( GetCapitalSize( rInf ).Width() );
455  rInf.SetPos(aOldPos);
456 
457  rInf.SetDrawSpace( GetUnderline() != LINESTYLE_NONE ||
458  GetOverline() != LINESTYLE_NONE ||
459  GetStrikeout() != STRIKEOUT_NONE );
460  SwDoDrawStretchCapital aDo( rInf, nCapWidth );
461  DoOnCapitals( aDo );
462 }
463 
465 {
466  OSL_ENSURE( pLastFont, "SwFont::DoOnCapitals: No LastFont?!" );
467 
468  long nKana = 0;
469  const OUString aText( CalcCaseMap( rDo.GetInf().GetText() ) );
470  TextFrameIndex nMaxPos = std::min(
471  TextFrameIndex(rDo.GetInf().GetText().getLength()) - rDo.GetInf().GetIdx(),
472  rDo.GetInf().GetLen() );
473  rDo.GetInf().SetLen( nMaxPos );
474 
475  const OUString oldText = rDo.GetInf().GetText();
476  rDo.GetInf().SetText( aText );
477  TextFrameIndex nPos = rDo.GetInf().GetIdx();
478  TextFrameIndex nOldPos = nPos;
479  nMaxPos = nMaxPos + nPos;
480 
481  // Look if the length of the original text and the ToUpper-converted
482  // text is different. If yes, do special handling.
483  SwCapitalInfo aCapInf(oldText);
484  bool bCaseMapLengthDiffers(aText.getLength() != oldText.getLength());
485  if ( bCaseMapLengthDiffers )
486  rDo.SetCapInf( aCapInf );
487 
488  SwFntObj *pOldLast = pLastFont;
489  std::unique_ptr<SwFntAccess> pBigFontAccess;
490  SwFntObj *pBigFont;
491  std::unique_ptr<SwFntAccess> pSpaceFontAccess;
492  SwFntObj *pSpaceFont = nullptr;
493 
494  const void* nFontCacheId2 = nullptr;
495  sal_uInt16 nIndex2 = 0;
496  SwSubFont aFont( *this );
497  Point aStartPos( rDo.GetInf().GetPos() );
498 
499  const bool bTextLines = aFont.GetUnderline() != LINESTYLE_NONE
500  || aFont.GetOverline() != LINESTYLE_NONE
501  || aFont.GetStrikeout() != STRIKEOUT_NONE;
502  const bool bWordWise = bTextLines && aFont.IsWordLineMode() &&
503  rDo.GetInf().GetDrawSpace();
504  const long nTmpKern = rDo.GetInf().GetKern();
505 
506  if ( bTextLines )
507  {
508  if ( bWordWise )
509  {
510  aFont.SetWordLineMode( false );
511  pSpaceFontAccess.reset(new SwFntAccess( nFontCacheId2, nIndex2, &aFont,
512  rDo.GetInf().GetShell() ));
513  pSpaceFont = pSpaceFontAccess->Get();
514  }
515  else
516  pSpaceFont = pLastFont;
517 
518  // Construct a font for the capitals:
519  aFont.SetUnderline( LINESTYLE_NONE );
520  aFont.SetOverline( LINESTYLE_NONE );
521  aFont.SetStrikeout( STRIKEOUT_NONE );
522  nFontCacheId2 = nullptr;
523  nIndex2 = 0;
524  pBigFontAccess.reset(new SwFntAccess( nFontCacheId2, nIndex2, &aFont,
525  rDo.GetInf().GetShell() ));
526  pBigFont = pBigFontAccess->Get();
527  }
528  else
529  pBigFont = pLastFont;
530 
531  // Older LO versions had 66 as the small caps percentage size, later changed to 80,
532  // therefore a backwards compatibility option is kept (otherwise layout is changed).
533  // NOTE: There are more uses of SMALL_CAPS_PERCENTAGE in editeng, but it seems they
534  // do not matter for Writer (and if they did it'd be pretty ugly to propagate
535  // the option there).
536  int smallCapsPercentage = m_bSmallCapsPercentage66 ? 66 : SMALL_CAPS_PERCENTAGE;
537  aFont.SetProportion( (aFont.GetPropr() * smallCapsPercentage ) / 100 );
538  nFontCacheId2 = nullptr;
539  nIndex2 = 0;
540  std::unique_ptr<SwFntAccess> pSmallFontAccess( new SwFntAccess( nFontCacheId2, nIndex2, &aFont,
541  rDo.GetInf().GetShell() ));
542  SwFntObj *pSmallFont = pSmallFontAccess->Get();
543 
544  rDo.Init( pBigFont, pSmallFont );
545  OutputDevice* pOutSize = pSmallFont->GetPrt();
546  if( !pOutSize )
547  pOutSize = &rDo.GetOut();
548  OutputDevice* pOldOut = &rDo.GetOut();
549 
550  const LanguageType eLng = LANGUAGE_DONTKNOW == GetLanguage()
552 
553  if( nPos < nMaxPos )
554  {
555  nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->endOfCharBlock(
556  oldText, sal_Int32(nPos),
557  g_pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER));
558  if (nPos < TextFrameIndex(0))
559  nPos = nOldPos;
560  else if( nPos > nMaxPos )
561  nPos = nMaxPos;
562  }
563 
564  while( nOldPos < nMaxPos )
565  {
566 
567  // The lower ones...
568  if( nOldPos != nPos )
569  {
570  SV_STAT( nGetTextSize );
571  pLastFont = pSmallFont;
572  pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
573 
574  // #107816#, #i14820#
575  if( bCaseMapLengthDiffers )
576  {
577  // Build an own 'changed' string for the given part of the
578  // source string and use it. That new string may differ in length
579  // from the source string.
580  const OUString aNewText = CalcCaseMap(
581  oldText.copy(sal_Int32(nOldPos), sal_Int32(nPos-nOldPos)));
582  aCapInf.nIdx = nOldPos;
583  aCapInf.nLen = nPos - nOldPos;
584  rDo.GetInf().SetIdx(TextFrameIndex(0));
585  rDo.GetInf().SetLen(TextFrameIndex(aNewText.getLength()));
586  rDo.GetInf().SetText( aNewText );
587  }
588  else
589  {
590  rDo.GetInf().SetIdx( nOldPos );
591  rDo.GetInf().SetLen( nPos - nOldPos );
592  }
593 
594  rDo.GetInf().SetUpper( false );
595  rDo.GetInf().SetOut( *pOutSize );
596  Size aPartSize = pSmallFont->GetTextSize( rDo.GetInf() );
597  nKana += rDo.GetInf().GetKanaDiff();
598  rDo.GetInf().SetOut( *pOldOut );
599  if( nTmpKern && nPos < nMaxPos )
600  aPartSize.AdjustWidth(nTmpKern );
601  rDo.GetInf().SetSize( aPartSize );
602  rDo.Do();
603  nOldPos = nPos;
604  }
605  nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->nextCharBlock(
606  oldText, sal_Int32(nPos),
607  g_pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER));
608  if (nPos < TextFrameIndex(0) || nPos > nMaxPos)
609  nPos = nMaxPos;
610  OSL_ENSURE( nPos, "nextCharBlock not implemented?" );
611 #if OSL_DEBUG_LEVEL > 1
612  if( !nPos )
613  nPos = nMaxPos;
614 #endif
615  // The upper ones...
616  if( nOldPos != nPos )
617  {
618  const long nSpaceAdd = rDo.GetInf().GetSpace() / SPACING_PRECISION_FACTOR;
619 
620  do
621  {
622  rDo.GetInf().SetUpper( true );
623  pLastFont = pBigFont;
624  pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
625  TextFrameIndex nTmp;
626  if( bWordWise )
627  {
628  nTmp = nOldPos;
629  while (nTmp < nPos && CH_BLANK == oldText[sal_Int32(nTmp)])
630  ++nTmp;
631  if( nOldPos < nTmp )
632  {
633  pLastFont = pSpaceFont;
635  rDo.GetOut() );
636  static_cast<SwDoDrawCapital&>(rDo).DrawSpace( aStartPos );
637  pLastFont = pBigFont;
639  rDo.GetOut() );
640 
641  // #107816#, #i14820#
642  if( bCaseMapLengthDiffers )
643  {
644  // Build an own 'changed' string for the given part of the
645  // source string and use it. That new string may differ in length
646  // from the source string.
647  const OUString aNewText = CalcCaseMap(
648  oldText.copy(sal_Int32(nOldPos), sal_Int32(nTmp-nOldPos)));
649  aCapInf.nIdx = nOldPos;
650  aCapInf.nLen = nTmp - nOldPos;
651  rDo.GetInf().SetIdx(TextFrameIndex(0));
652  rDo.GetInf().SetLen(TextFrameIndex(aNewText.getLength()));
653  rDo.GetInf().SetText( aNewText );
654  }
655  else
656  {
657  rDo.GetInf().SetIdx( nOldPos );
658  rDo.GetInf().SetLen( nTmp - nOldPos );
659  }
660 
661  rDo.GetInf().SetOut( *pOutSize );
662  Size aPartSize = pBigFont->GetTextSize( rDo.GetInf() );
663  nKana += rDo.GetInf().GetKanaDiff();
664  rDo.GetInf().SetOut( *pOldOut );
665  if( nSpaceAdd )
666  aPartSize.AdjustWidth(nSpaceAdd * sal_Int32(nTmp - nOldPos));
667  if( nTmpKern && nPos < nMaxPos )
668  aPartSize.AdjustWidth(nTmpKern );
669  rDo.GetInf().SetSize( aPartSize );
670  rDo.Do();
671  aStartPos = rDo.GetInf().GetPos();
672  nOldPos = nTmp;
673  }
674 
675  while (nTmp < nPos && CH_BLANK != oldText[sal_Int32(nTmp)])
676  ++nTmp;
677  }
678  else
679  nTmp = nPos;
680  if( nTmp > nOldPos )
681  {
682  // #107816#, #i14820#
683  if( bCaseMapLengthDiffers )
684  {
685  // Build an own 'changed' string for the given part of the
686  // source string and use it. That new string may differ in length
687  // from the source string.
688  const OUString aNewText = CalcCaseMap(
689  oldText.copy(sal_Int32(nOldPos), sal_Int32(nTmp-nOldPos)));
690  aCapInf.nIdx = nOldPos;
691  aCapInf.nLen = nTmp - nOldPos;
692  rDo.GetInf().SetIdx(TextFrameIndex(0));
693  rDo.GetInf().SetLen(TextFrameIndex(aNewText.getLength()));
694  rDo.GetInf().SetText( aNewText );
695  }
696  else
697  {
698  rDo.GetInf().SetIdx( nOldPos );
699  rDo.GetInf().SetLen( nTmp - nOldPos );
700  }
701 
702  rDo.GetInf().SetOut( *pOutSize );
703  Size aPartSize = pBigFont->GetTextSize( rDo.GetInf() );
704  nKana += rDo.GetInf().GetKanaDiff();
705  rDo.GetInf().SetOut( *pOldOut );
706  if( !bWordWise && rDo.GetInf().GetSpace() )
707  {
708  for (TextFrameIndex nI = nOldPos; nI < nPos; ++nI)
709  {
710  if (CH_BLANK == oldText[sal_Int32(nI)])
711  aPartSize.AdjustWidth(nSpaceAdd );
712  }
713  }
714  if( nTmpKern && nPos < nMaxPos )
715  aPartSize.AdjustWidth(nTmpKern );
716  rDo.GetInf().SetSize( aPartSize );
717  rDo.Do();
718  nOldPos = nTmp;
719  }
720  } while( nOldPos != nPos );
721  }
722  nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->endOfCharBlock(
723  oldText, sal_Int32(nPos),
724  g_pBreakIt->GetLocale( eLng ), CharType::LOWERCASE_LETTER));
725  if (nPos < TextFrameIndex(0) || nPos > nMaxPos)
726  nPos = nMaxPos;
727  OSL_ENSURE( nPos, "endOfCharBlock not implemented?" );
728 #if OSL_DEBUG_LEVEL > 1
729  if( !nPos )
730  nPos = nMaxPos;
731 #endif
732  }
733 
734  // clean up:
735  if( pBigFont != pOldLast )
736  pBigFontAccess.reset();
737 
738  if( bTextLines )
739  {
740  if( rDo.GetInf().GetDrawSpace() )
741  {
742  pLastFont = pSpaceFont;
743  pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
744  static_cast<SwDoDrawCapital&>( rDo ).DrawSpace( aStartPos );
745  }
746  if ( bWordWise )
747  pSpaceFontAccess.reset();
748  }
749  pLastFont = pOldLast;
750  pLastFont->SetDevFont( rDo.GetInf().GetShell(), rDo.GetOut() );
751 
752  pSmallFontAccess.reset();
753  rDo.GetInf().SetText(oldText);
754  rDo.GetInf().SetKanaDiff( nKana );
755 }
756 
757 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetSmartTags(sw::WrongListIterator *const pNew)
Definition: drawfont.hxx:435
OutputDevice * GetPrt() const
Definition: fntcache.hxx:122
long Width() const
SwFntObj * pLastFont
Definition: fntcache.cxx:69
SwDrawTextInfo & rInf
Definition: fntcap.cxx:94
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
SwViewShell const * GetShell() const
Definition: drawfont.hxx:175
long GetSpace() const
Definition: drawfont.hxx:325
const sal_uInt16 nOrgWidth
Definition: fntcap.cxx:393
sal_uInt8 GetPropr() const
short CheckKerning()
Definition: swfont.hxx:320
TextFrameIndex GetCursor()
Definition: fntcap.cxx:331
SwCapitalInfo * pCapInf
Definition: fntcap.cxx:95
TextFrameIndex nLen
Definition: fntcap.cxx:50
vcl::RenderContext * GetpOut() const
Definition: drawfont.hxx:185
SwFont * GetFont() const
Definition: drawfont.hxx:250
bool m_bSmallCapsPercentage66
Definition: swfont.hxx:59
TextFrameIndex GetCapitalCursorOfst(SwDrawTextInfo &rInf)
Definition: fntcap.cxx:377
long AdjustWidth(long n)
void SetCapInf(SwCapitalInfo &rNew)
Definition: fntcap.cxx:105
bool GetDrawSpace() const
Definition: drawfont.hxx:359
SwDoGetCapitalBreak(SwDrawTextInfo &rInfo, long const nWidth)
Definition: fntcap.cxx:162
#define SMALL_CAPS_PERCENTAGE
TextFrameIndex GetEnd() const
Definition: drawfont.hxx:281
long Height() const
void SetSize(const Size &rNew)
Definition: drawfont.hxx:440
bool GetBullet() const
Definition: drawfont.hxx:346
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
Definition: txtfrm.cxx:483
void SetKern(long nNew)
Definition: drawfont.hxx:495
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:402
void SetIdx(TextFrameIndex const nNew)
Definition: drawfont.hxx:456
void SetUnderline(const FontLineStyle eUnderline)
Definition: swfont.hxx:536
const SvxFont & GetActualFont() const
Definition: swfont.hxx:182
void SetKanaComp(short nNew)
Definition: drawfont.hxx:531
void SetPos(const Point &rNew)
Definition: drawfont.hxx:397
ComplexTextLayoutFlags GetLayoutMode() const
sal_uInt16 GetWidth() const
Definition: drawfont.hxx:294
void SetWidth(sal_uInt16 nNew)
Definition: drawfont.hxx:482
virtual void Init(SwFntObj *pUpperFont, SwFntObj *pLowerFont) override
Definition: fntcap.cxx:120
SwDoCapitalCursorOfst(SwDrawTextInfo &rInfo, const sal_uInt16 nOfs)
Definition: fntcap.cxx:324
~SwDoCapitals()
Definition: fntcap.cxx:98
void SetKanaDiff(long nNew)
Definition: drawfont.hxx:474
void DrawCapital(SwDrawTextInfo &rInf)
Definition: fntcap.cxx:305
sal_Int32 GetOfst() const
Definition: drawfont.hxx:273
vcl::Font & GetFont()
Definition: fntcache.hxx:109
const SwScriptInfo * GetScriptInfo() const
Definition: drawfont.hxx:190
long GetLen(const Point &rPnt)
sal_uInt16 nOfst
Definition: fntcap.cxx:322
TextFrameIndex sw_CalcCaseMap(const SwFont &rFnt, const OUString &rOrigString, TextFrameIndex const nOfst, TextFrameIndex const nLen, TextFrameIndex const nIdx)
Definition: fntcap.cxx:59
void DrawStretchText(const Point &rStartPt, sal_uLong nWidth, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1)
const SwTextFrame * GetFrame() const
Definition: drawfont.hxx:165
LINESTYLE_NONE
void setX(long nX)
virtual ~SwDoDrawCapital()
Definition: fntcap.cxx:243
void SetOut(OutputDevice &rNew)
Definition: drawfont.hxx:392
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:34
TextFrameIndex GetCursorOfst(SwDrawTextInfo &rInf)
Definition: fntcache.cxx:2093
virtual void Init(SwFntObj *pUpperFont, SwFntObj *pLowerFont)=0
SvxCaseMap GetCaseMap() const
Definition: swfont.hxx:276
long GetKern() const
Definition: drawfont.hxx:320
TextFrameIndex getBreak() const
Definition: fntcap.cxx:170
TextFrameIndex nIdx
Definition: fntcap.cxx:49
sal_uInt16 GetKanaComp() const
Definition: drawfont.hxx:307
void SetWrong(sw::WrongListIterator *const pNew)
Definition: drawfont.hxx:419
void SetLen(TextFrameIndex const nNew)
Definition: drawfont.hxx:461
void Shift(sal_uInt16 nDir)
Definition: swfont.cxx:1467
const OUString & GetText() const
Definition: drawfont.hxx:216
SwDoDrawStretchCapital(SwDrawTextInfo &rInfo, const sal_uInt16 nCapitalWidth)
Definition: fntcap.cxx:397
void SetOverline(const FontLineStyle eOverline)
Definition: swfont.hxx:551
bool ApplyAutoColor(vcl::Font *pFnt=nullptr)
Definition: fntcache.cxx:2582
void SetWordLineMode(const bool bWordLineMode)
Definition: swfont.hxx:662
bool IsIgnoreFrameRTL() const
Definition: drawfont.hxx:382
virtual void Do() override
Definition: fntcap.cxx:340
void SetOfst(sal_Int32 nNew)
Definition: drawfont.hxx:466
void DrawStretchCapital(SwDrawTextInfo &rInf)
Definition: fntcap.cxx:446
SwFntObj * pUpperFnt
Definition: fntcap.cxx:237
#define LANGUAGE_SYSTEM
ComplexTextLayoutFlags
virtual void Init(SwFntObj *pUpperFont, SwFntObj *pLowerFont) override
Definition: fntcap.cxx:249
Size GetCapitalSize(SwDrawTextInfo &rInf)
Definition: fntcap.cxx:133
int i
const sal_Unicode CH_BLANK
Definition: swfont.hxx:42
void SetProportion(const sal_uInt8 nNewPropr)
Definition: swfont.hxx:754
void SetUpper(bool bNew)
Definition: drawfont.hxx:546
#define LANGUAGE_DONTKNOW
void SetBullet(bool bNew)
Definition: drawfont.hxx:536
virtual ~SwDoGetCapitalSize()
Definition: fntcap.cxx:114
void SetGrammarCheck(sw::WrongListIterator *const pNew)
Definition: drawfont.hxx:427
const Size & GetSize() const
Definition: fntcap.cxx:117
virtual void Do() override
Definition: fntcap.cxx:405
void DoOnCapitals(SwDoCapitals &rDo)
Definition: swfont.hxx:303
long GetTextHeight() const
long X() const
TextFrameIndex m_nBreak
Definition: fntcap.cxx:159
#define SV_STAT(nWhich)
Definition: swfont.hxx:996
SwFntObj * pLowerFnt
Definition: fntcap.cxx:238
void SetDrawSpace(bool bNew)
Definition: drawfont.hxx:554
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Definition: txtfrm.cxx:693
bool GetUpper() const
Definition: drawfont.hxx:351
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
SwCapitalInfo * GetCapInf() const
Definition: fntcap.cxx:104
void SetDevFont(const SwViewShell *pSh, OutputDevice &rOut)
Definition: fntcache.cxx:643
LanguageType GetLanguage() const
Definition: swfont.hxx:279
void DoOnCapitals(SwDoCapitals &rDo)
Definition: fntcap.cxx:464
short GetOrientation() const
const OUString & rString
Definition: fntcap.cxx:47
SwDoGetCapitalSize(SwDrawTextInfo &rInfo)
Definition: fntcap.cxx:113
long GetKanaDiff() const
Definition: drawfont.hxx:286
const Point & GetPos() const
Definition: drawfont.hxx:195
TextFrameIndex GetLen() const
Definition: drawfont.hxx:268
OutputDevice & GetOut()
Definition: fntcap.cxx:102
const Size & GetSize() const
Definition: drawfont.hxx:242
OUString CalcCaseMap(const OUString &rTxt) const
void DrawSpace(Point &rPos)
Definition: fntcap.cxx:275
bool IsRightToLeft() const
Definition: frame.hxx:963
SwDoDrawCapital(SwDrawTextInfo &rInfo)
Definition: fntcap.cxx:240
const TextFrameIndex nStrLen
Definition: fntcap.cxx:391
vcl::RenderContext & GetOut() const
Definition: drawfont.hxx:180
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter()
Definition: breakit.hxx:62
void DrawText(SwDrawTextInfo &rInf)
Definition: fntcache.cxx:839
bool IsVertical() const
Definition: frame.hxx:949
#define SPACING_PRECISION_FACTOR
Definition: scriptinfo.hxx:37
void SetText(const OUString &rNew)
Definition: drawfont.hxx:413
TextFrameIndex GetIdx() const
Definition: drawfont.hxx:263
void SetFont(SwFont *pNew)
Definition: drawfont.hxx:448
virtual void Do() override
Definition: fntcap.cxx:126
TextFrameIndex nCursor
Definition: fntcap.cxx:321
void SetSpace(long nNew)
Definition: drawfont.hxx:500
STRIKEOUT_NONE
SwDrawTextInfo & GetInf()
Definition: fntcap.cxx:103
virtual void Init(SwFntObj *pUpperFont, SwFntObj *pLowerFont) override
Definition: fntcap.cxx:334
SwCapitalInfo(const OUString &rOrigText)
Definition: fntcap.cxx:46
SwFntObj * pLowerFnt
Definition: fntcap.cxx:320
void SetStrikeout(const FontStrikeout eStrikeout)
Definition: swfont.hxx:566
sal_Int32 nPos
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 ~SwDoCapitalCursorOfst()
Definition: fntcap.cxx:327
void setWidth(long nWidth)
virtual void Do() override
Definition: fntcap.cxx:255
virtual void Init(SwFntObj *pUpperFont, SwFntObj *pLowerFont) override
Definition: fntcap.cxx:173
TextFrameIndex GetCapitalBreak(SwViewShell const *pSh, const OutputDevice *pOut, const SwScriptInfo *pScript, const OUString &rText, long nTextWidth, TextFrameIndex nIdx, TextFrameIndex nLen)
Definition: fntcap.cxx:211
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwFntObj * pUpperFnt
Definition: fntcap.cxx:319
const sal_uInt16 nCapWidth
Definition: fntcap.cxx:392
virtual void Do() override
Definition: fntcap.cxx:177
virtual ~SwDoGetCapitalBreak()
Definition: fntcap.cxx:167
Size GetTextSize(SwDrawTextInfo &rInf)
determine the TextSize (of the printer)
Definition: fntcache.cxx:1891
virtual void Do()=0
SwDoCapitals(SwDrawTextInfo &rInfo)
Definition: fntcap.cxx:97
short CheckKerning()
Definition: swfont.hxx:109
void setHeight(long nHeight)