diff options
Diffstat (limited to 'editeng/source/items/svxfont.cxx')
-rw-r--r-- | editeng/source/items/svxfont.cxx | 857 |
1 files changed, 857 insertions, 0 deletions
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx new file mode 100644 index 000000000000..769147099ce0 --- /dev/null +++ b/editeng/source/items/svxfont.cxx @@ -0,0 +1,857 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_editeng.hxx" + +// include ---------------------------------------------------------------- + +#include <vcl/outdev.hxx> +#include <vcl/print.hxx> +#include <tools/poly.hxx> +#include <unotools/charclass.hxx> +#include <editeng/unolingu.hxx> +#include <com/sun/star/i18n/KCharacterType.hpp> + +#define _SVX_SVXFONT_CXX + +#include <editeng/svxfont.hxx> +#include <editeng/escpitem.hxx> + +// Minimum: Prozentwert fuers kernen +#define MINKERNPERCENT 5 + +// prop. Groesse der Kleinbuchstaben bei Kapitaelchen +#define KAPITAELCHENPROP 66 + +#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, 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. + BOOL bBlank = TRUE; + + for( USHORT i = 0; i < aTxt.Len(); ++i ) + { + if( sal_Unicode(' ') == aTxt.GetChar(i) || sal_Unicode('\t') == aTxt.GetChar(i) ) + bBlank = TRUE; + else + { + if( bBlank ) + { + String aTemp( aTxt.GetChar( i ) ); + aCharClass.toUpper( aTemp ); + aTxt.Replace( i, 1, aTemp ); + } + bBlank = FALSE; + } + } + break; + } + default: + { + DBG_ASSERT(!this, "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 BOOL bDraw ); + virtual void SetSpace(); + virtual void Do( const XubString &rTxt, + const xub_StrLen nIdx, const xub_StrLen nLen, + const 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 BOOL /*bDraw*/ ) { } + +void SvxDoCapitals::SetSpace() { } + +void SvxDoCapitals::Do( const XubString &/*_rTxt*/, const xub_StrLen /*_nIdx*/, + const xub_StrLen /*_nLen*/, const 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 USHORT nTxtLen = Min( rTxt.Len(), nLen ); + USHORT nPos = 0; + USHORT 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(), TRUE ); + } + else + { + rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, 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(), FALSE ); + } + else + { + rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, 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( 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(), FALSE ); + } + else + { + rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, FALSE ); + } + + nOldPos = nPos; + rDo.SetSpace(); + } + } + rDo.DoSpace( 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 USHORT nIdx, const USHORT 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 BOOL bUpper ); + + inline const Size &GetSize() const { return aTxtSize; }; +}; + +void SvxDoGetCapitalSize::Do( const XubString &_rTxt, const xub_StrLen _nIdx, + const xub_StrLen _nLen, const BOOL bUpper ) +{ + Size aPartSize; + if ( !bUpper ) + { + BYTE 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 BOOL bDraw ); + virtual void SetSpace(); + virtual void Do( const XubString &rTxt, const xub_StrLen nIdx, + const xub_StrLen nLen, const BOOL bUpper ); +}; + +void SvxDoDrawCapital::DoSpace( const BOOL bDraw ) +{ + if ( bDraw || pFont->IsWordLineMode() ) + { + USHORT nDiff = (USHORT)(aPos.X() - aSpacePos.X()); + if ( nDiff ) + { + BOOL bWordWise = pFont->IsWordLineMode(); + BOOL bTrans = pFont->IsTransparent(); + pFont->SetWordLineMode( FALSE ); + pFont->SetTransparent( 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 BOOL bUpper) +{ + BYTE 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 + + |