1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svxfont.cxx,v $
10 * $Revision: 1.15.216.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 // include ----------------------------------------------------------------
36 #ifndef _OUTDEV_HXX //autogen
37 #include <vcl/outdev.hxx>
39 #ifndef _PRINT_HXX //autogen
40 #include <vcl/print.hxx>
42 #include <tools/poly.hxx>
43 #include <unotools/charclass.hxx>
44 #include <unolingu.hxx>
45 #include <com/sun/star/i18n/KCharacterType.hpp>
47 #define _SVX_SVXFONT_CXX
49 #include <svx/svxfont.hxx>
50 #include <svx/escpitem.hxx>
52 // Minimum: Prozentwert fuers kernen
53 #define MINKERNPERCENT 5
55 // prop. Groesse der Kleinbuchstaben bei Kapitaelchen
56 #define KAPITAELCHENPROP 66
58 #ifndef REDUCEDSVXFONT
59 const sal_Unicode CH_BLANK
= sal_Unicode(' '); // ' ' Leerzeichen
60 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
63 /*************************************************************************
65 *************************************************************************/
71 eCaseMap
= SVX_CASEMAP_NOT_MAPPED
;
72 eLang
= LANGUAGE_SYSTEM
;
75 SvxFont::SvxFont( const Font
&rFont
)
80 eCaseMap
= SVX_CASEMAP_NOT_MAPPED
;
81 eLang
= LANGUAGE_SYSTEM
;
84 /*************************************************************************
85 * class SvxFont: Copy-Ctor
86 *************************************************************************/
88 SvxFont::SvxFont( const SvxFont
&rFont
)
91 nKern
= rFont
.GetFixKerning();
92 nEsc
= rFont
.GetEscapement();
93 nPropr
= rFont
.GetPropr();
94 eCaseMap
= rFont
.GetCaseMap();
95 eLang
= rFont
.GetLanguage();
98 /*************************************************************************
99 * static SvxFont::DrawArrow
100 *************************************************************************/
102 void SvxFont::DrawArrow( OutputDevice
&rOut
, const Rectangle
& rRect
,
103 const Size
& rSize
, const Color
& rCol
, BOOL bLeft
)
105 long nLeft
= ( rRect
.Left() + rRect
.Right() - rSize
.Width() )/ 2;
106 long nRight
= nLeft
+ rSize
.Width();
107 long nMid
= ( rRect
.Top() + rRect
.Bottom() ) / 2;
108 long nTop
= nMid
- rSize
.Height() / 2;
109 long nBottom
= nTop
+ rSize
.Height();
110 if( nLeft
< rRect
.Left() )
112 nLeft
= rRect
.Left();
113 nRight
= rRect
.Right();
115 if( nTop
< rRect
.Top() )
118 nBottom
= rRect
.Bottom();
121 Point
aTmp( bLeft
? nLeft
: nRight
, nMid
);
122 Point
aNxt( bLeft
? nRight
: nLeft
, nTop
);
123 aPoly
.Insert( 0, aTmp
);
124 aPoly
.Insert( 0, aNxt
);
126 aPoly
.Insert( 0, aNxt
);
127 aPoly
.Insert( 0, aTmp
);
128 Color aOldLineColor
= rOut
.GetLineColor();
129 Color aOldFillColor
= rOut
.GetFillColor();
130 rOut
.SetFillColor( rCol
);
131 rOut
.SetLineColor( Color( COL_BLACK
) );
132 rOut
.DrawPolygon( aPoly
);
133 rOut
.DrawLine( aTmp
, aNxt
);
134 rOut
.SetLineColor( aOldLineColor
);
135 rOut
.SetFillColor( aOldFillColor
);
138 /*************************************************************************
139 * SvxFont::CalcCaseMap
140 *************************************************************************/
142 XubString
SvxFont::CalcCaseMap( const XubString
&rTxt
) const
144 if( !IsCaseMap() || !rTxt
.Len() ) return rTxt
;
145 XubString
aTxt( rTxt
);
146 // Ich muss mir noch die Sprache besorgen
147 const LanguageType eLng
= LANGUAGE_DONTKNOW
== eLang
148 ? LANGUAGE_SYSTEM
: eLang
;
150 CharClass
aCharClass( SvxCreateLocale( eLng
) );
154 case SVX_CASEMAP_KAPITAELCHEN
:
155 case SVX_CASEMAP_VERSALIEN
:
157 aCharClass
.toUpper( aTxt
);
161 case SVX_CASEMAP_GEMEINE
:
163 aCharClass
.toLower( aTxt
);
166 case SVX_CASEMAP_TITEL
:
168 // Jeder Wortbeginn wird gross geschrieben,
169 // der Rest des Wortes wird unbesehen uebernommen.
170 // Bug: wenn das Attribut mitten im Wort beginnt.
173 for( USHORT i
= 0; i
< aTxt
.Len(); ++i
)
175 if( sal_Unicode(' ') == aTxt
.GetChar(i
) || sal_Unicode('\t') == aTxt
.GetChar(i
) )
181 String
aTemp( aTxt
.GetChar( i
) );
182 aCharClass
.toUpper( aTemp
);
183 aTxt
.Replace( i
, 1, aTemp
);
192 DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
199 /*************************************************************************
200 * Hier beginnen die Methoden, die im Writer nicht benutzt werden koennen,
201 * deshalb kann man diesen Bereich durch setzen von REDUCEDSVXFONT ausklammern.
202 *************************************************************************/
203 #ifndef REDUCEDSVXFONT
205 /*************************************************************************
206 * class SvxDoCapitals
207 * die virtuelle Methode Do wird von SvxFont::DoOnCapitals abwechselnd mit
208 * den "Gross-" und "Kleinbuchstaben"-Teilen aufgerufen.
209 * Die Ableitungen von SvxDoCapitals erfuellen diese Methode mit Leben.
210 *************************************************************************/
216 const XubString
&rTxt
;
217 const xub_StrLen nIdx
;
218 const xub_StrLen nLen
;
221 SvxDoCapitals( OutputDevice
*_pOut
, const XubString
&_rTxt
,
222 const xub_StrLen _nIdx
, const xub_StrLen _nLen
)
223 : pOut(_pOut
), rTxt(_rTxt
), nIdx(_nIdx
), nLen(_nLen
)
226 virtual void DoSpace( const BOOL bDraw
);
227 virtual void SetSpace();
228 virtual void Do( const XubString
&rTxt
,
229 const xub_StrLen nIdx
, const xub_StrLen nLen
,
230 const BOOL bUpper
) = 0;
232 inline OutputDevice
*GetOut() { return pOut
; }
233 inline const XubString
&GetTxt() const { return rTxt
; }
234 xub_StrLen
GetIdx() const { return nIdx
; }
235 xub_StrLen
GetLen() const { return nLen
; }
238 void SvxDoCapitals::DoSpace( const BOOL
/*bDraw*/ ) { }
240 void SvxDoCapitals::SetSpace() { }
242 void SvxDoCapitals::Do( const XubString
&/*_rTxt*/, const xub_StrLen
/*_nIdx*/,
243 const xub_StrLen
/*_nLen*/, const BOOL
/*bUpper*/ ) { }
245 /*************************************************************************
246 * SvxFont::DoOnCapitals() const
247 * zerlegt den String in Gross- und Kleinbuchstaben und ruft jeweils die
248 * Methode SvxDoCapitals::Do( ) auf.
249 *************************************************************************/
251 void SvxFont::DoOnCapitals(SvxDoCapitals
&rDo
, const xub_StrLen nPartLen
) const
253 const XubString
&rTxt
= rDo
.GetTxt();
254 const xub_StrLen nIdx
= rDo
.GetIdx();
255 const xub_StrLen nLen
= STRING_LEN
== nPartLen
? rDo
.GetLen() : nPartLen
;
257 const XubString
aTxt( CalcCaseMap( rTxt
) );
258 const USHORT nTxtLen
= Min( rTxt
.Len(), nLen
);
260 USHORT nOldPos
= nPos
;
263 // Test if string length differ between original and CaseMapped
264 sal_Bool
bCaseMapLengthDiffers(aTxt
.Len() != rTxt
.Len());
266 const LanguageType eLng
= LANGUAGE_DONTKNOW
== eLang
267 ? LANGUAGE_SYSTEM
: eLang
;
269 CharClass
aCharClass( SvxCreateLocale( eLng
) );
272 while( nPos
< nTxtLen
)
274 // Erst kommen die Upper-Chars dran
276 // 4251: Es gibt Zeichen, die Upper _und_ Lower sind (z.B. das Blank).
277 // Solche Zweideutigkeiten fuehren ins Chaos, deswegen werden diese
278 // Zeichen der Menge Lower zugeordnet !
280 while( nPos
< nTxtLen
)
282 aCharString
= rTxt
.GetChar( nPos
+ nIdx
);
283 sal_Int32 nCharacterType
= aCharClass
.getCharacterType( aCharString
, 0 );
284 if ( nCharacterType
& ::com::sun::star::i18n::KCharacterType::LOWER
)
286 if ( ! ( nCharacterType
& ::com::sun::star::i18n::KCharacterType::UPPER
) )
290 if( nOldPos
!= nPos
)
292 if(bCaseMapLengthDiffers
)
295 // If strings differ work preparing the necessary snippet to address that
296 // potential difference
297 const XubString
aSnippet(rTxt
, nIdx
+ nOldPos
, nPos
-nOldPos
);
298 XubString aNewText
= CalcCaseMap(aSnippet
);
300 rDo
.Do( aNewText
, 0, aNewText
.Len(), TRUE
);
304 rDo
.Do( aTxt
, nIdx
+ nOldPos
, nPos
-nOldPos
, TRUE
);
309 // Nun werden die Lower-Chars verarbeitet (ohne Blanks)
310 while( nPos
< nTxtLen
)
312 sal_uInt32 nCharacterType
= aCharClass
.getCharacterType( aCharString
, 0 );
313 if ( ( nCharacterType
& ::com::sun::star::i18n::KCharacterType::UPPER
) )
315 if ( CH_BLANK
== aCharString
)
317 if( ++nPos
< nTxtLen
)
318 aCharString
= rTxt
.GetChar( nPos
+ nIdx
);
320 if( nOldPos
!= nPos
)
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(), FALSE
);
334 rDo
.Do( aTxt
, nIdx
+ nOldPos
, nPos
-nOldPos
, FALSE
);
339 // Nun werden die Blanks verarbeitet
340 while( nPos
< nTxtLen
&& CH_BLANK
== aCharString
&& ++nPos
< nTxtLen
)
341 aCharString
= rTxt
.GetChar( nPos
+ nIdx
);
343 if( nOldPos
!= nPos
)
345 rDo
.DoSpace( FALSE
);
347 if(bCaseMapLengthDiffers
)
350 // If strings differ work preparing the necessary snippet to address that
351 // potential difference
352 const XubString
aSnippet(rTxt
, nIdx
+ nOldPos
, nPos
- nOldPos
);
353 XubString aNewText
= CalcCaseMap(aSnippet
);
355 rDo
.Do( aNewText
, 0, aNewText
.Len(), FALSE
);
359 rDo
.Do( aTxt
, nIdx
+ nOldPos
, nPos
- nOldPos
, FALSE
);
369 /**************************************************************************
370 * SvxFont::SetPhysFont()
371 *************************************************************************/
373 void SvxFont::SetPhysFont( OutputDevice
*pOut
) const
375 const Font
& rCurrentFont
= pOut
->GetFont();
378 if ( !rCurrentFont
.IsSameInstance( *this ) )
379 pOut
->SetFont( *this );
383 Font
aNewFont( *this );
384 Size
aSize( aNewFont
.GetSize() );
385 aNewFont
.SetSize( Size( aSize
.Width() * nPropr
/ 100L,
386 aSize
.Height() * nPropr
/ 100L ) );
387 if ( !rCurrentFont
.IsSameInstance( aNewFont
) )
388 pOut
->SetFont( aNewFont
);
392 /*************************************************************************
393 * SvxFont::ChgPhysFont()
394 *************************************************************************/
396 Font
SvxFont::ChgPhysFont( OutputDevice
*pOut
) const
398 Font
aOldFont( pOut
->GetFont() );
403 /*************************************************************************
404 * SvxFont::GetPhysTxtSize()
405 *************************************************************************/
407 Size
SvxFont::GetPhysTxtSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
408 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
410 if ( !IsCaseMap() && !IsKern() )
411 return Size( pOut
->GetTextWidth( rTxt
, nIdx
, nLen
),
412 pOut
->GetTextHeight() );
415 aTxtSize
.setHeight( pOut
->GetTextHeight() );
417 aTxtSize
.setWidth( pOut
->GetTextWidth( rTxt
, nIdx
, nLen
) );
421 const XubString aNewText
= CalcCaseMap(rTxt
);
422 sal_Bool
bCaseMapLengthDiffers(aNewText
.Len() != rTxt
.Len());
423 sal_Int32
nWidth(0L);
425 if(bCaseMapLengthDiffers
)
427 // If strings differ work preparing the necessary snippet to address that
428 // potential difference
429 const XubString
aSnippet(rTxt
, nIdx
, nLen
);
430 XubString _aNewText
= CalcCaseMap(aSnippet
);
431 nWidth
= pOut
->GetTextWidth( _aNewText
, 0, _aNewText
.Len() );
435 nWidth
= pOut
->GetTextWidth( aNewText
, nIdx
, nLen
);
438 aTxtSize
.setWidth(nWidth
);
441 if( IsKern() && ( nLen
> 1 ) )
442 aTxtSize
.Width() += ( ( nLen
-1 ) * long( nKern
) );
447 Size
SvxFont::GetPhysTxtSize( const OutputDevice
*pOut
, const XubString
&rTxt
)
449 if ( !IsCaseMap() && !IsKern() )
450 return Size( pOut
->GetTextWidth( rTxt
), pOut
->GetTextHeight() );
453 aTxtSize
.setHeight( pOut
->GetTextHeight() );
455 aTxtSize
.setWidth( pOut
->GetTextWidth( rTxt
) );
457 aTxtSize
.setWidth( pOut
->GetTextWidth( CalcCaseMap( rTxt
) ) );
459 if( IsKern() && ( rTxt
.Len() > 1 ) )
460 aTxtSize
.Width() += ( ( rTxt
.Len()-1 ) * long( nKern
) );
465 Size
SvxFont::QuickGetTextSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
466 const USHORT nIdx
, const USHORT nLen
, sal_Int32
* pDXArray
) const
468 if ( !IsCaseMap() && !IsKern() )
469 return Size( pOut
->GetTextArray( rTxt
, pDXArray
, nIdx
, nLen
),
470 pOut
->GetTextHeight() );
473 aTxtSize
.setHeight( pOut
->GetTextHeight() );
475 aTxtSize
.setWidth( pOut
->GetTextArray( rTxt
, pDXArray
, nIdx
, nLen
) );
477 aTxtSize
.setWidth( pOut
->GetTextArray( CalcCaseMap( rTxt
),
478 pDXArray
, nIdx
, nLen
) );
480 if( IsKern() && ( nLen
> 1 ) )
482 aTxtSize
.Width() += ( ( nLen
-1 ) * long( nKern
) );
486 for ( xub_StrLen i
= 0; i
< nLen
; i
++ )
487 pDXArray
[i
] += ( (i
+1) * long( nKern
) );
488 // Der letzte ist um ein nKern zu gross:
489 pDXArray
[nLen
-1] -= nKern
;
495 /*************************************************************************
496 * SvxFont::GetTxtSize()
497 *************************************************************************/
499 Size
SvxFont::GetTxtSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
500 const xub_StrLen nIdx
, const xub_StrLen nLen
)
502 xub_StrLen nTmp
= nLen
;
503 if ( nTmp
== STRING_LEN
) // schon initialisiert?
505 Font
aOldFont( ChgPhysFont((OutputDevice
*)pOut
) );
507 if( IsCapital() && rTxt
.Len() )
509 aTxtSize
= GetCapitalSize( pOut
, rTxt
, nIdx
, nTmp
);
511 else aTxtSize
= GetPhysTxtSize(pOut
,rTxt
,nIdx
,nTmp
);
512 ((OutputDevice
*)pOut
)->SetFont( aOldFont
);
516 /*************************************************************************
517 * SvxFont::DrawText()
518 *************************************************************************/
520 void SvxFont::DrawText( OutputDevice
*pOut
,
521 const Point
&rPos
, const XubString
&rTxt
,
522 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
524 if( !nLen
|| !rTxt
.Len() ) return;
525 xub_StrLen nTmp
= nLen
;
526 if ( nTmp
== STRING_LEN
) // schon initialisiert?
531 Size aSize
= (this->GetSize());
532 aPos
.Y() -= ((nEsc
*long(aSize
.Height()))/ 100L);
534 Font
aOldFont( ChgPhysFont( pOut
) );
537 DrawCapital( pOut
, aPos
, rTxt
, nIdx
, nTmp
);
540 Size aSize
= GetPhysTxtSize( pOut
, rTxt
, nIdx
, nTmp
);
543 pOut
->DrawStretchText( aPos
, aSize
.Width(), rTxt
, nIdx
, nTmp
);
545 pOut
->DrawStretchText( aPos
, aSize
.Width(), CalcCaseMap( rTxt
),
548 pOut
->SetFont(aOldFont
);
551 void SvxFont::QuickDrawText( OutputDevice
*pOut
,
552 const Point
&rPos
, const XubString
&rTxt
,
553 const xub_StrLen nIdx
, const xub_StrLen nLen
, const sal_Int32
* pDXArray
) const
555 // Font muss ins OutputDevice selektiert sein...
556 if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
558 pOut
->DrawTextArray( rPos
, rTxt
, pDXArray
, nIdx
, nLen
);
566 long nDiff
= GetSize().Height();
578 DBG_ASSERT( !pDXArray
, "DrawCapital nicht fuer TextArray!" );
579 DrawCapital( pOut
, aPos
, rTxt
, nIdx
, nLen
);
583 if ( IsKern() && !pDXArray
)
585 Size aSize
= GetPhysTxtSize( pOut
, rTxt
, nIdx
, nLen
);
588 pOut
->DrawStretchText( aPos
, aSize
.Width(), rTxt
, nIdx
, nLen
);
590 pOut
->DrawStretchText( aPos
, aSize
.Width(), CalcCaseMap( rTxt
), nIdx
, nLen
);
595 pOut
->DrawTextArray( aPos
, rTxt
, pDXArray
, nIdx
, nLen
);
597 pOut
->DrawTextArray( aPos
, CalcCaseMap( rTxt
), pDXArray
, nIdx
, nLen
);
602 // -----------------------------------------------------------------------
604 void SvxFont::DrawPrev( OutputDevice
*pOut
, Printer
* pPrinter
,
605 const Point
&rPos
, const XubString
&rTxt
,
606 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
608 if ( !nLen
|| !rTxt
.Len() )
610 xub_StrLen nTmp
= nLen
;
612 if ( nTmp
== STRING_LEN
) // schon initialisiert?
619 if( DFLT_ESC_AUTO_SUPER
== nEsc
)
621 else if( DFLT_ESC_AUTO_SUB
== nEsc
)
625 Size aSize
= ( this->GetSize() );
626 aPos
.Y() -= ( ( nTmpEsc
* long( aSize
.Height() ) ) / 100L );
628 Font
aOldFont( ChgPhysFont( pOut
) );
629 Font
aOldPrnFont( ChgPhysFont( pPrinter
) );
632 DrawCapital( pOut
, aPos
, rTxt
, nIdx
, nTmp
);
635 Size aSize
= GetPhysTxtSize( pPrinter
, rTxt
, nIdx
, nTmp
);
638 pOut
->DrawStretchText( aPos
, aSize
.Width(), rTxt
, nIdx
, nTmp
);
642 const XubString aNewText
= CalcCaseMap(rTxt
);
643 sal_Bool
bCaseMapLengthDiffers(aNewText
.Len() != rTxt
.Len());
645 if(bCaseMapLengthDiffers
)
647 // If strings differ work preparing the necessary snippet to address that
648 // potential difference
649 const XubString
aSnippet(rTxt
, nIdx
, nTmp
);
650 XubString _aNewText
= CalcCaseMap(aSnippet
);
652 pOut
->DrawStretchText( aPos
, aSize
.Width(), _aNewText
, 0, _aNewText
.Len() );
656 pOut
->DrawStretchText( aPos
, aSize
.Width(), CalcCaseMap( rTxt
), nIdx
, nTmp
);
660 pOut
->SetFont(aOldFont
);
661 pPrinter
->SetFont( aOldPrnFont
);
664 // -----------------------------------------------------------------------
666 SvxFont
& SvxFont::operator=( const Font
& rFont
)
668 Font::operator=( rFont
);
672 SvxFont
& SvxFont::operator=( const SvxFont
& rFont
)
674 Font::operator=( rFont
);
676 eCaseMap
= rFont
.eCaseMap
;
678 nPropr
= rFont
.nPropr
;
684 /*************************************************************************
685 * class SvxDoGetCapitalSize
686 * wird von SvxFont::GetCapitalSize() zur Berechnung der TxtSize bei
687 * eingestellten Kapitaelchen benutzt.
688 *************************************************************************/
690 class SvxDoGetCapitalSize
: public SvxDoCapitals
697 SvxDoGetCapitalSize( SvxFont
*_pFnt
, const OutputDevice
*_pOut
,
698 const XubString
&_rTxt
, const xub_StrLen _nIdx
,
699 const xub_StrLen _nLen
, const short _nKrn
)
700 : SvxDoCapitals( (OutputDevice
*)_pOut
, _rTxt
, _nIdx
, _nLen
),
705 virtual void Do( const XubString
&rTxt
, const xub_StrLen nIdx
,
706 const xub_StrLen nLen
, const BOOL bUpper
);
708 inline const Size
&GetSize() const { return aTxtSize
; };
711 void SvxDoGetCapitalSize::Do( const XubString
&_rTxt
, const xub_StrLen _nIdx
,
712 const xub_StrLen _nLen
, const BOOL bUpper
)
717 BYTE nProp
= pFont
->GetPropr();
718 pFont
->SetProprRel( KAPITAELCHENPROP
);
719 pFont
->SetPhysFont( pOut
);
720 aPartSize
.setWidth( pOut
->GetTextWidth( _rTxt
, _nIdx
, _nLen
) );
721 aPartSize
.setHeight( pOut
->GetTextHeight() );
722 aTxtSize
.Height() = aPartSize
.Height();
723 pFont
->SetPropr( nProp
);
724 pFont
->SetPhysFont( pOut
);
728 aPartSize
.setWidth( pOut
->GetTextWidth( _rTxt
, _nIdx
, _nLen
) );
729 aPartSize
.setHeight( pOut
->GetTextHeight() );
731 aTxtSize
.Width() += aPartSize
.Width();
732 aTxtSize
.Width() += ( _nLen
* long( nKern
) );
735 /*************************************************************************
736 * SvxFont::GetCapitalSize()
737 * berechnet TxtSize, wenn Kapitaelchen eingestellt sind.
738 *************************************************************************/
740 Size
SvxFont::GetCapitalSize( const OutputDevice
*pOut
, const XubString
&rTxt
,
741 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
744 SvxDoGetCapitalSize
aDo( (SvxFont
*)this, pOut
, rTxt
, nIdx
, nLen
, nKern
);
746 Size
aTxtSize( aDo
.GetSize() );
749 if( !aTxtSize
.Height() )
751 aTxtSize
.setWidth( 0 );
752 aTxtSize
.setHeight( pOut
->GetTextHeight() );
757 /*************************************************************************
758 * class SvxDoDrawCapital
759 * wird von SvxFont::DrawCapital zur Ausgabe von Kapitaelchen benutzt.
760 *************************************************************************/
762 class SvxDoDrawCapital
: public SvxDoCapitals
770 SvxDoDrawCapital( SvxFont
*pFnt
, OutputDevice
*_pOut
, const XubString
&_rTxt
,
771 const xub_StrLen _nIdx
, const xub_StrLen _nLen
,
772 const Point
&rPos
, const short nKrn
)
773 : SvxDoCapitals( _pOut
, _rTxt
, _nIdx
, _nLen
),
779 virtual void DoSpace( const BOOL bDraw
);
780 virtual void SetSpace();
781 virtual void Do( const XubString
&rTxt
, const xub_StrLen nIdx
,
782 const xub_StrLen nLen
, const BOOL bUpper
);
785 void SvxDoDrawCapital::DoSpace( const BOOL bDraw
)
787 if ( bDraw
|| pFont
->IsWordLineMode() )
789 USHORT nDiff
= (USHORT
)(aPos
.X() - aSpacePos
.X());
792 BOOL bWordWise
= pFont
->IsWordLineMode();
793 BOOL bTrans
= pFont
->IsTransparent();
794 pFont
->SetWordLineMode( FALSE
);
795 pFont
->SetTransparent( TRUE
);
796 pFont
->SetPhysFont( pOut
);
797 pOut
->DrawStretchText( aSpacePos
, nDiff
, XubString( sDoubleSpace
,
798 RTL_TEXTENCODING_MS_1252
), 0, 2 );
799 pFont
->SetWordLineMode( bWordWise
);
800 pFont
->SetTransparent( bTrans
);
801 pFont
->SetPhysFont( pOut
);
806 void SvxDoDrawCapital::SetSpace()
808 if ( pFont
->IsWordLineMode() )
809 aSpacePos
.X() = aPos
.X();
812 void SvxDoDrawCapital::Do( const XubString
&_rTxt
, const xub_StrLen _nIdx
,
813 const xub_StrLen _nLen
, const BOOL bUpper
)
818 // Einstellen der gewuenschten Fonts
819 FontUnderline eUnder
= pFont
->GetUnderline();
820 FontStrikeout eStrike
= pFont
->GetStrikeout();
821 pFont
->SetUnderline( UNDERLINE_NONE
);
822 pFont
->SetStrikeout( STRIKEOUT_NONE
);
825 nProp
= pFont
->GetPropr();
826 pFont
->SetProprRel( KAPITAELCHENPROP
);
828 pFont
->SetPhysFont( pOut
);
830 aPartSize
.setWidth( pOut
->GetTextWidth( _rTxt
, _nIdx
, _nLen
) );
831 aPartSize
.setHeight( pOut
->GetTextHeight() );
832 long nWidth
= aPartSize
.Width();
835 aPos
.X() += (nKern
/2);
836 if ( _nLen
) nWidth
+= (_nLen
*long(nKern
));
838 pOut
->DrawStretchText(aPos
,nWidth
-nKern
,_rTxt
,_nIdx
,_nLen
);
841 pFont
->SetUnderline( eUnder
);
842 pFont
->SetStrikeout( eStrike
);
844 pFont
->SetPropr( nProp
);
845 pFont
->SetPhysFont( pOut
);
847 aPos
.X() += nWidth
-(nKern
/2);
850 /*************************************************************************
851 * SvxFont::DrawCapital() gibt Kapitaelchen aus.
852 *************************************************************************/
854 void SvxFont::DrawCapital( OutputDevice
*pOut
,
855 const Point
&rPos
, const XubString
&rTxt
,
856 const xub_StrLen nIdx
, const xub_StrLen nLen
) const
858 SvxDoDrawCapital
aDo( (SvxFont
*)this,pOut
,rTxt
,nIdx
,nLen
,rPos
,nKern
);
862 #endif // !REDUCEDSVXFONT