merge the formfield patch from ooo-build
[ooovba.git] / svx / source / items / svxfont.cxx
blob98c911c8a8500e05807c84351f8ea6e2b4674f55
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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>
38 #endif
39 #ifndef _PRINT_HXX //autogen
40 #include <vcl/print.hxx>
41 #endif
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[] = " ";
61 #endif
63 /*************************************************************************
64 * class SvxFont
65 *************************************************************************/
67 SvxFont::SvxFont()
69 nKern = nEsc = 0;
70 nPropr = 100;
71 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
72 eLang = LANGUAGE_SYSTEM;
75 SvxFont::SvxFont( const Font &rFont )
76 : Font( rFont )
78 nKern = nEsc = 0;
79 nPropr = 100;
80 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
81 eLang = LANGUAGE_SYSTEM;
84 /*************************************************************************
85 * class SvxFont: Copy-Ctor
86 *************************************************************************/
88 SvxFont::SvxFont( const SvxFont &rFont )
89 : Font( 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() )
117 nTop = rRect.Top();
118 nBottom = rRect.Bottom();
120 Polygon aPoly;
121 Point aTmp( bLeft ? nLeft : nRight, nMid );
122 Point aNxt( bLeft ? nRight : nLeft, nTop );
123 aPoly.Insert( 0, aTmp );
124 aPoly.Insert( 0, aNxt );
125 aNxt.Y() = nBottom;
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 ) );
152 switch( eCaseMap )
154 case SVX_CASEMAP_KAPITAELCHEN:
155 case SVX_CASEMAP_VERSALIEN:
157 aCharClass.toUpper( aTxt );
158 break;
161 case SVX_CASEMAP_GEMEINE:
163 aCharClass.toLower( aTxt );
164 break;
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.
171 BOOL bBlank = TRUE;
173 for( USHORT i = 0; i < aTxt.Len(); ++i )
175 if( sal_Unicode(' ') == aTxt.GetChar(i) || sal_Unicode('\t') == aTxt.GetChar(i) )
176 bBlank = TRUE;
177 else
179 if( bBlank )
181 String aTemp( aTxt.GetChar( i ) );
182 aCharClass.toUpper( aTemp );
183 aTxt.Replace( i, 1, aTemp );
185 bBlank = FALSE;
188 break;
190 default:
192 DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
193 break;
196 return aTxt;
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 *************************************************************************/
212 class SvxDoCapitals
214 protected:
215 OutputDevice *pOut;
216 const XubString &rTxt;
217 const xub_StrLen nIdx;
218 const xub_StrLen nLen;
220 public:
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 );
259 USHORT nPos = 0;
260 USHORT nOldPos = nPos;
262 // #108210#
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 ) );
270 String aCharString;
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 )
285 break;
286 if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
287 break;
288 ++nPos;
290 if( nOldPos != nPos )
292 if(bCaseMapLengthDiffers)
294 // #108210#
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 );
302 else
304 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, TRUE );
307 nOldPos = nPos;
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 ) )
314 break;
315 if ( CH_BLANK == aCharString )
316 break;
317 if( ++nPos < nTxtLen )
318 aCharString = rTxt.GetChar( nPos + nIdx );
320 if( nOldPos != nPos )
322 if(bCaseMapLengthDiffers)
324 // #108210#
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 );
332 else
334 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, FALSE );
337 nOldPos = nPos;
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)
349 // #108210#
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 );
357 else
359 rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, FALSE );
362 nOldPos = nPos;
363 rDo.SetSpace();
366 rDo.DoSpace( TRUE );
369 /**************************************************************************
370 * SvxFont::SetPhysFont()
371 *************************************************************************/
373 void SvxFont::SetPhysFont( OutputDevice *pOut ) const
375 const Font& rCurrentFont = pOut->GetFont();
376 if ( nPropr == 100 )
378 if ( !rCurrentFont.IsSameInstance( *this ) )
379 pOut->SetFont( *this );
381 else
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() );
399 SetPhysFont( pOut );
400 return aOldFont;
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() );
414 Size aTxtSize;
415 aTxtSize.setHeight( pOut->GetTextHeight() );
416 if ( !IsCaseMap() )
417 aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
418 else
420 // #108210#
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() );
433 else
435 nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
438 aTxtSize.setWidth(nWidth);
441 if( IsKern() && ( nLen > 1 ) )
442 aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
444 return aTxtSize;
447 Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt )
449 if ( !IsCaseMap() && !IsKern() )
450 return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
452 Size aTxtSize;
453 aTxtSize.setHeight( pOut->GetTextHeight() );
454 if ( !IsCaseMap() )
455 aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
456 else
457 aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
459 if( IsKern() && ( rTxt.Len() > 1 ) )
460 aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) );
462 return aTxtSize;
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() );
472 Size aTxtSize;
473 aTxtSize.setHeight( pOut->GetTextHeight() );
474 if ( !IsCaseMap() )
475 aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
476 else
477 aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
478 pDXArray, nIdx, nLen ) );
480 if( IsKern() && ( nLen > 1 ) )
482 aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
484 if ( pDXArray )
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;
492 return aTxtSize;
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?
504 nTmp = rTxt.Len();
505 Font aOldFont( ChgPhysFont((OutputDevice *)pOut) );
506 Size aTxtSize;
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 );
513 return aTxtSize;
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?
527 nTmp = rTxt.Len();
528 Point aPos( rPos );
529 if ( nEsc )
531 Size aSize = (this->GetSize());
532 aPos.Y() -= ((nEsc*long(aSize.Height()))/ 100L);
534 Font aOldFont( ChgPhysFont( pOut ) );
536 if ( IsCapital() )
537 DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
538 else
540 Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nTmp );
542 if ( !IsCaseMap() )
543 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
544 else
545 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ),
546 nIdx, nTmp );
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 );
559 return;
562 Point aPos( rPos );
564 if ( nEsc )
566 long nDiff = GetSize().Height();
567 nDiff *= nEsc;
568 nDiff /= 100;
570 if ( !IsVertical() )
571 aPos.Y() -= nDiff;
572 else
573 aPos.X() += nDiff;
576 if( IsCapital() )
578 DBG_ASSERT( !pDXArray, "DrawCapital nicht fuer TextArray!" );
579 DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
581 else
583 if ( IsKern() && !pDXArray )
585 Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
587 if ( !IsCaseMap() )
588 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
589 else
590 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
592 else
594 if ( !IsCaseMap() )
595 pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
596 else
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() )
609 return;
610 xub_StrLen nTmp = nLen;
612 if ( nTmp == STRING_LEN ) // schon initialisiert?
613 nTmp = rTxt.Len();
614 Point aPos( rPos );
616 if ( nEsc )
618 short nTmpEsc;
619 if( DFLT_ESC_AUTO_SUPER == nEsc )
620 nTmpEsc = 33;
621 else if( DFLT_ESC_AUTO_SUB == nEsc )
622 nTmpEsc = -20;
623 else
624 nTmpEsc = nEsc;
625 Size aSize = ( this->GetSize() );
626 aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
628 Font aOldFont( ChgPhysFont( pOut ) );
629 Font aOldPrnFont( ChgPhysFont( pPrinter ) );
631 if ( IsCapital() )
632 DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
633 else
635 Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
637 if ( !IsCaseMap() )
638 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
639 else
641 // #108210#
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() );
654 else
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 );
669 return *this;
672 SvxFont& SvxFont::operator=( const SvxFont& rFont )
674 Font::operator=( rFont );
675 eLang = rFont.eLang;
676 eCaseMap = rFont.eCaseMap;
677 nEsc = rFont.nEsc;
678 nPropr = rFont.nPropr;
679 nKern = rFont.nKern;
680 return *this;
684 /*************************************************************************
685 * class SvxDoGetCapitalSize
686 * wird von SvxFont::GetCapitalSize() zur Berechnung der TxtSize bei
687 * eingestellten Kapitaelchen benutzt.
688 *************************************************************************/
690 class SvxDoGetCapitalSize : public SvxDoCapitals
692 protected:
693 SvxFont* pFont;
694 Size aTxtSize;
695 short nKern;
696 public:
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 ),
701 pFont( _pFnt ),
702 nKern( _nKrn )
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 )
714 Size aPartSize;
715 if ( !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 );
726 else
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
743 // Start:
744 SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern );
745 DoOnCapitals( aDo );
746 Size aTxtSize( aDo.GetSize() );
748 // End:
749 if( !aTxtSize.Height() )
751 aTxtSize.setWidth( 0 );
752 aTxtSize.setHeight( pOut->GetTextHeight() );
754 return aTxtSize;
757 /*************************************************************************
758 * class SvxDoDrawCapital
759 * wird von SvxFont::DrawCapital zur Ausgabe von Kapitaelchen benutzt.
760 *************************************************************************/
762 class SvxDoDrawCapital : public SvxDoCapitals
764 protected:
765 SvxFont *pFont;
766 Point aPos;
767 Point aSpacePos;
768 short nKern;
769 public:
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 ),
774 pFont( pFnt ),
775 aPos( rPos ),
776 aSpacePos( rPos ),
777 nKern( nKrn )
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());
790 if ( nDiff )
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)
815 BYTE nProp = 0;
816 Size aPartSize;
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 );
823 if ( !bUpper )
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();
833 if ( nKern )
835 aPos.X() += (nKern/2);
836 if ( _nLen ) nWidth += (_nLen*long(nKern));
838 pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
840 // Font restaurieren
841 pFont->SetUnderline( eUnder );
842 pFont->SetStrikeout( eStrike );
843 if ( !bUpper )
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 );
859 DoOnCapitals( aDo );
862 #endif // !REDUCEDSVXFONT