Bump for 3.6-28
[LibreOffice.git] / editeng / source / items / svxfont.cxx
blob02bca71f887ad285d86a37f24bbc2c43bed829d4
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[] = " ";
50 #endif
53 SvxFont::SvxFont()
55 nKern = nEsc = 0;
56 nPropr = 100;
57 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
58 eLang = LANGUAGE_SYSTEM;
61 SvxFont::SvxFont( const Font &rFont )
62 : Font( rFont )
64 nKern = nEsc = 0;
65 nPropr = 100;
66 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
67 eLang = LANGUAGE_SYSTEM;
70 SvxFont::SvxFont( const SvxFont &rFont )
71 : Font( 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() )
91 nLeft = rRect.Left();
92 nRight = rRect.Right();
94 if( nTop < rRect.Top() )
96 nTop = rRect.Top();
97 nBottom = rRect.Bottom();
99 Polygon aPoly;
100 Point aTmp( bLeft ? nLeft : nRight, nMid );
101 Point aNxt( bLeft ? nRight : nLeft, nTop );
102 aPoly.Insert( 0, aTmp );
103 aPoly.Insert( 0, aNxt );
104 aNxt.Y() = nBottom;
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 ) );
128 switch( eCaseMap )
130 case SVX_CASEMAP_KAPITAELCHEN:
131 case SVX_CASEMAP_VERSALIEN:
133 aTxt = aCharClass.uppercase( aTxt );
134 break;
137 case SVX_CASEMAP_GEMEINE:
139 aTxt = aCharClass.lowercase( aTxt );
140 break;
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) )
152 bBlank = sal_True;
153 else
155 if( bBlank )
157 String aTemp( aTxt.GetChar( i ) );
158 aTemp = aCharClass.uppercase( aTemp );
159 aTxt.Replace( i, 1, aTemp );
161 bBlank = sal_False;
164 break;
166 default:
168 DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
169 break;
172 return aTxt;
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 *************************************************************************/
188 class SvxDoCapitals
190 protected:
191 OutputDevice *pOut;
192 const XubString &rTxt;
193 const xub_StrLen nIdx;
194 const xub_StrLen nLen;
196 public:
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 );
234 sal_uInt16 nPos = 0;
235 sal_uInt16 nOldPos = nPos;
237 // #108210#
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 ) );
245 String aCharString;
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 )
260 break;
261 if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
262 break;
263 ++nPos;
265 if( nOldPos != nPos )
267 if(bCaseMapLengthDiffers)
269 // #108210#
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 );
277 else
279 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_True );
282 nOldPos = nPos;
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 ) )
289 break;
290 if ( CH_BLANK == aCharString )
291 break;
292 if( ++nPos < nTxtLen )
293 aCharString = rTxt.GetChar( nPos + nIdx );
295 if( nOldPos != nPos )
297 if(bCaseMapLengthDiffers)
299 // #108210#
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 );
307 else
309 rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_False );
312 nOldPos = nPos;
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)
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(), sal_False );
332 else
334 rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, sal_False );
337 nOldPos = nPos;
338 rDo.SetSpace();
341 rDo.DoSpace( sal_True );
345 void SvxFont::SetPhysFont( OutputDevice *pOut ) const
347 const Font& rCurrentFont = pOut->GetFont();
348 if ( nPropr == 100 )
350 if ( !rCurrentFont.IsSameInstance( *this ) )
351 pOut->SetFont( *this );
353 else
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() );
368 SetPhysFont( pOut );
369 return aOldFont;
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() );
380 Size aTxtSize;
381 aTxtSize.setHeight( pOut->GetTextHeight() );
382 if ( !IsCaseMap() )
383 aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
384 else
386 // #108210#
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() );
399 else
401 nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
404 aTxtSize.setWidth(nWidth);
407 if( IsKern() && ( nLen > 1 ) )
408 aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
410 return aTxtSize;
413 Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt )
415 if ( !IsCaseMap() && !IsKern() )
416 return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
418 Size aTxtSize;
419 aTxtSize.setHeight( pOut->GetTextHeight() );
420 if ( !IsCaseMap() )
421 aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
422 else
423 aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
425 if( IsKern() && ( rTxt.Len() > 1 ) )
426 aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) );
428 return aTxtSize;
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() );
438 Size aTxtSize;
439 aTxtSize.setHeight( pOut->GetTextHeight() );
440 if ( !IsCaseMap() )
441 aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
442 else
443 aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
444 pDXArray, nIdx, nLen ) );
446 if( IsKern() && ( nLen > 1 ) )
448 aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
450 if ( pDXArray )
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;
458 return aTxtSize;
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?
467 nTmp = rTxt.Len();
468 Font aOldFont( ChgPhysFont((OutputDevice *)pOut) );
469 Size aTxtSize;
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 );
476 return aTxtSize;
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 );
488 return;
491 Point aPos( rPos );
493 if ( nEsc )
495 long nDiff = GetSize().Height();
496 nDiff *= nEsc;
497 nDiff /= 100;
499 if ( !IsVertical() )
500 aPos.Y() -= nDiff;
501 else
502 aPos.X() += nDiff;
505 if( IsCapital() )
507 DBG_ASSERT( !pDXArray, "DrawCapital not for TextArray!" );
508 DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
510 else
512 if ( IsKern() && !pDXArray )
514 Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
516 if ( !IsCaseMap() )
517 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
518 else
519 pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
521 else
523 if ( !IsCaseMap() )
524 pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
525 else
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() )
537 return;
538 xub_StrLen nTmp = nLen;
540 if ( nTmp == STRING_LEN ) // already initialized?
541 nTmp = rTxt.Len();
542 Point aPos( rPos );
544 if ( nEsc )
546 short nTmpEsc;
547 if( DFLT_ESC_AUTO_SUPER == nEsc )
548 nTmpEsc = 33;
549 else if( DFLT_ESC_AUTO_SUB == nEsc )
550 nTmpEsc = -20;
551 else
552 nTmpEsc = nEsc;
553 Size aSize = ( this->GetSize() );
554 aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
556 Font aOldFont( ChgPhysFont( pOut ) );
557 Font aOldPrnFont( ChgPhysFont( pPrinter ) );
559 if ( IsCapital() )
560 DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
561 else
563 Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
565 if ( !IsCaseMap() )
566 pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
567 else
569 // #108210#
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() );
582 else
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 );
596 return *this;
599 SvxFont& SvxFont::operator=( const SvxFont& rFont )
601 Font::operator=( rFont );
602 eLang = rFont.eLang;
603 eCaseMap = rFont.eCaseMap;
604 nEsc = rFont.nEsc;
605 nPropr = rFont.nPropr;
606 nKern = rFont.nKern;
607 return *this;
610 class SvxDoGetCapitalSize : public SvxDoCapitals
612 protected:
613 SvxFont* pFont;
614 Size aTxtSize;
615 short nKern;
616 public:
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 ),
621 pFont( _pFnt ),
622 nKern( _nKrn )
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 )
636 Size aPartSize;
637 if ( !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 );
648 else
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
660 // Start:
661 SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern );
662 DoOnCapitals( aDo );
663 Size aTxtSize( aDo.GetSize() );
665 // End:
666 if( !aTxtSize.Height() )
668 aTxtSize.setWidth( 0 );
669 aTxtSize.setHeight( pOut->GetTextHeight() );
671 return aTxtSize;
674 class SvxDoDrawCapital : public SvxDoCapitals
676 protected:
677 SvxFont *pFont;
678 Point aPos;
679 Point aSpacePos;
680 short nKern;
681 public:
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 ),
686 pFont( pFnt ),
687 aPos( rPos ),
688 aSpacePos( rPos ),
689 nKern( nKrn )
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());
703 if ( nDiff )
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)
728 sal_uInt8 nProp = 0;
729 Size aPartSize;
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 );
736 if ( !bUpper )
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();
746 if ( nKern )
748 aPos.X() += (nKern/2);
749 if ( _nLen ) nWidth += (_nLen*long(nKern));
751 pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
753 // Restore Font
754 pFont->SetUnderline( eUnder );
755 pFont->SetStrikeout( eStrike );
756 if ( !bUpper )
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 );
772 DoOnCapitals( aDo );
775 #endif // !REDUCEDSVXFONT
778 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */