Bump version to 4.1-6
[LibreOffice.git] / editeng / source / items / svxfont.cxx
blob0c6648dbce77717ae852f1f342fafe7ee04fc418
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <comphelper/string.hxx>
21 #include <vcl/outdev.hxx>
22 #include <vcl/print.hxx>
23 #include <tools/gen.hxx>
24 #include <tools/poly.hxx>
25 #include <unotools/charclass.hxx>
26 #include <editeng/unolingu.hxx>
27 #include <com/sun/star/i18n/KCharacterType.hpp>
28 #include <editeng/svxfont.hxx>
29 #include <editeng/escapementitem.hxx>
31 #ifndef REDUCEDSVXFONT
32 const sal_Unicode CH_BLANK = sal_Unicode(' '); // ' ' Space character
33 static sal_Char const sDoubleSpace[] = " ";
34 #endif
37 SvxFont::SvxFont()
39 nKern = nEsc = 0;
40 nPropr = 100;
41 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
42 eLang = LANGUAGE_SYSTEM;
45 SvxFont::SvxFont( const Font &rFont )
46 : Font( rFont )
48 nKern = nEsc = 0;
49 nPropr = 100;
50 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
51 eLang = LANGUAGE_SYSTEM;
54 SvxFont::SvxFont( const SvxFont &rFont )
55 : Font( rFont )
57 nKern = rFont.GetFixKerning();
58 nEsc = rFont.GetEscapement();
59 nPropr = rFont.GetPropr();
60 eCaseMap = rFont.GetCaseMap();
61 eLang = rFont.GetLanguage();
65 void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect,
66 const Size& rSize, const Color& rCol, sal_Bool bLeft )
68 long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
69 long nRight = nLeft + rSize.Width();
70 long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
71 long nTop = nMid - rSize.Height() / 2;
72 long nBottom = nTop + rSize.Height();
73 if( nLeft < rRect.Left() )
75 nLeft = rRect.Left();
76 nRight = rRect.Right();
78 if( nTop < rRect.Top() )
80 nTop = rRect.Top();
81 nBottom = rRect.Bottom();
83 Polygon aPoly;
84 Point aTmp( bLeft ? nLeft : nRight, nMid );
85 Point aNxt( bLeft ? nRight : nLeft, nTop );
86 aPoly.Insert( 0, aTmp );
87 aPoly.Insert( 0, aNxt );
88 aNxt.Y() = nBottom;
89 aPoly.Insert( 0, aNxt );
90 aPoly.Insert( 0, aTmp );
91 Color aOldLineColor = rOut.GetLineColor();
92 Color aOldFillColor = rOut.GetFillColor();
93 rOut.SetFillColor( rCol );
94 rOut.SetLineColor( Color( COL_BLACK ) );
95 rOut.DrawPolygon( aPoly );
96 rOut.DrawLine( aTmp, aNxt );
97 rOut.SetLineColor( aOldLineColor );
98 rOut.SetFillColor( aOldFillColor );
102 OUString SvxFont::CalcCaseMap(const OUString &rTxt) const
104 if (!IsCaseMap() || rTxt.isEmpty())
105 return rTxt;
106 OUString aTxt(rTxt);
107 // I still have to get the language
108 const LanguageType eLng = LANGUAGE_DONTKNOW == eLang
109 ? LANGUAGE_SYSTEM : eLang;
111 LanguageTag aLanguageTag( eLng);
112 CharClass aCharClass( aLanguageTag );
114 switch( eCaseMap )
116 case SVX_CASEMAP_KAPITAELCHEN:
117 case SVX_CASEMAP_VERSALIEN:
119 aTxt = aCharClass.uppercase( aTxt );
120 break;
123 case SVX_CASEMAP_GEMEINE:
125 aTxt = aCharClass.lowercase( aTxt );
126 break;
128 case SVX_CASEMAP_TITEL:
130 // Every beginning of a word is capitalized, the rest of the word
131 // is taken over as is.
132 // Bug: if the attribute starts in the middle of the word.
133 bool bBlank = true;
135 for (sal_Int32 i = 0; i < aTxt.getLength(); ++i)
137 if( aTxt[i] == ' ' || aTxt[i] == '\t')
138 bBlank = true;
139 else
141 if (bBlank)
143 OUString sTitle(aCharClass.uppercase(OUString(aTxt[i])));
144 aTxt = aTxt.replaceAt(i, 1, sTitle);
146 bBlank = false;
149 break;
151 default:
153 DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
154 break;
157 return aTxt;
160 /*************************************************************************
161 * class SvxDoCapitals
162 * The virtual Method Do si called by SvxFont::DoOnCapitals alternately
163 * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills
164 * this method with life.
165 *************************************************************************/
167 class SvxDoCapitals
169 protected:
170 OutputDevice *pOut;
171 const XubString &rTxt;
172 const xub_StrLen nIdx;
173 const xub_StrLen nLen;
175 public:
176 SvxDoCapitals( OutputDevice *_pOut, const XubString &_rTxt,
177 const xub_StrLen _nIdx, const xub_StrLen _nLen )
178 : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen)
181 virtual ~SvxDoCapitals() {}
183 virtual void DoSpace( const sal_Bool bDraw );
184 virtual void SetSpace();
185 virtual void Do( const XubString &rTxt,
186 const xub_StrLen nIdx, const xub_StrLen nLen,
187 const sal_Bool bUpper ) = 0;
189 inline OutputDevice *GetOut() { return pOut; }
190 inline const XubString &GetTxt() const { return rTxt; }
191 xub_StrLen GetIdx() const { return nIdx; }
192 xub_StrLen GetLen() const { return nLen; }
195 void SvxDoCapitals::DoSpace( const sal_Bool /*bDraw*/ ) { }
197 void SvxDoCapitals::SetSpace() { }
199 /*************************************************************************
200 * SvxFont::DoOnCapitals() const
201 * Decomposes the String into uppercase and lowercase letters and then
202 * calls the method SvxDoCapitals::Do( ).
203 *************************************************************************/
205 void SvxFont::DoOnCapitals(SvxDoCapitals &rDo, const xub_StrLen nPartLen) const
207 const XubString &rTxt = rDo.GetTxt();
208 const xub_StrLen nIdx = rDo.GetIdx();
209 const xub_StrLen nLen = STRING_LEN == nPartLen ? rDo.GetLen() : nPartLen;
211 const XubString aTxt( CalcCaseMap( rTxt ) );
212 const sal_uInt16 nTxtLen = std::min( rTxt.Len(), nLen );
213 sal_uInt16 nPos = 0;
214 sal_uInt16 nOldPos = nPos;
216 // #108210#
217 // Test if string length differ between original and CaseMapped
218 sal_Bool bCaseMapLengthDiffers(aTxt.Len() != rTxt.Len());
220 const LanguageType eLng = LANGUAGE_DONTKNOW == eLang
221 ? LANGUAGE_SYSTEM : eLang;
223 LanguageTag aLanguageTag( eLng );
224 CharClass aCharClass( aLanguageTag );
225 String aCharString;
227 while( nPos < nTxtLen )
229 // first in turn are the uppercase letters
231 // There are characters that are both upper- and lower-case L (eg blank)
232 // Such ambiguities lead to chaos, this is why these characters are
233 // allocated to the lowercase characters!
235 while( nPos < nTxtLen )
237 aCharString = rTxt.GetChar( nPos + nIdx );
238 sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
239 if ( nCharacterType & ::com::sun::star::i18n::KCharacterType::LOWER )
240 break;
241 if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
242 break;
243 ++nPos;
245 if( nOldPos != nPos )
247 if(bCaseMapLengthDiffers)
249 // #108210#
250 // If strings differ work preparing the necessary snippet to address that
251 // potential difference
252 const XubString aSnippet(rTxt, nIdx + nOldPos, nPos-nOldPos);
253 XubString aNewText = CalcCaseMap(aSnippet);
255 rDo.Do( aNewText, 0, aNewText.Len(), sal_True );
257 else
259 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_True );
262 nOldPos = nPos;
264 // Now the lowercase are processed (without blanks)
265 while( nPos < nTxtLen )
267 sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
268 if ( ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
269 break;
270 if ( comphelper::string::equals(aCharString, CH_BLANK) )
271 break;
272 if( ++nPos < nTxtLen )
273 aCharString = rTxt.GetChar( nPos + nIdx );
275 if( nOldPos != nPos )
277 if(bCaseMapLengthDiffers)
279 // #108210#
280 // If strings differ work preparing the necessary snippet to address that
281 // potential difference
282 const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos);
283 XubString aNewText = CalcCaseMap(aSnippet);
285 rDo.Do( aNewText, 0, aNewText.Len(), sal_False );
287 else
289 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_False );
292 nOldPos = nPos;
294 // Now the blanks are<processed
295 while( nPos < nTxtLen && comphelper::string::equals(aCharString, CH_BLANK) && ++nPos < nTxtLen )
296 aCharString = rTxt.GetChar( nPos + nIdx );
298 if( nOldPos != nPos )
300 rDo.DoSpace( sal_False );
302 if(bCaseMapLengthDiffers)
304 // #108210#
305 // If strings differ work preparing the necessary snippet to address that
306 // potential difference
307 const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos);
308 XubString aNewText = CalcCaseMap(aSnippet);
310 rDo.Do( aNewText, 0, aNewText.Len(), sal_False );
312 else
314 rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, sal_False );
317 nOldPos = nPos;
318 rDo.SetSpace();
321 rDo.DoSpace( sal_True );
325 void SvxFont::SetPhysFont( OutputDevice *pOut ) const
327 const Font& rCurrentFont = pOut->GetFont();
328 if ( nPropr == 100 )
330 if ( !rCurrentFont.IsSameInstance( *this ) )
331 pOut->SetFont( *this );
333 else
335 Font aNewFont( *this );
336 Size aSize( aNewFont.GetSize() );
337 aNewFont.SetSize( Size( aSize.Width() * nPropr / 100L,
338 aSize.Height() * nPropr / 100L ) );
339 if ( !rCurrentFont.IsSameInstance( aNewFont ) )
340 pOut->SetFont( aNewFont );
345 Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
347 Font aOldFont( pOut->GetFont() );
348 SetPhysFont( pOut );
349 return aOldFont;
353 Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt,
354 const xub_StrLen nIdx, const xub_StrLen nLen ) const
356 if ( !IsCaseMap() && !IsKern() )
357 return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ),
358 pOut->GetTextHeight() );
360 Size aTxtSize;
361 aTxtSize.setHeight( pOut->GetTextHeight() );
362 if ( !IsCaseMap() )
363 aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
364 else
366 // #108210#
367 const XubString aNewText = CalcCaseMap(rTxt);
368 sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len());
369 sal_Int32 nWidth(0L);
371 if(bCaseMapLengthDiffers)
373 // If strings differ work preparing the necessary snippet to address that
374 // potential difference
375 const XubString aSnippet(rTxt, nIdx, nLen);
376 XubString _aNewText = CalcCaseMap(aSnippet);
377 nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.Len() );
379 else
381 nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
384 aTxtSize.setWidth(nWidth);
387 if( IsKern() && ( nLen > 1 ) )
388 aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
390 return aTxtSize;
393 Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt )
395 if ( !IsCaseMap() && !IsKern() )
396 return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
398 Size aTxtSize;
399 aTxtSize.setHeight( pOut->GetTextHeight() );
400 if ( !IsCaseMap() )
401 aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
402 else
403 aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
405 if( IsKern() && ( rTxt.Len() > 1 ) )
406 aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) );
408 return aTxtSize;
411 Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const XubString &rTxt,
412 const sal_uInt16 nIdx, const sal_uInt16 nLen, sal_Int32* pDXArray ) const
414 if ( !IsCaseMap() && !IsKern() )
415 return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
416 pOut->GetTextHeight() );
418 Size aTxtSize;
419 aTxtSize.setHeight( pOut->GetTextHeight() );
420 if ( !IsCaseMap() )
421 aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
422 else
423 aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
424 pDXArray, nIdx, nLen ) );
426 if( IsKern() && ( nLen > 1 ) )
428 aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
430 if ( pDXArray )
432 for ( xub_StrLen i = 0; i < nLen; i++ )
433 pDXArray[i] += ( (i+1) * long( nKern ) );
434 // The last one is a nKern too big:
435 pDXArray[nLen-1] -= nKern;
438 return aTxtSize;
442 Size SvxFont::GetTxtSize( const OutputDevice *pOut, const XubString &rTxt,
443 const xub_StrLen nIdx, const xub_StrLen nLen ) const
445 xub_StrLen nTmp = nLen;
446 if ( nTmp == STRING_LEN ) // already initialized?
447 nTmp = rTxt.Len();
448 Font aOldFont( ChgPhysFont((OutputDevice *)pOut) );
449 Size aTxtSize;
450 if( IsCapital() && rTxt.Len() )
452 aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp );
454 else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp);
455 ((OutputDevice *)pOut)->SetFont( aOldFont );
456 return aTxtSize;
460 void SvxFont::QuickDrawText( OutputDevice *pOut,
461 const Point &rPos, const XubString &rTxt,
462 const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Int32* pDXArray ) const
464 // Font has to be selected in OutputDevice...
465 if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
467 pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
468 return;
471 Point aPos( rPos );
473 if ( nEsc )
475 long nDiff = GetSize().Height();
476 nDiff *= nEsc;
477 nDiff /= 100;
479 if ( !IsVertical() )
480 aPos.Y() -= nDiff;
481 else
482 aPos.X() += nDiff;
485 if( IsCapital() )
487 DBG_ASSERT( !pDXArray, "DrawCapital not for TextArray!" );
488 DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
490 else
492 if ( IsKern() && !pDXArray )
494 Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
496 if ( !IsCaseMap() )
497 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
498 else
499 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
501 else
503 if ( !IsCaseMap() )
504 pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
505 else
506 pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
512 void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
513 const Point &rPos, const XubString &rTxt,
514 const xub_StrLen nIdx, const xub_StrLen nLen ) const
516 if ( !nLen || !rTxt.Len() )
517 return;
518 xub_StrLen nTmp = nLen;
520 if ( nTmp == STRING_LEN ) // already initialized?
521 nTmp = rTxt.Len();
522 Point aPos( rPos );
524 if ( nEsc )
526 short nTmpEsc;
527 if( DFLT_ESC_AUTO_SUPER == nEsc )
528 nTmpEsc = 33;
529 else if( DFLT_ESC_AUTO_SUB == nEsc )
530 nTmpEsc = -20;
531 else
532 nTmpEsc = nEsc;
533 Size aSize = ( this->GetSize() );
534 aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
536 Font aOldFont( ChgPhysFont( pOut ) );
537 Font aOldPrnFont( ChgPhysFont( pPrinter ) );
539 if ( IsCapital() )
540 DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
541 else
543 Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
545 if ( !IsCaseMap() )
546 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
547 else
549 // #108210#
550 const XubString aNewText = CalcCaseMap(rTxt);
551 sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len());
553 if(bCaseMapLengthDiffers)
555 // If strings differ work preparing the necessary snippet to address that
556 // potential difference
557 const XubString aSnippet(rTxt, nIdx, nTmp);
558 XubString _aNewText = CalcCaseMap(aSnippet);
560 pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.Len() );
562 else
564 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
568 pOut->SetFont(aOldFont);
569 pPrinter->SetFont( aOldPrnFont );
573 SvxFont& SvxFont::operator=( const Font& rFont )
575 Font::operator=( rFont );
576 return *this;
579 SvxFont& SvxFont::operator=( const SvxFont& rFont )
581 Font::operator=( rFont );
582 eLang = rFont.eLang;
583 eCaseMap = rFont.eCaseMap;
584 nEsc = rFont.nEsc;
585 nPropr = rFont.nPropr;
586 nKern = rFont.nKern;
587 return *this;
590 class SvxDoGetCapitalSize : public SvxDoCapitals
592 protected:
593 SvxFont* pFont;
594 Size aTxtSize;
595 short nKern;
596 public:
597 SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
598 const XubString &_rTxt, const xub_StrLen _nIdx,
599 const xub_StrLen _nLen, const short _nKrn )
600 : SvxDoCapitals( (OutputDevice*)_pOut, _rTxt, _nIdx, _nLen ),
601 pFont( _pFnt ),
602 nKern( _nKrn )
605 virtual ~SvxDoGetCapitalSize() {}
607 virtual void Do( const XubString &rTxt, const xub_StrLen nIdx,
608 const xub_StrLen nLen, const sal_Bool bUpper );
610 inline const Size &GetSize() const { return aTxtSize; };
613 void SvxDoGetCapitalSize::Do( const XubString &_rTxt, const xub_StrLen _nIdx,
614 const xub_StrLen _nLen, const sal_Bool bUpper )
616 Size aPartSize;
617 if ( !bUpper )
619 sal_uInt8 nProp = pFont->GetPropr();
620 pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
621 pFont->SetPhysFont( pOut );
622 aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
623 aPartSize.setHeight( pOut->GetTextHeight() );
624 aTxtSize.Height() = aPartSize.Height();
625 pFont->SetPropr( nProp );
626 pFont->SetPhysFont( pOut );
628 else
630 aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
631 aPartSize.setHeight( pOut->GetTextHeight() );
633 aTxtSize.Width() += aPartSize.Width();
634 aTxtSize.Width() += ( _nLen * long( nKern ) );
637 Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const XubString &rTxt,
638 const xub_StrLen nIdx, const xub_StrLen nLen) const
640 // Start:
641 SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern );
642 DoOnCapitals( aDo );
643 Size aTxtSize( aDo.GetSize() );
645 // End:
646 if( !aTxtSize.Height() )
648 aTxtSize.setWidth( 0 );
649 aTxtSize.setHeight( pOut->GetTextHeight() );
651 return aTxtSize;
654 class SvxDoDrawCapital : public SvxDoCapitals
656 protected:
657 SvxFont *pFont;
658 Point aPos;
659 Point aSpacePos;
660 short nKern;
661 public:
662 SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const XubString &_rTxt,
663 const xub_StrLen _nIdx, const xub_StrLen _nLen,
664 const Point &rPos, const short nKrn )
665 : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
666 pFont( pFnt ),
667 aPos( rPos ),
668 aSpacePos( rPos ),
669 nKern( nKrn )
671 virtual ~SvxDoDrawCapital() {}
672 virtual void DoSpace( const sal_Bool bDraw );
673 virtual void SetSpace();
674 virtual void Do( const XubString &rTxt, const xub_StrLen nIdx,
675 const xub_StrLen nLen, const sal_Bool bUpper );
678 void SvxDoDrawCapital::DoSpace( const sal_Bool bDraw )
680 if ( bDraw || pFont->IsWordLineMode() )
682 sal_uInt16 nDiff = (sal_uInt16)(aPos.X() - aSpacePos.X());
683 if ( nDiff )
685 sal_Bool bWordWise = pFont->IsWordLineMode();
686 sal_Bool bTrans = pFont->IsTransparent();
687 pFont->SetWordLineMode( sal_False );
688 pFont->SetTransparent( sal_True );
689 pFont->SetPhysFont( pOut );
690 pOut->DrawStretchText( aSpacePos, nDiff, XubString( sDoubleSpace,
691 RTL_TEXTENCODING_MS_1252 ), 0, 2 );
692 pFont->SetWordLineMode( bWordWise );
693 pFont->SetTransparent( bTrans );
694 pFont->SetPhysFont( pOut );
699 void SvxDoDrawCapital::SetSpace()
701 if ( pFont->IsWordLineMode() )
702 aSpacePos.X() = aPos.X();
705 void SvxDoDrawCapital::Do( const XubString &_rTxt, const xub_StrLen _nIdx,
706 const xub_StrLen _nLen, const sal_Bool bUpper)
708 sal_uInt8 nProp = 0;
709 Size aPartSize;
711 // Set the desired font
712 FontUnderline eUnder = pFont->GetUnderline();
713 FontStrikeout eStrike = pFont->GetStrikeout();
714 pFont->SetUnderline( UNDERLINE_NONE );
715 pFont->SetStrikeout( STRIKEOUT_NONE );
716 if ( !bUpper )
718 nProp = pFont->GetPropr();
719 pFont->SetProprRel( SMALL_CAPS_PERCENTAGE );
721 pFont->SetPhysFont( pOut );
723 aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
724 aPartSize.setHeight( pOut->GetTextHeight() );
725 long nWidth = aPartSize.Width();
726 if ( nKern )
728 aPos.X() += (nKern/2);
729 if ( _nLen ) nWidth += (_nLen*long(nKern));
731 pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
733 // Restore Font
734 pFont->SetUnderline( eUnder );
735 pFont->SetStrikeout( eStrike );
736 if ( !bUpper )
737 pFont->SetPropr( nProp );
738 pFont->SetPhysFont( pOut );
740 aPos.X() += nWidth-(nKern/2);
743 /*************************************************************************
744 * SvxFont::DrawCapital() draws the uppercase letter.
745 *************************************************************************/
747 void SvxFont::DrawCapital( OutputDevice *pOut,
748 const Point &rPos, const XubString &rTxt,
749 const xub_StrLen nIdx, const xub_StrLen nLen ) const
751 SvxDoDrawCapital aDo( (SvxFont *)this,pOut,rTxt,nIdx,nLen,rPos,nKern );
752 DoOnCapitals( aDo );
755 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */