1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 // include ----------------------------------------------------------------
32 #include <vcl/outdev.hxx>
33 #include <vcl/print.hxx>
34 #include <tools/poly.hxx>
35 #include <unotools/charclass.hxx>
36 #include <editeng/unolingu.hxx>
37 #include <com/sun/star/i18n/KCharacterType.hpp>
39 #define _SVX_SVXFONT_CXX
41 #include <editeng/svxfont.hxx>
42 #include <editeng/escpitem.hxx>
44 // Minimum: Percentage of kernel
45 #define MINKERNPERCENT 5
47 #ifndef REDUCEDSVXFONT
48 const sal_Unicode CH_BLANK
= sal_Unicode(' '); // ' ' Space character
49 static sal_Char
const sDoubleSpace
[] = " ";
57 eCaseMap
= SVX_CASEMAP_NOT_MAPPED
;
58 eLang
= LANGUAGE_SYSTEM
;
61 SvxFont::SvxFont( const Font
&rFont
)
66 eCaseMap
= SVX_CASEMAP_NOT_MAPPED
;
67 eLang
= LANGUAGE_SYSTEM
;
70 SvxFont::SvxFont( const SvxFont
&rFont
)
73 nKern
= rFont
.GetFixKerning();
74 nEsc
= rFont
.GetEscapement();
75 nPropr
= rFont
.GetPropr();
76 eCaseMap
= rFont
.GetCaseMap();
77 eLang
= rFont
.GetLanguage();
81 void SvxFont::DrawArrow( OutputDevice
&rOut
, const Rectangle
& rRect
,
82 const Size
& rSize
, const Color
& rCol
, sal_Bool bLeft
)
84 long nLeft
= ( rRect
.Left() + rRect
.Right() - rSize
.Width() )/ 2;
85 long nRight
= nLeft
+ rSize
.Width();
86 long nMid
= ( rRect
.Top() + rRect
.Bottom() ) / 2;
87 long nTop
= nMid
- rSize
.Height() / 2;
88 long nBottom
= nTop
+ rSize
.Height();
89 if( nLeft
< rRect
.Left() )
92 nRight
= rRect
.Right();
94 if( nTop
< rRect
.Top() )
97 nBottom
= rRect
.Bottom();
100 Point
aTmp( bLeft
? nLeft
: nRight
, nMid
);
101 Point
aNxt( bLeft
? nRight
: nLeft
, nTop
);
102 aPoly
.Insert( 0, aTmp
);
103 aPoly
.Insert( 0, aNxt
);
105 aPoly
.Insert( 0, aNxt
);
106 aPoly
.Insert( 0, aTmp
);
107 Color aOldLineColor
= rOut
.GetLineColor();
108 Color aOldFillColor
= rOut
.GetFillColor();
109 rOut
.SetFillColor( rCol
);
110 rOut
.SetLineColor( Color( COL_BLACK
) );
111 rOut
.DrawPolygon( aPoly
);
112 rOut
.DrawLine( aTmp
, aNxt
);
113 rOut
.SetLineColor( aOldLineColor
);
114 rOut
.SetFillColor( aOldFillColor
);
118 XubString
SvxFont::CalcCaseMap( const XubString
&rTxt
) const
120 if( !IsCaseMap() || !rTxt
.Len() ) return rTxt
;
121 XubString
aTxt( rTxt
);
122 // I still have to get the language
123 const LanguageType eLng
= LANGUAGE_DONTKNOW
== eLang
124 ? LANGUAGE_SYSTEM
: eLang
;
126 CharClass
aCharClass( SvxCreateLocale( eLng
) );
130 case SVX_CASEMAP_KAPITAELCHEN
:
131 case SVX_CASEMAP_VERSALIEN
:
133 aTxt
= aCharClass
.uppercase( aTxt
);
137 case SVX_CASEMAP_GEMEINE
:
139 aTxt
= aCharClass
.lowercase( aTxt
);
142 case SVX_CASEMAP_TITEL
:
144 // Every beginning of a word is capitalized, the rest of the word
145 // is taken over as is.
146 // Bug: if the attribute starts in the middle of the word.
147 sal_Bool bBlank
= sal_True
;
149 for( sal_uInt16 i
= 0; i
< aTxt
.Len(); ++i
)
151 if( sal_Unicode(' ') == aTxt
.GetChar(i
) || sal_Unicode('\t') == aTxt
.GetChar(i
) )
157 String
aTemp( aTxt
.GetChar( i
) );
158 aTemp
= aCharClass
.uppercase( aTemp
);
159 aTxt
.Replace( i
, 1, aTemp
);
168 DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
175 /*************************************************************************
176 * Starting form here are the methods that can not be used in Writer,
177 * so we put this section to be excluded by REDUCEDSVXFONT.
178 *************************************************************************/
179 #ifndef REDUCEDSVXFONT
181 /*************************************************************************
182 * class SvxDoCapitals
183 * The virtual Method Do si called by SvxFont::DoOnCapitals alternately
184 * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills
185 * this method with life.
186 *************************************************************************/
192 const XubString
&rTxt
;
193 const xub_StrLen nIdx
;
194 const xub_StrLen nLen
;
197 SvxDoCapitals( OutputDevice
*_pOut
, const XubString
&_rTxt
,
198 const xub_StrLen _nIdx
, const xub_StrLen _nLen
)
199 : pOut(_pOut
), rTxt(_rTxt
), nIdx(_nIdx
), nLen(_nLen
)
202 virtual ~SvxDoCapitals() {}
204 virtual void DoSpace( const sal_Bool bDraw
);
205 virtual void SetSpace();
206 virtual void Do( const XubString
&rTxt
,
207 const xub_StrLen nIdx
, const xub_StrLen nLen
,
208 const sal_Bool bUpper
) = 0;
210 inline OutputDevice
*GetOut() { return pOut
; }
211 inline const XubString
&GetTxt() const { return rTxt
; }
212 xub_StrLen
GetIdx() const { return nIdx
; }
213 xub_StrLen
GetLen() const { return nLen
; }
216 void SvxDoCapitals::DoSpace( const sal_Bool
/*bDraw*/ ) { }
218 void SvxDoCapitals::SetSpace() { }
220 /*************************************************************************
221 * SvxFont::DoOnCapitals() const
222 * Decomposes the String into uppercase and lowercase letters and then
223 * calls the method SvxDoCapitals::Do( ).
224 *************************************************************************/
226 void SvxFont::DoOnCapitals(SvxDoCapitals
&rDo
, const xub_StrLen nPartLen
) const
228 const XubString
&rTxt
= rDo
.GetTxt();
229 const xub_StrLen nIdx
= rDo
.GetIdx();
230 const xub_StrLen nLen
= STRING_LEN
== nPartLen
? rDo
.GetLen() : nPartLen
;
232 const XubString
aTxt( CalcCaseMap( rTxt
) );
233 const sal_uInt16 nTxtLen
= Min( rTxt
.Len(), nLen
);
235 sal_uInt16 nOldPos
= nPos
;
238 // Test if string length differ between original and CaseMapped
239 sal_Bool
bCaseMapLengthDiffers(aTxt
.Len() != rTxt
.Len());
241 const LanguageType eLng
= LANGUAGE_DONTKNOW
== eLang
242 ? LANGUAGE_SYSTEM
: eLang
;
244 CharClass
aCharClass( SvxCreateLocale( eLng
) );
247 while( nPos
< nTxtLen
)
249 // first in turn are teh uppercase letters
251 // There are characters that are both upper- and lower-case L (eg blank)
252 // Such ambiguities lead to chaos, this is why these characters are
253 // allocated to the lowercase characters!
255 while( nPos
< nTxtLen
)
257 aCharString
= rTxt
.GetChar( nPos
+ nIdx
);
258 sal_Int32 nCharacterType
= aCharClass
.getCharacterType( aCharString
, 0 );
259 if ( nCharacterType
& ::com::sun::star::i18n::KCharacterType::LOWER
)
261 if ( ! ( nCharacterType
& ::com::sun::star::i18n::KCharacterType::UPPER
) )
265 if( nOldPos
!= nPos
)
267 if(bCaseMapLengthDiffers
)
270 // If strings differ work preparing the necessary snippet to address that
271 // potential difference
272 const XubString
aSnippet(rTxt
, nIdx
+ nOldPos
, nPos
-nOldPos
);
273 XubString aNewText
= CalcCaseMap(aSnippet
);
275 rDo
.Do( aNewText
, 0, aNewText
.Len(), sal_True
);
279 rDo
.Do( aTxt
, nIdx
+ nOldPos
, nPos
-nOldPos
, sal_True
);
284 // Now the lowercase are processed (without blanks)
285 while( nPos
< nTxtLen
)
287 sal_uInt32 nCharacterType
= aCharClass
.getCharacterType( aCharString
, 0 );
288 if ( ( nCharacterType
& ::com::sun::star::i18n::KCharacterType::UPPER
) )
290 if ( CH_BLANK
== aCharString
)
292 if( ++nPos
< nTxtLen
)
293 aCharString
= rTxt
.GetChar( nPos
+ nIdx
);
295 if( nOldPos
!= nPos
)
297 if(bCaseMapLengthDiffers
)
300 // If strings differ work preparing the necessary snippet to address that
301 // potential difference
302 const XubString
aSnippet(rTxt
, nIdx
+ nOldPos
, nPos
- nOldPos
);
303 XubString aNewText
= CalcCaseMap(aSnippet
);
305 rDo
.Do( aNewText
, 0, aNewText
.Len(), sal_False
);
309 rDo
.Do( aTxt
, nIdx
+ nOldPos
, nPos
-nOldPos
, sal_False
);
314 // Now the blanks are<processed
315 while( nPos
< nTxtLen
&& CH_BLANK
== aCharString
&& ++nPos
< nTxtLen
)
316 aCharString
= rTxt
.GetChar( nPos
+ nIdx
);
318 if( nOldPos
!= nPos
)
320 rDo
.DoSpace( sal_False
);
322 if(bCaseMapLengthDiffers
)
325 // If strings differ work preparing the necessary snippet to address that
326 // potential difference
327 const XubString
aSnippet(rTxt
, nIdx
+ nOldPos
, nPos
- nOldPos
);
328 XubString aNewText
= CalcCaseMap(aSnippet
);
330 rDo
.Do( aNewText
, 0, aNewText
.Len(), sal_False
);
334 rDo
.Do( aTxt
, nIdx
+ nOldPos
, nPos
- nOldPos
, sal_False
);
341 rDo
.DoSpace( sal_True
);
345 void SvxFont::SetPhysFont( OutputDevice
*pOut
) const
347 const Font
& rCurrentFont
= pOut
->GetFont();
350 if ( !rCurrentFont
.IsSameInstance( *this ) )
351 pOut
->SetFont( *this );
355 Font
aNewFont( *this );
356 Size
aSize( aNewFont
.GetSize() );
357 aNewFont
.SetSize( Size( aSize
.Width() * nPropr
/ 100L,
358 aSize
.Height() * nPropr
/ 100L ) );
359 if ( !rCurrentFont
.IsSameInstance( aNewFont
) )
360 pOut
->SetFont( aNewFont
);
365 Font
SvxFont::ChgPhysFont( OutputDevice
*pOut
) const
367 Font
aOldFont( pOut
->GetFont() );
373 Size
SvxFont::GetPhysTxtSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
374 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
376 if ( !IsCaseMap() && !IsKern() )
377 return Size( pOut
->GetTextWidth( rTxt
, nIdx
, nLen
),
378 pOut
->GetTextHeight() );
381 aTxtSize
.setHeight( pOut
->GetTextHeight() );
383 aTxtSize
.setWidth( pOut
->GetTextWidth( rTxt
, nIdx
, nLen
) );
387 const XubString aNewText
= CalcCaseMap(rTxt
);
388 sal_Bool
bCaseMapLengthDiffers(aNewText
.Len() != rTxt
.Len());
389 sal_Int32
nWidth(0L);
391 if(bCaseMapLengthDiffers
)
393 // If strings differ work preparing the necessary snippet to address that
394 // potential difference
395 const XubString
aSnippet(rTxt
, nIdx
, nLen
);
396 XubString _aNewText
= CalcCaseMap(aSnippet
);
397 nWidth
= pOut
->GetTextWidth( _aNewText
, 0, _aNewText
.Len() );
401 nWidth
= pOut
->GetTextWidth( aNewText
, nIdx
, nLen
);
404 aTxtSize
.setWidth(nWidth
);
407 if( IsKern() && ( nLen
> 1 ) )
408 aTxtSize
.Width() += ( ( nLen
-1 ) * long( nKern
) );
413 Size
SvxFont::GetPhysTxtSize( const OutputDevice
*pOut
, const XubString
&rTxt
)
415 if ( !IsCaseMap() && !IsKern() )
416 return Size( pOut
->GetTextWidth( rTxt
), pOut
->GetTextHeight() );
419 aTxtSize
.setHeight( pOut
->GetTextHeight() );
421 aTxtSize
.setWidth( pOut
->GetTextWidth( rTxt
) );
423 aTxtSize
.setWidth( pOut
->GetTextWidth( CalcCaseMap( rTxt
) ) );
425 if( IsKern() && ( rTxt
.Len() > 1 ) )
426 aTxtSize
.Width() += ( ( rTxt
.Len()-1 ) * long( nKern
) );
431 Size
SvxFont::QuickGetTextSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
432 const sal_uInt16 nIdx
, const sal_uInt16 nLen
, sal_Int32
* pDXArray
) const
434 if ( !IsCaseMap() && !IsKern() )
435 return Size( pOut
->GetTextArray( rTxt
, pDXArray
, nIdx
, nLen
),
436 pOut
->GetTextHeight() );
439 aTxtSize
.setHeight( pOut
->GetTextHeight() );
441 aTxtSize
.setWidth( pOut
->GetTextArray( rTxt
, pDXArray
, nIdx
, nLen
) );
443 aTxtSize
.setWidth( pOut
->GetTextArray( CalcCaseMap( rTxt
),
444 pDXArray
, nIdx
, nLen
) );
446 if( IsKern() && ( nLen
> 1 ) )
448 aTxtSize
.Width() += ( ( nLen
-1 ) * long( nKern
) );
452 for ( xub_StrLen i
= 0; i
< nLen
; i
++ )
453 pDXArray
[i
] += ( (i
+1) * long( nKern
) );
454 // The last one is a nKern too big:
455 pDXArray
[nLen
-1] -= nKern
;
462 Size
SvxFont::GetTxtSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
463 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
465 xub_StrLen nTmp
= nLen
;
466 if ( nTmp
== STRING_LEN
) // already initialized?
468 Font
aOldFont( ChgPhysFont((OutputDevice
*)pOut
) );
470 if( IsCapital() && rTxt
.Len() )
472 aTxtSize
= GetCapitalSize( pOut
, rTxt
, nIdx
, nTmp
);
474 else aTxtSize
= GetPhysTxtSize(pOut
,rTxt
,nIdx
,nTmp
);
475 ((OutputDevice
*)pOut
)->SetFont( aOldFont
);
480 void SvxFont::QuickDrawText( OutputDevice
*pOut
,
481 const Point
&rPos
, const XubString
&rTxt
,
482 const xub_StrLen nIdx
, const xub_StrLen nLen
, const sal_Int32
* pDXArray
) const
484 // Font has to be selected in OutputDevice...
485 if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
487 pOut
->DrawTextArray( rPos
, rTxt
, pDXArray
, nIdx
, nLen
);
495 long nDiff
= GetSize().Height();
507 DBG_ASSERT( !pDXArray
, "DrawCapital not for TextArray!" );
508 DrawCapital( pOut
, aPos
, rTxt
, nIdx
, nLen
);
512 if ( IsKern() && !pDXArray
)
514 Size aSize
= GetPhysTxtSize( pOut
, rTxt
, nIdx
, nLen
);
517 pOut
->DrawStretchText( aPos
, aSize
.Width(), rTxt
, nIdx
, nLen
);
519 pOut
->DrawStretchText( aPos
, aSize
.Width(), CalcCaseMap( rTxt
), nIdx
, nLen
);
524 pOut
->DrawTextArray( aPos
, rTxt
, pDXArray
, nIdx
, nLen
);
526 pOut
->DrawTextArray( aPos
, CalcCaseMap( rTxt
), pDXArray
, nIdx
, nLen
);
532 void SvxFont::DrawPrev( OutputDevice
*pOut
, Printer
* pPrinter
,
533 const Point
&rPos
, const XubString
&rTxt
,
534 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
536 if ( !nLen
|| !rTxt
.Len() )
538 xub_StrLen nTmp
= nLen
;
540 if ( nTmp
== STRING_LEN
) // already initialized?
547 if( DFLT_ESC_AUTO_SUPER
== nEsc
)
549 else if( DFLT_ESC_AUTO_SUB
== nEsc
)
553 Size aSize
= ( this->GetSize() );
554 aPos
.Y() -= ( ( nTmpEsc
* long( aSize
.Height() ) ) / 100L );
556 Font
aOldFont( ChgPhysFont( pOut
) );
557 Font
aOldPrnFont( ChgPhysFont( pPrinter
) );
560 DrawCapital( pOut
, aPos
, rTxt
, nIdx
, nTmp
);
563 Size aSize
= GetPhysTxtSize( pPrinter
, rTxt
, nIdx
, nTmp
);
566 pOut
->DrawStretchText( aPos
, aSize
.Width(), rTxt
, nIdx
, nTmp
);
570 const XubString aNewText
= CalcCaseMap(rTxt
);
571 sal_Bool
bCaseMapLengthDiffers(aNewText
.Len() != rTxt
.Len());
573 if(bCaseMapLengthDiffers
)
575 // If strings differ work preparing the necessary snippet to address that
576 // potential difference
577 const XubString
aSnippet(rTxt
, nIdx
, nTmp
);
578 XubString _aNewText
= CalcCaseMap(aSnippet
);
580 pOut
->DrawStretchText( aPos
, aSize
.Width(), _aNewText
, 0, _aNewText
.Len() );
584 pOut
->DrawStretchText( aPos
, aSize
.Width(), CalcCaseMap( rTxt
), nIdx
, nTmp
);
588 pOut
->SetFont(aOldFont
);
589 pPrinter
->SetFont( aOldPrnFont
);
593 SvxFont
& SvxFont::operator=( const Font
& rFont
)
595 Font::operator=( rFont
);
599 SvxFont
& SvxFont::operator=( const SvxFont
& rFont
)
601 Font::operator=( rFont
);
603 eCaseMap
= rFont
.eCaseMap
;
605 nPropr
= rFont
.nPropr
;
610 class SvxDoGetCapitalSize
: public SvxDoCapitals
617 SvxDoGetCapitalSize( SvxFont
*_pFnt
, const OutputDevice
*_pOut
,
618 const XubString
&_rTxt
, const xub_StrLen _nIdx
,
619 const xub_StrLen _nLen
, const short _nKrn
)
620 : SvxDoCapitals( (OutputDevice
*)_pOut
, _rTxt
, _nIdx
, _nLen
),
625 virtual ~SvxDoGetCapitalSize() {}
627 virtual void Do( const XubString
&rTxt
, const xub_StrLen nIdx
,
628 const xub_StrLen nLen
, const sal_Bool bUpper
);
630 inline const Size
&GetSize() const { return aTxtSize
; };
633 void SvxDoGetCapitalSize::Do( const XubString
&_rTxt
, const xub_StrLen _nIdx
,
634 const xub_StrLen _nLen
, const sal_Bool bUpper
)
639 sal_uInt8 nProp
= pFont
->GetPropr();
640 pFont
->SetProprRel( SMALL_CAPS_PERCENTAGE
);
641 pFont
->SetPhysFont( pOut
);
642 aPartSize
.setWidth( pOut
->GetTextWidth( _rTxt
, _nIdx
, _nLen
) );
643 aPartSize
.setHeight( pOut
->GetTextHeight() );
644 aTxtSize
.Height() = aPartSize
.Height();
645 pFont
->SetPropr( nProp
);
646 pFont
->SetPhysFont( pOut
);
650 aPartSize
.setWidth( pOut
->GetTextWidth( _rTxt
, _nIdx
, _nLen
) );
651 aPartSize
.setHeight( pOut
->GetTextHeight() );
653 aTxtSize
.Width() += aPartSize
.Width();
654 aTxtSize
.Width() += ( _nLen
* long( nKern
) );
657 Size
SvxFont::GetCapitalSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
658 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
661 SvxDoGetCapitalSize
aDo( (SvxFont
*)this, pOut
, rTxt
, nIdx
, nLen
, nKern
);
663 Size
aTxtSize( aDo
.GetSize() );
666 if( !aTxtSize
.Height() )
668 aTxtSize
.setWidth( 0 );
669 aTxtSize
.setHeight( pOut
->GetTextHeight() );
674 class SvxDoDrawCapital
: public SvxDoCapitals
682 SvxDoDrawCapital( SvxFont
*pFnt
, OutputDevice
*_pOut
, const XubString
&_rTxt
,
683 const xub_StrLen _nIdx
, const xub_StrLen _nLen
,
684 const Point
&rPos
, const short nKrn
)
685 : SvxDoCapitals( _pOut
, _rTxt
, _nIdx
, _nLen
),
691 virtual ~SvxDoDrawCapital() {}
692 virtual void DoSpace( const sal_Bool bDraw
);
693 virtual void SetSpace();
694 virtual void Do( const XubString
&rTxt
, const xub_StrLen nIdx
,
695 const xub_StrLen nLen
, const sal_Bool bUpper
);
698 void SvxDoDrawCapital::DoSpace( const sal_Bool bDraw
)
700 if ( bDraw
|| pFont
->IsWordLineMode() )
702 sal_uInt16 nDiff
= (sal_uInt16
)(aPos
.X() - aSpacePos
.X());
705 sal_Bool bWordWise
= pFont
->IsWordLineMode();
706 sal_Bool bTrans
= pFont
->IsTransparent();
707 pFont
->SetWordLineMode( sal_False
);
708 pFont
->SetTransparent( sal_True
);
709 pFont
->SetPhysFont( pOut
);
710 pOut
->DrawStretchText( aSpacePos
, nDiff
, XubString( sDoubleSpace
,
711 RTL_TEXTENCODING_MS_1252
), 0, 2 );
712 pFont
->SetWordLineMode( bWordWise
);
713 pFont
->SetTransparent( bTrans
);
714 pFont
->SetPhysFont( pOut
);
719 void SvxDoDrawCapital::SetSpace()
721 if ( pFont
->IsWordLineMode() )
722 aSpacePos
.X() = aPos
.X();
725 void SvxDoDrawCapital::Do( const XubString
&_rTxt
, const xub_StrLen _nIdx
,
726 const xub_StrLen _nLen
, const sal_Bool bUpper
)
731 // Set the desired font
732 FontUnderline eUnder
= pFont
->GetUnderline();
733 FontStrikeout eStrike
= pFont
->GetStrikeout();
734 pFont
->SetUnderline( UNDERLINE_NONE
);
735 pFont
->SetStrikeout( STRIKEOUT_NONE
);
738 nProp
= pFont
->GetPropr();
739 pFont
->SetProprRel( SMALL_CAPS_PERCENTAGE
);
741 pFont
->SetPhysFont( pOut
);
743 aPartSize
.setWidth( pOut
->GetTextWidth( _rTxt
, _nIdx
, _nLen
) );
744 aPartSize
.setHeight( pOut
->GetTextHeight() );
745 long nWidth
= aPartSize
.Width();
748 aPos
.X() += (nKern
/2);
749 if ( _nLen
) nWidth
+= (_nLen
*long(nKern
));
751 pOut
->DrawStretchText(aPos
,nWidth
-nKern
,_rTxt
,_nIdx
,_nLen
);
754 pFont
->SetUnderline( eUnder
);
755 pFont
->SetStrikeout( eStrike
);
757 pFont
->SetPropr( nProp
);
758 pFont
->SetPhysFont( pOut
);
760 aPos
.X() += nWidth
-(nKern
/2);
763 /*************************************************************************
764 * SvxFont::DrawCapital() draws the uppercase letter.
765 *************************************************************************/
767 void SvxFont::DrawCapital( OutputDevice
*pOut
,
768 const Point
&rPos
, const XubString
&rTxt
,
769 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
771 SvxDoDrawCapital
aDo( (SvxFont
*)this,pOut
,rTxt
,nIdx
,nLen
,rPos
,nKern
);
775 #endif // !REDUCEDSVXFONT
778 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */