/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_editeng.hxx" // include ---------------------------------------------------------------- #include #include #include #include #include #include #define _SVX_SVXFONT_CXX #include #include // Minimum: Prozentwert fuers kernen #define MINKERNPERCENT 5 // prop. Size of the small cap letters #define KAPITAELCHENPROP 74 #ifndef REDUCEDSVXFONT const sal_Unicode CH_BLANK = sal_Unicode(' '); // ' ' Leerzeichen static sal_Char __READONLY_DATA sDoubleSpace[] = " "; #endif /************************************************************************* * class SvxFont *************************************************************************/ SvxFont::SvxFont() { nKern = nEsc = 0; nPropr = 100; eCaseMap = SVX_CASEMAP_NOT_MAPPED; eLang = LANGUAGE_SYSTEM; } SvxFont::SvxFont( const Font &rFont ) : Font( rFont ) { nKern = nEsc = 0; nPropr = 100; eCaseMap = SVX_CASEMAP_NOT_MAPPED; eLang = LANGUAGE_SYSTEM; } /************************************************************************* * class SvxFont: Copy-Ctor *************************************************************************/ SvxFont::SvxFont( const SvxFont &rFont ) : Font( rFont ) { nKern = rFont.GetFixKerning(); nEsc = rFont.GetEscapement(); nPropr = rFont.GetPropr(); eCaseMap = rFont.GetCaseMap(); eLang = rFont.GetLanguage(); } /************************************************************************* * static SvxFont::DrawArrow *************************************************************************/ void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect, const Size& rSize, const Color& rCol, sal_Bool bLeft ) { long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2; long nRight = nLeft + rSize.Width(); long nMid = ( rRect.Top() + rRect.Bottom() ) / 2; long nTop = nMid - rSize.Height() / 2; long nBottom = nTop + rSize.Height(); if( nLeft < rRect.Left() ) { nLeft = rRect.Left(); nRight = rRect.Right(); } if( nTop < rRect.Top() ) { nTop = rRect.Top(); nBottom = rRect.Bottom(); } Polygon aPoly; Point aTmp( bLeft ? nLeft : nRight, nMid ); Point aNxt( bLeft ? nRight : nLeft, nTop ); aPoly.Insert( 0, aTmp ); aPoly.Insert( 0, aNxt ); aNxt.Y() = nBottom; aPoly.Insert( 0, aNxt ); aPoly.Insert( 0, aTmp ); Color aOldLineColor = rOut.GetLineColor(); Color aOldFillColor = rOut.GetFillColor(); rOut.SetFillColor( rCol ); rOut.SetLineColor( Color( COL_BLACK ) ); rOut.DrawPolygon( aPoly ); rOut.DrawLine( aTmp, aNxt ); rOut.SetLineColor( aOldLineColor ); rOut.SetFillColor( aOldFillColor ); } /************************************************************************* * SvxFont::CalcCaseMap *************************************************************************/ XubString SvxFont::CalcCaseMap( const XubString &rTxt ) const { if( !IsCaseMap() || !rTxt.Len() ) return rTxt; XubString aTxt( rTxt ); // Ich muss mir noch die Sprache besorgen const LanguageType eLng = LANGUAGE_DONTKNOW == eLang ? LANGUAGE_SYSTEM : eLang; CharClass aCharClass( SvxCreateLocale( eLng ) ); switch( eCaseMap ) { case SVX_CASEMAP_KAPITAELCHEN: case SVX_CASEMAP_VERSALIEN: { aCharClass.toUpper( aTxt ); break; } case SVX_CASEMAP_GEMEINE: { aCharClass.toLower( aTxt ); break; } case SVX_CASEMAP_TITEL: { // Jeder Wortbeginn wird gross geschrieben, // der Rest des Wortes wird unbesehen uebernommen. // Bug: wenn das Attribut mitten im Wort beginnt. sal_Bool bBlank = sal_True; for( sal_uInt16 i = 0; i < aTxt.Len(); ++i ) { if( sal_Unicode(' ') == aTxt.GetChar(i) || sal_Unicode('\t') == aTxt.GetChar(i) ) bBlank = sal_True; else { if( bBlank ) { String aTemp( aTxt.GetChar( i ) ); aCharClass.toUpper( aTemp ); aTxt.Replace( i, 1, aTemp ); } bBlank = sal_False; } } break; } default: { DBG_ASSERT(sal_False, "SvxFont::CaseMapTxt: unknown casemap"); break; } } return aTxt; } /************************************************************************* * Hier beginnen die Methoden, die im Writer nicht benutzt werden koennen, * deshalb kann man diesen Bereich durch setzen von REDUCEDSVXFONT ausklammern. *************************************************************************/ #ifndef REDUCEDSVXFONT /************************************************************************* * class SvxDoCapitals * die virtuelle Methode Do wird von SvxFont::DoOnCapitals abwechselnd mit * den "Gross-" und "Kleinbuchstaben"-Teilen aufgerufen. * Die Ableitungen von SvxDoCapitals erfuellen diese Methode mit Leben. *************************************************************************/ class SvxDoCapitals { protected: OutputDevice *pOut; const XubString &rTxt; const xub_StrLen nIdx; const xub_StrLen nLen; public: SvxDoCapitals( OutputDevice *_pOut, const XubString &_rTxt, const xub_StrLen _nIdx, const xub_StrLen _nLen ) : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen) { } virtual void DoSpace( const sal_Bool bDraw ); virtual void SetSpace(); virtual void Do( const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Bool bUpper ) = 0; inline OutputDevice *GetOut() { return pOut; } inline const XubString &GetTxt() const { return rTxt; } xub_StrLen GetIdx() const { return nIdx; } xub_StrLen GetLen() const { return nLen; } }; void SvxDoCapitals::DoSpace( const sal_Bool /*bDraw*/ ) { } void SvxDoCapitals::SetSpace() { } void SvxDoCapitals::Do( const XubString &/*_rTxt*/, const xub_StrLen /*_nIdx*/, const xub_StrLen /*_nLen*/, const sal_Bool /*bUpper*/ ) { } /************************************************************************* * SvxFont::DoOnCapitals() const * zerlegt den String in Gross- und Kleinbuchstaben und ruft jeweils die * Methode SvxDoCapitals::Do( ) auf. *************************************************************************/ void SvxFont::DoOnCapitals(SvxDoCapitals &rDo, const xub_StrLen nPartLen) const { const XubString &rTxt = rDo.GetTxt(); const xub_StrLen nIdx = rDo.GetIdx(); const xub_StrLen nLen = STRING_LEN == nPartLen ? rDo.GetLen() : nPartLen; const XubString aTxt( CalcCaseMap( rTxt ) ); const sal_uInt16 nTxtLen = Min( rTxt.Len(), nLen ); sal_uInt16 nPos = 0; sal_uInt16 nOldPos = nPos; // #108210# // Test if string length differ between original and CaseMapped sal_Bool bCaseMapLengthDiffers(aTxt.Len() != rTxt.Len()); const LanguageType eLng = LANGUAGE_DONTKNOW == eLang ? LANGUAGE_SYSTEM : eLang; CharClass aCharClass( SvxCreateLocale( eLng ) ); String aCharString; while( nPos < nTxtLen ) { // Erst kommen die Upper-Chars dran // 4251: Es gibt Zeichen, die Upper _und_ Lower sind (z.B. das Blank). // Solche Zweideutigkeiten fuehren ins Chaos, deswegen werden diese // Zeichen der Menge Lower zugeordnet ! while( nPos < nTxtLen ) { aCharString = rTxt.GetChar( nPos + nIdx ); sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 ); if ( nCharacterType & ::com::sun::star::i18n::KCharacterType::LOWER ) break; if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) ) break; ++nPos; } if( nOldPos != nPos ) { if(bCaseMapLengthDiffers) { // #108210# // If strings differ work preparing the necessary snippet to address that // potential difference const XubString aSnippet(rTxt, nIdx + nOldPos, nPos-nOldPos); XubString aNewText = CalcCaseMap(aSnippet); rDo.Do( aNewText, 0, aNewText.Len(), sal_True ); } else { rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_True ); } nOldPos = nPos; } // Nun werden die Lower-Chars verarbeitet (ohne Blanks) while( nPos < nTxtLen ) { sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 ); if ( ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) ) break; if ( CH_BLANK == aCharString ) break; if( ++nPos < nTxtLen ) aCharString = rTxt.GetChar( nPos + nIdx ); } if( nOldPos != nPos ) { if(bCaseMapLengthDiffers) { // #108210# // If strings differ work preparing the necessary snippet to address that // potential difference const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos); XubString aNewText = CalcCaseMap(aSnippet); rDo.Do( aNewText, 0, aNewText.Len(), sal_False ); } else { rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_False ); } nOldPos = nPos; } // Nun werden die Blanks verarbeitet while( nPos < nTxtLen && CH_BLANK == aCharString && ++nPos < nTxtLen ) aCharString = rTxt.GetChar( nPos + nIdx ); if( nOldPos != nPos ) { rDo.DoSpace( sal_False ); if(bCaseMapLengthDiffers) { // #108210# // If strings differ work preparing the necessary snippet to address that // potential difference const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos); XubString aNewText = CalcCaseMap(aSnippet); rDo.Do( aNewText, 0, aNewText.Len(), sal_False ); } else { rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, sal_False ); } nOldPos = nPos; rDo.SetSpace(); } } rDo.DoSpace( sal_True ); } /************************************************************************** * SvxFont::SetPhysFont() *************************************************************************/ void SvxFont::SetPhysFont( OutputDevice *pOut ) const { const Font& rCurrentFont = pOut->GetFont(); if ( nPropr == 100 ) { if ( !rCurrentFont.IsSameInstance( *this ) ) pOut->SetFont( *this ); } else { Font aNewFont( *this ); Size aSize( aNewFont.GetSize() ); aNewFont.SetSize( Size( aSize.Width() * nPropr / 100L, aSize.Height() * nPropr / 100L ) ); if ( !rCurrentFont.IsSameInstance( aNewFont ) ) pOut->SetFont( aNewFont ); } } /************************************************************************* * SvxFont::ChgPhysFont() *************************************************************************/ Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const { Font aOldFont( pOut->GetFont() ); SetPhysFont( pOut ); return aOldFont; } /************************************************************************* * SvxFont::GetPhysTxtSize() *************************************************************************/ Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen ) const { if ( !IsCaseMap() && !IsKern() ) return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ), pOut->GetTextHeight() ); Size aTxtSize; aTxtSize.setHeight( pOut->GetTextHeight() ); if ( !IsCaseMap() ) aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) ); else { // #108210# const XubString aNewText = CalcCaseMap(rTxt); sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len()); sal_Int32 nWidth(0L); if(bCaseMapLengthDiffers) { // If strings differ work preparing the necessary snippet to address that // potential difference const XubString aSnippet(rTxt, nIdx, nLen); XubString _aNewText = CalcCaseMap(aSnippet); nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.Len() ); } else { nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen ); } aTxtSize.setWidth(nWidth); } if( IsKern() && ( nLen > 1 ) ) aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) ); return aTxtSize; } Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt ) { if ( !IsCaseMap() && !IsKern() ) return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() ); Size aTxtSize; aTxtSize.setHeight( pOut->GetTextHeight() ); if ( !IsCaseMap() ) aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) ); else aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) ); if( IsKern() && ( rTxt.Len() > 1 ) ) aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) ); return aTxtSize; } Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const XubString &rTxt, const sal_uInt16 nIdx, const sal_uInt16 nLen, sal_Int32* pDXArray ) const { if ( !IsCaseMap() && !IsKern() ) return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ), pOut->GetTextHeight() ); Size aTxtSize; aTxtSize.setHeight( pOut->GetTextHeight() ); if ( !IsCaseMap() ) aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) ); else aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ), pDXArray, nIdx, nLen ) ); if( IsKern() && ( nLen > 1 ) ) { aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) ); if ( pDXArray ) { for ( xub_StrLen i = 0; i < nLen; i++ ) pDXArray[i] += ( (i+1) * long( nKern ) ); // Der letzte ist um ein nKern zu gross: pDXArray[nLen-1] -= nKern; } } return aTxtSize; } /************************************************************************* * SvxFont::GetTxtSize() *************************************************************************/ Size SvxFont::GetTxtSize( const OutputDevice *pOut, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen ) { xub_StrLen nTmp = nLen; if ( nTmp == STRING_LEN ) // schon initialisiert? nTmp = rTxt.Len(); Font aOldFont( ChgPhysFont((OutputDevice *)pOut) ); Size aTxtSize; if( IsCapital() && rTxt.Len() ) { aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp ); } else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp); ((OutputDevice *)pOut)->SetFont( aOldFont ); return aTxtSize; } /************************************************************************* * SvxFont::DrawText() *************************************************************************/ void SvxFont::DrawText( OutputDevice *pOut, const Point &rPos, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen ) const { if( !nLen || !rTxt.Len() ) return; xub_StrLen nTmp = nLen; if ( nTmp == STRING_LEN ) // schon initialisiert? nTmp = rTxt.Len(); Point aPos( rPos ); if ( nEsc ) { Size aSize = (this->GetSize()); aPos.Y() -= ((nEsc*long(aSize.Height()))/ 100L); } Font aOldFont( ChgPhysFont( pOut ) ); if ( IsCapital() ) DrawCapital( pOut, aPos, rTxt, nIdx, nTmp ); else { Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nTmp ); if ( !IsCaseMap() ) pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp ); else pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp ); } pOut->SetFont(aOldFont); } void SvxFont::QuickDrawText( OutputDevice *pOut, const Point &rPos, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Int32* pDXArray ) const { // Font muss ins OutputDevice selektiert sein... if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() ) { pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen ); return; } Point aPos( rPos ); if ( nEsc ) { long nDiff = GetSize().Height(); nDiff *= nEsc; nDiff /= 100; if ( !IsVertical() ) aPos.Y() -= nDiff; else aPos.X() += nDiff; } if( IsCapital() ) { DBG_ASSERT( !pDXArray, "DrawCapital nicht fuer TextArray!" ); DrawCapital( pOut, aPos, rTxt, nIdx, nLen ); } else { if ( IsKern() && !pDXArray ) { Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen ); if ( !IsCaseMap() ) pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen ); else pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen ); } else { if ( !IsCaseMap() ) pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen ); else pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen ); } } } // ----------------------------------------------------------------------- void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter, const Point &rPos, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen ) const { if ( !nLen || !rTxt.Len() ) return; xub_StrLen nTmp = nLen; if ( nTmp == STRING_LEN ) // schon initialisiert? nTmp = rTxt.Len(); Point aPos( rPos ); if ( nEsc ) { short nTmpEsc; if( DFLT_ESC_AUTO_SUPER == nEsc ) nTmpEsc = 33; else if( DFLT_ESC_AUTO_SUB == nEsc ) nTmpEsc = -20; else nTmpEsc = nEsc; Size aSize = ( this->GetSize() ); aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L ); } Font aOldFont( ChgPhysFont( pOut ) ); Font aOldPrnFont( ChgPhysFont( pPrinter ) ); if ( IsCapital() ) DrawCapital( pOut, aPos, rTxt, nIdx, nTmp ); else { Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp ); if ( !IsCaseMap() ) pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp ); else { // #108210# const XubString aNewText = CalcCaseMap(rTxt); sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len()); if(bCaseMapLengthDiffers) { // If strings differ work preparing the necessary snippet to address that // potential difference const XubString aSnippet(rTxt, nIdx, nTmp); XubString _aNewText = CalcCaseMap(aSnippet); pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.Len() ); } else { pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp ); } } } pOut->SetFont(aOldFont); pPrinter->SetFont( aOldPrnFont ); } // ----------------------------------------------------------------------- SvxFont& SvxFont::operator=( const Font& rFont ) { Font::operator=( rFont ); return *this; } SvxFont& SvxFont::operator=( const SvxFont& rFont ) { Font::operator=( rFont ); eLang = rFont.eLang; eCaseMap = rFont.eCaseMap; nEsc = rFont.nEsc; nPropr = rFont.nPropr; nKern = rFont.nKern; return *this; } /************************************************************************* * class SvxDoGetCapitalSize * wird von SvxFont::GetCapitalSize() zur Berechnung der TxtSize bei * eingestellten Kapitaelchen benutzt. *************************************************************************/ class SvxDoGetCapitalSize : public SvxDoCapitals { protected: SvxFont* pFont; Size aTxtSize; short nKern; public: SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut, const XubString &_rTxt, const xub_StrLen _nIdx, const xub_StrLen _nLen, const short _nKrn ) : SvxDoCapitals( (OutputDevice*)_pOut, _rTxt, _nIdx, _nLen ), pFont( _pFnt ), nKern( _nKrn ) { } virtual void Do( const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Bool bUpper ); inline const Size &GetSize() const { return aTxtSize; }; }; void SvxDoGetCapitalSize::Do( const XubString &_rTxt, const xub_StrLen _nIdx, const xub_StrLen _nLen, const sal_Bool bUpper ) { Size aPartSize; if ( !bUpper ) { sal_uInt8 nProp = pFont->GetPropr(); pFont->SetProprRel( KAPITAELCHENPROP ); pFont->SetPhysFont( pOut ); aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); aPartSize.setHeight( pOut->GetTextHeight() ); aTxtSize.Height() = aPartSize.Height(); pFont->SetPropr( nProp ); pFont->SetPhysFont( pOut ); } else { aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); aPartSize.setHeight( pOut->GetTextHeight() ); } aTxtSize.Width() += aPartSize.Width(); aTxtSize.Width() += ( _nLen * long( nKern ) ); } /************************************************************************* * SvxFont::GetCapitalSize() * berechnet TxtSize, wenn Kapitaelchen eingestellt sind. *************************************************************************/ Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen) const { // Start: SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern ); DoOnCapitals( aDo ); Size aTxtSize( aDo.GetSize() ); // End: if( !aTxtSize.Height() ) { aTxtSize.setWidth( 0 ); aTxtSize.setHeight( pOut->GetTextHeight() ); } return aTxtSize; } /************************************************************************* * class SvxDoDrawCapital * wird von SvxFont::DrawCapital zur Ausgabe von Kapitaelchen benutzt. *************************************************************************/ class SvxDoDrawCapital : public SvxDoCapitals { protected: SvxFont *pFont; Point aPos; Point aSpacePos; short nKern; public: SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const XubString &_rTxt, const xub_StrLen _nIdx, const xub_StrLen _nLen, const Point &rPos, const short nKrn ) : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ), pFont( pFnt ), aPos( rPos ), aSpacePos( rPos ), nKern( nKrn ) { } virtual void DoSpace( const sal_Bool bDraw ); virtual void SetSpace(); virtual void Do( const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Bool bUpper ); }; void SvxDoDrawCapital::DoSpace( const sal_Bool bDraw ) { if ( bDraw || pFont->IsWordLineMode() ) { sal_uInt16 nDiff = (sal_uInt16)(aPos.X() - aSpacePos.X()); if ( nDiff ) { sal_Bool bWordWise = pFont->IsWordLineMode(); sal_Bool bTrans = pFont->IsTransparent(); pFont->SetWordLineMode( sal_False ); pFont->SetTransparent( sal_True ); pFont->SetPhysFont( pOut ); pOut->DrawStretchText( aSpacePos, nDiff, XubString( sDoubleSpace, RTL_TEXTENCODING_MS_1252 ), 0, 2 ); pFont->SetWordLineMode( bWordWise ); pFont->SetTransparent( bTrans ); pFont->SetPhysFont( pOut ); } } } void SvxDoDrawCapital::SetSpace() { if ( pFont->IsWordLineMode() ) aSpacePos.X() = aPos.X(); } void SvxDoDrawCapital::Do( const XubString &_rTxt, const xub_StrLen _nIdx, const xub_StrLen _nLen, const sal_Bool bUpper) { sal_uInt8 nProp = 0; Size aPartSize; // Einstellen der gewuenschten Fonts FontUnderline eUnder = pFont->GetUnderline(); FontStrikeout eStrike = pFont->GetStrikeout(); pFont->SetUnderline( UNDERLINE_NONE ); pFont->SetStrikeout( STRIKEOUT_NONE ); if ( !bUpper ) { nProp = pFont->GetPropr(); pFont->SetProprRel( KAPITAELCHENPROP ); } pFont->SetPhysFont( pOut ); aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); aPartSize.setHeight( pOut->GetTextHeight() ); long nWidth = aPartSize.Width(); if ( nKern ) { aPos.X() += (nKern/2); if ( _nLen ) nWidth += (_nLen*long(nKern)); } pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen); // Font restaurieren pFont->SetUnderline( eUnder ); pFont->SetStrikeout( eStrike ); if ( !bUpper ) pFont->SetPropr( nProp ); pFont->SetPhysFont( pOut ); aPos.X() += nWidth-(nKern/2); } /************************************************************************* * SvxFont::DrawCapital() gibt Kapitaelchen aus. *************************************************************************/ void SvxFont::DrawCapital( OutputDevice *pOut, const Point &rPos, const XubString &rTxt, const xub_StrLen nIdx, const xub_StrLen nLen ) const { SvxDoDrawCapital aDo( (SvxFont *)this,pOut,rTxt,nIdx,nLen,rPos,nKern ); DoOnCapitals( aDo ); } #endif // !REDUCEDSVXFONT