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