/**************************************************************
 *
 * 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 <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. 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
