xref: /AOO41X/main/editeng/source/items/svxfont.cxx (revision 0f91224e2ffefa56a4e022d1ea8a17968e21da1d)
1cdf0e10cSrcweir /*************************************************************************
2cdf0e10cSrcweir  *
3cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4cdf0e10cSrcweir  *
5cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6cdf0e10cSrcweir  *
7cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8cdf0e10cSrcweir  *
9cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10cdf0e10cSrcweir  *
11cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14cdf0e10cSrcweir  *
15cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20cdf0e10cSrcweir  *
21cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25cdf0e10cSrcweir  *
26cdf0e10cSrcweir  ************************************************************************/
27cdf0e10cSrcweir 
28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29cdf0e10cSrcweir #include "precompiled_editeng.hxx"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir // include ----------------------------------------------------------------
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <vcl/outdev.hxx>
34cdf0e10cSrcweir #include <vcl/print.hxx>
35cdf0e10cSrcweir #include <tools/poly.hxx>
36cdf0e10cSrcweir #include <unotools/charclass.hxx>
37cdf0e10cSrcweir #include <editeng/unolingu.hxx>
38cdf0e10cSrcweir #include <com/sun/star/i18n/KCharacterType.hpp>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #define _SVX_SVXFONT_CXX
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <editeng/svxfont.hxx>
43cdf0e10cSrcweir #include <editeng/escpitem.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir // Minimum: Prozentwert fuers kernen
46cdf0e10cSrcweir #define MINKERNPERCENT 5
47cdf0e10cSrcweir 
48*0f91224eSPedro Giffuni // prop. Size of the small cap letters
49*0f91224eSPedro Giffuni #define KAPITAELCHENPROP 75
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #ifndef REDUCEDSVXFONT
52cdf0e10cSrcweir 	const sal_Unicode CH_BLANK = sal_Unicode(' ');  	// ' ' Leerzeichen
53cdf0e10cSrcweir 	static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
54cdf0e10cSrcweir #endif
55cdf0e10cSrcweir 
56cdf0e10cSrcweir /*************************************************************************
57cdf0e10cSrcweir  *						class SvxFont
58cdf0e10cSrcweir  *************************************************************************/
59cdf0e10cSrcweir 
60cdf0e10cSrcweir SvxFont::SvxFont()
61cdf0e10cSrcweir {
62cdf0e10cSrcweir 	nKern = nEsc = 0;
63cdf0e10cSrcweir 	nPropr = 100;
64cdf0e10cSrcweir 	eCaseMap = SVX_CASEMAP_NOT_MAPPED;
65cdf0e10cSrcweir 	eLang = LANGUAGE_SYSTEM;
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir SvxFont::SvxFont( const Font &rFont )
69cdf0e10cSrcweir 	: Font( rFont )
70cdf0e10cSrcweir {
71cdf0e10cSrcweir 	nKern = nEsc = 0;
72cdf0e10cSrcweir 	nPropr = 100;
73cdf0e10cSrcweir 	eCaseMap = SVX_CASEMAP_NOT_MAPPED;
74cdf0e10cSrcweir 	eLang = LANGUAGE_SYSTEM;
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir /*************************************************************************
78cdf0e10cSrcweir  *						class SvxFont: Copy-Ctor
79cdf0e10cSrcweir  *************************************************************************/
80cdf0e10cSrcweir 
81cdf0e10cSrcweir SvxFont::SvxFont( const SvxFont &rFont )
82cdf0e10cSrcweir 	: Font( rFont )
83cdf0e10cSrcweir {
84cdf0e10cSrcweir 	nKern = rFont.GetFixKerning();
85cdf0e10cSrcweir 	nEsc  = rFont.GetEscapement();
86cdf0e10cSrcweir 	nPropr = rFont.GetPropr();
87cdf0e10cSrcweir 	eCaseMap = rFont.GetCaseMap();
88cdf0e10cSrcweir 	eLang = rFont.GetLanguage();
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir /*************************************************************************
92cdf0e10cSrcweir  *				 static	SvxFont::DrawArrow
93cdf0e10cSrcweir  *************************************************************************/
94cdf0e10cSrcweir 
95cdf0e10cSrcweir void SvxFont::DrawArrow( OutputDevice &rOut, const Rectangle& rRect,
96cdf0e10cSrcweir 	const Size& rSize, const Color& rCol, sal_Bool bLeft )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
99cdf0e10cSrcweir 	long nRight = nLeft + rSize.Width();
100cdf0e10cSrcweir 	long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
101cdf0e10cSrcweir 	long nTop = nMid - rSize.Height() / 2;
102cdf0e10cSrcweir 	long nBottom = nTop + rSize.Height();
103cdf0e10cSrcweir 	if( nLeft < rRect.Left() )
104cdf0e10cSrcweir 	{
105cdf0e10cSrcweir 		nLeft = rRect.Left();
106cdf0e10cSrcweir 		nRight = rRect.Right();
107cdf0e10cSrcweir 	}
108cdf0e10cSrcweir 	if( nTop < rRect.Top() )
109cdf0e10cSrcweir 	{
110cdf0e10cSrcweir 		nTop = rRect.Top();
111cdf0e10cSrcweir 		nBottom = rRect.Bottom();
112cdf0e10cSrcweir 	}
113cdf0e10cSrcweir 	Polygon aPoly;
114cdf0e10cSrcweir 	Point aTmp( bLeft ? nLeft : nRight, nMid );
115cdf0e10cSrcweir 	Point aNxt( bLeft ? nRight : nLeft, nTop );
116cdf0e10cSrcweir 	aPoly.Insert( 0, aTmp );
117cdf0e10cSrcweir 	aPoly.Insert( 0, aNxt );
118cdf0e10cSrcweir 	aNxt.Y() = nBottom;
119cdf0e10cSrcweir 	aPoly.Insert( 0, aNxt );
120cdf0e10cSrcweir 	aPoly.Insert( 0, aTmp );
121cdf0e10cSrcweir 	Color aOldLineColor = rOut.GetLineColor();
122cdf0e10cSrcweir 	Color aOldFillColor = rOut.GetFillColor();
123cdf0e10cSrcweir 	rOut.SetFillColor( rCol );
124cdf0e10cSrcweir 	rOut.SetLineColor( Color( COL_BLACK ) );
125cdf0e10cSrcweir 	rOut.DrawPolygon( aPoly );
126cdf0e10cSrcweir 	rOut.DrawLine( aTmp, aNxt );
127cdf0e10cSrcweir 	rOut.SetLineColor( aOldLineColor );
128cdf0e10cSrcweir 	rOut.SetFillColor( aOldFillColor );
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
131cdf0e10cSrcweir /*************************************************************************
132cdf0e10cSrcweir  *                      SvxFont::CalcCaseMap
133cdf0e10cSrcweir  *************************************************************************/
134cdf0e10cSrcweir 
135cdf0e10cSrcweir XubString SvxFont::CalcCaseMap( const XubString &rTxt ) const
136cdf0e10cSrcweir {
137cdf0e10cSrcweir 	if( !IsCaseMap() || !rTxt.Len() ) return rTxt;
138cdf0e10cSrcweir 	XubString aTxt( rTxt );
139cdf0e10cSrcweir 	// Ich muss mir noch die Sprache besorgen
140cdf0e10cSrcweir 	const LanguageType eLng = LANGUAGE_DONTKNOW == eLang
141cdf0e10cSrcweir 							? LANGUAGE_SYSTEM : eLang;
142cdf0e10cSrcweir 
143cdf0e10cSrcweir 	CharClass aCharClass( SvxCreateLocale( eLng ) );
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 	switch( eCaseMap )
146cdf0e10cSrcweir 	{
147cdf0e10cSrcweir 		case SVX_CASEMAP_KAPITAELCHEN:
148cdf0e10cSrcweir 		case SVX_CASEMAP_VERSALIEN:
149cdf0e10cSrcweir 		{
150cdf0e10cSrcweir 			aCharClass.toUpper( aTxt );
151cdf0e10cSrcweir 			break;
152cdf0e10cSrcweir 		}
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 		case SVX_CASEMAP_GEMEINE:
155cdf0e10cSrcweir 		{
156cdf0e10cSrcweir 			aCharClass.toLower( aTxt );
157cdf0e10cSrcweir 			break;
158cdf0e10cSrcweir 		}
159cdf0e10cSrcweir 		case SVX_CASEMAP_TITEL:
160cdf0e10cSrcweir 		{
161cdf0e10cSrcweir 			// Jeder Wortbeginn wird gross geschrieben,
162cdf0e10cSrcweir 			// der Rest des Wortes wird unbesehen uebernommen.
163cdf0e10cSrcweir 			// Bug: wenn das Attribut mitten im Wort beginnt.
164cdf0e10cSrcweir 			sal_Bool bBlank = sal_True;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 			for( sal_uInt16 i = 0; i < aTxt.Len(); ++i )
167cdf0e10cSrcweir 			{
168cdf0e10cSrcweir 				if( sal_Unicode(' ') == aTxt.GetChar(i) || sal_Unicode('\t') == aTxt.GetChar(i) )
169cdf0e10cSrcweir 					bBlank = sal_True;
170cdf0e10cSrcweir 				else
171cdf0e10cSrcweir 				{
172cdf0e10cSrcweir 					if( bBlank )
173cdf0e10cSrcweir 					{
174cdf0e10cSrcweir 						String aTemp( aTxt.GetChar( i ) );
175cdf0e10cSrcweir 						aCharClass.toUpper( aTemp );
176cdf0e10cSrcweir 						aTxt.Replace( i, 1, aTemp );
177cdf0e10cSrcweir 					}
178cdf0e10cSrcweir 					bBlank = sal_False;
179cdf0e10cSrcweir 				}
180cdf0e10cSrcweir 			}
181cdf0e10cSrcweir 			break;
182cdf0e10cSrcweir 		}
183cdf0e10cSrcweir 		default:
184cdf0e10cSrcweir 		{
185cdf0e10cSrcweir 			DBG_ASSERT(!this, "SvxFont::CaseMapTxt: unknown casemap");
186cdf0e10cSrcweir 			break;
187cdf0e10cSrcweir 		}
188cdf0e10cSrcweir 	}
189cdf0e10cSrcweir 	return aTxt;
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
192cdf0e10cSrcweir /*************************************************************************
193cdf0e10cSrcweir  * Hier beginnen die Methoden, die im Writer nicht benutzt werden koennen,
194cdf0e10cSrcweir  * deshalb kann man diesen Bereich durch setzen von REDUCEDSVXFONT ausklammern.
195cdf0e10cSrcweir  *************************************************************************/
196cdf0e10cSrcweir #ifndef REDUCEDSVXFONT
197cdf0e10cSrcweir 
198cdf0e10cSrcweir /*************************************************************************
199cdf0e10cSrcweir  *						class SvxDoCapitals
200cdf0e10cSrcweir  * die virtuelle Methode Do wird von SvxFont::DoOnCapitals abwechselnd mit
201cdf0e10cSrcweir  * den "Gross-" und "Kleinbuchstaben"-Teilen aufgerufen.
202cdf0e10cSrcweir  * Die Ableitungen von SvxDoCapitals erfuellen diese Methode mit Leben.
203cdf0e10cSrcweir  *************************************************************************/
204cdf0e10cSrcweir 
205cdf0e10cSrcweir class SvxDoCapitals
206cdf0e10cSrcweir {
207cdf0e10cSrcweir protected:
208cdf0e10cSrcweir 	OutputDevice *pOut;
209cdf0e10cSrcweir 	const XubString &rTxt;
210cdf0e10cSrcweir 	const xub_StrLen nIdx;
211cdf0e10cSrcweir 	const xub_StrLen nLen;
212cdf0e10cSrcweir 
213cdf0e10cSrcweir public:
214cdf0e10cSrcweir     SvxDoCapitals( OutputDevice *_pOut, const XubString &_rTxt,
215cdf0e10cSrcweir                    const xub_StrLen _nIdx, const xub_StrLen _nLen )
216cdf0e10cSrcweir         : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen)
217cdf0e10cSrcweir 		{ }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir 	virtual void DoSpace( const sal_Bool bDraw );
220cdf0e10cSrcweir 	virtual void SetSpace();
221cdf0e10cSrcweir 	virtual void Do( const XubString &rTxt,
222cdf0e10cSrcweir 					 const xub_StrLen nIdx, const xub_StrLen nLen,
223cdf0e10cSrcweir 					 const sal_Bool bUpper ) = 0;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir 	inline OutputDevice *GetOut() { return pOut; }
226cdf0e10cSrcweir 	inline const XubString &GetTxt() const { return rTxt; }
227cdf0e10cSrcweir 	xub_StrLen GetIdx() const { return nIdx; }
228cdf0e10cSrcweir 	xub_StrLen GetLen() const { return nLen; }
229cdf0e10cSrcweir };
230cdf0e10cSrcweir 
231cdf0e10cSrcweir void SvxDoCapitals::DoSpace( const sal_Bool /*bDraw*/ ) { }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir void SvxDoCapitals::SetSpace() { }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir void SvxDoCapitals::Do( const XubString &/*_rTxt*/, const xub_StrLen /*_nIdx*/,
236cdf0e10cSrcweir     const xub_StrLen /*_nLen*/, const sal_Bool /*bUpper*/ ) { }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir /*************************************************************************
239cdf0e10cSrcweir  *					SvxFont::DoOnCapitals() const
240cdf0e10cSrcweir  * zerlegt den String in Gross- und Kleinbuchstaben und ruft jeweils die
241cdf0e10cSrcweir  * Methode SvxDoCapitals::Do( ) auf.
242cdf0e10cSrcweir  *************************************************************************/
243cdf0e10cSrcweir 
244cdf0e10cSrcweir void SvxFont::DoOnCapitals(SvxDoCapitals &rDo, const xub_StrLen nPartLen) const
245cdf0e10cSrcweir {
246cdf0e10cSrcweir 	const XubString &rTxt = rDo.GetTxt();
247cdf0e10cSrcweir 	const xub_StrLen nIdx = rDo.GetIdx();
248cdf0e10cSrcweir 	const xub_StrLen nLen = STRING_LEN == nPartLen ? rDo.GetLen() : nPartLen;
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	const XubString aTxt( CalcCaseMap( rTxt ) );
251cdf0e10cSrcweir 	const sal_uInt16 nTxtLen = Min( rTxt.Len(), nLen );
252cdf0e10cSrcweir 	sal_uInt16 nPos = 0;
253cdf0e10cSrcweir 	sal_uInt16 nOldPos = nPos;
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	// #108210#
256cdf0e10cSrcweir 	// Test if string length differ between original and CaseMapped
257cdf0e10cSrcweir 	sal_Bool bCaseMapLengthDiffers(aTxt.Len() != rTxt.Len());
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 	const LanguageType eLng = LANGUAGE_DONTKNOW == eLang
260cdf0e10cSrcweir 							? LANGUAGE_SYSTEM : eLang;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir 	CharClass	aCharClass( SvxCreateLocale( eLng ) );
263cdf0e10cSrcweir 	String		aCharString;
264cdf0e10cSrcweir 
265cdf0e10cSrcweir 	while( nPos < nTxtLen )
266cdf0e10cSrcweir 	{
267cdf0e10cSrcweir 		// Erst kommen die Upper-Chars dran
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 		// 4251: Es gibt Zeichen, die Upper _und_ Lower sind (z.B. das Blank).
270cdf0e10cSrcweir 		// Solche Zweideutigkeiten fuehren ins Chaos, deswegen werden diese
271cdf0e10cSrcweir 		// Zeichen der Menge Lower zugeordnet !
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 		while( nPos < nTxtLen )
274cdf0e10cSrcweir 		{
275cdf0e10cSrcweir 			aCharString = rTxt.GetChar( nPos + nIdx );
276cdf0e10cSrcweir 			sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
277cdf0e10cSrcweir 			if ( nCharacterType & ::com::sun::star::i18n::KCharacterType::LOWER )
278cdf0e10cSrcweir 				break;
279cdf0e10cSrcweir 			if ( ! ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
280cdf0e10cSrcweir 				break;
281cdf0e10cSrcweir 			++nPos;
282cdf0e10cSrcweir 		}
283cdf0e10cSrcweir 		if( nOldPos != nPos )
284cdf0e10cSrcweir 		{
285cdf0e10cSrcweir 			if(bCaseMapLengthDiffers)
286cdf0e10cSrcweir 			{
287cdf0e10cSrcweir 				// #108210#
288cdf0e10cSrcweir 				// If strings differ work preparing the necessary snippet to address that
289cdf0e10cSrcweir 				// potential difference
290cdf0e10cSrcweir 				const XubString aSnippet(rTxt, nIdx + nOldPos, nPos-nOldPos);
291cdf0e10cSrcweir 				XubString aNewText = CalcCaseMap(aSnippet);
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 				rDo.Do( aNewText, 0, aNewText.Len(), sal_True );
294cdf0e10cSrcweir 			}
295cdf0e10cSrcweir 			else
296cdf0e10cSrcweir 			{
297cdf0e10cSrcweir 				rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_True );
298cdf0e10cSrcweir 			}
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 			nOldPos = nPos;
301cdf0e10cSrcweir 		}
302cdf0e10cSrcweir 		// Nun werden die Lower-Chars verarbeitet (ohne Blanks)
303cdf0e10cSrcweir 		while( nPos < nTxtLen )
304cdf0e10cSrcweir 		{
305cdf0e10cSrcweir 			sal_uInt32	nCharacterType = aCharClass.getCharacterType( aCharString, 0 );
306cdf0e10cSrcweir 			if ( ( nCharacterType & ::com::sun::star::i18n::KCharacterType::UPPER ) )
307cdf0e10cSrcweir 				break;
308cdf0e10cSrcweir 			if ( CH_BLANK == aCharString )
309cdf0e10cSrcweir 				break;
310cdf0e10cSrcweir 			if( ++nPos < nTxtLen )
311cdf0e10cSrcweir 				aCharString = rTxt.GetChar( nPos + nIdx );
312cdf0e10cSrcweir 		}
313cdf0e10cSrcweir 		if( nOldPos != nPos )
314cdf0e10cSrcweir 		{
315cdf0e10cSrcweir 			if(bCaseMapLengthDiffers)
316cdf0e10cSrcweir 			{
317cdf0e10cSrcweir 				// #108210#
318cdf0e10cSrcweir 				// If strings differ work preparing the necessary snippet to address that
319cdf0e10cSrcweir 				// potential difference
320cdf0e10cSrcweir 				const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos);
321cdf0e10cSrcweir 				XubString aNewText = CalcCaseMap(aSnippet);
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 				rDo.Do( aNewText, 0, aNewText.Len(), sal_False );
324cdf0e10cSrcweir 			}
325cdf0e10cSrcweir 			else
326cdf0e10cSrcweir 			{
327cdf0e10cSrcweir 				rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, sal_False );
328cdf0e10cSrcweir 			}
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 			nOldPos = nPos;
331cdf0e10cSrcweir 		}
332cdf0e10cSrcweir 		// Nun werden die Blanks verarbeitet
333cdf0e10cSrcweir 		while( nPos < nTxtLen && CH_BLANK == aCharString && ++nPos < nTxtLen )
334cdf0e10cSrcweir 			aCharString = rTxt.GetChar( nPos + nIdx );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 		if( nOldPos != nPos )
337cdf0e10cSrcweir 		{
338cdf0e10cSrcweir 			rDo.DoSpace( sal_False );
339cdf0e10cSrcweir 
340cdf0e10cSrcweir 			if(bCaseMapLengthDiffers)
341cdf0e10cSrcweir 			{
342cdf0e10cSrcweir 				// #108210#
343cdf0e10cSrcweir 				// If strings differ work preparing the necessary snippet to address that
344cdf0e10cSrcweir 				// potential difference
345cdf0e10cSrcweir 				const XubString aSnippet(rTxt, nIdx + nOldPos, nPos - nOldPos);
346cdf0e10cSrcweir 				XubString aNewText = CalcCaseMap(aSnippet);
347cdf0e10cSrcweir 
348cdf0e10cSrcweir 				rDo.Do( aNewText, 0, aNewText.Len(), sal_False );
349cdf0e10cSrcweir 			}
350cdf0e10cSrcweir 			else
351cdf0e10cSrcweir 			{
352cdf0e10cSrcweir 				rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, sal_False );
353cdf0e10cSrcweir 			}
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 			nOldPos = nPos;
356cdf0e10cSrcweir 			rDo.SetSpace();
357cdf0e10cSrcweir 		}
358cdf0e10cSrcweir 	}
359cdf0e10cSrcweir 	rDo.DoSpace( sal_True );
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir /**************************************************************************
363cdf0e10cSrcweir  *					  SvxFont::SetPhysFont()
364cdf0e10cSrcweir  *************************************************************************/
365cdf0e10cSrcweir 
366cdf0e10cSrcweir void SvxFont::SetPhysFont( OutputDevice *pOut ) const
367cdf0e10cSrcweir {
368cdf0e10cSrcweir 	const Font& rCurrentFont = pOut->GetFont();
369cdf0e10cSrcweir 	if ( nPropr == 100 )
370cdf0e10cSrcweir 	{
371cdf0e10cSrcweir 		if ( !rCurrentFont.IsSameInstance( *this ) )
372cdf0e10cSrcweir 			pOut->SetFont( *this );
373cdf0e10cSrcweir 	}
374cdf0e10cSrcweir 	else
375cdf0e10cSrcweir 	{
376cdf0e10cSrcweir 		Font aNewFont( *this );
377cdf0e10cSrcweir 		Size aSize( aNewFont.GetSize() );
378cdf0e10cSrcweir 		aNewFont.SetSize( Size(	aSize.Width() * nPropr / 100L,
379cdf0e10cSrcweir 									aSize.Height() * nPropr / 100L ) );
380cdf0e10cSrcweir 		if ( !rCurrentFont.IsSameInstance( aNewFont ) )
381cdf0e10cSrcweir 			pOut->SetFont( aNewFont );
382cdf0e10cSrcweir 	}
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
385cdf0e10cSrcweir /*************************************************************************
386cdf0e10cSrcweir  *					  SvxFont::ChgPhysFont()
387cdf0e10cSrcweir  *************************************************************************/
388cdf0e10cSrcweir 
389cdf0e10cSrcweir Font SvxFont::ChgPhysFont( OutputDevice *pOut ) const
390cdf0e10cSrcweir {
391cdf0e10cSrcweir 	Font aOldFont( pOut->GetFont() );
392cdf0e10cSrcweir 	SetPhysFont( pOut );
393cdf0e10cSrcweir 	return aOldFont;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir /*************************************************************************
397cdf0e10cSrcweir  *					  SvxFont::GetPhysTxtSize()
398cdf0e10cSrcweir  *************************************************************************/
399cdf0e10cSrcweir 
400cdf0e10cSrcweir Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt,
401cdf0e10cSrcweir 						 const xub_StrLen nIdx, const xub_StrLen nLen ) const
402cdf0e10cSrcweir {
403cdf0e10cSrcweir 	if ( !IsCaseMap() && !IsKern() )
404cdf0e10cSrcweir 		return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ),
405cdf0e10cSrcweir 					 pOut->GetTextHeight() );
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 	Size aTxtSize;
408cdf0e10cSrcweir 	aTxtSize.setHeight( pOut->GetTextHeight() );
409cdf0e10cSrcweir 	if ( !IsCaseMap() )
410cdf0e10cSrcweir 		aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) );
411cdf0e10cSrcweir 	else
412cdf0e10cSrcweir 	{
413cdf0e10cSrcweir 		// #108210#
414cdf0e10cSrcweir 		const XubString aNewText = CalcCaseMap(rTxt);
415cdf0e10cSrcweir 		sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len());
416cdf0e10cSrcweir 		sal_Int32 nWidth(0L);
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 		if(bCaseMapLengthDiffers)
419cdf0e10cSrcweir 		{
420cdf0e10cSrcweir 			// If strings differ work preparing the necessary snippet to address that
421cdf0e10cSrcweir 			// potential difference
422cdf0e10cSrcweir 			const XubString aSnippet(rTxt, nIdx, nLen);
423cdf0e10cSrcweir             XubString _aNewText = CalcCaseMap(aSnippet);
424cdf0e10cSrcweir             nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.Len() );
425cdf0e10cSrcweir 		}
426cdf0e10cSrcweir 		else
427cdf0e10cSrcweir 		{
428cdf0e10cSrcweir 			nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen );
429cdf0e10cSrcweir 		}
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 		aTxtSize.setWidth(nWidth);
432cdf0e10cSrcweir 	}
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 	if( IsKern() && ( nLen > 1 ) )
435cdf0e10cSrcweir 		aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 	return aTxtSize;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const XubString &rTxt )
441cdf0e10cSrcweir {
442cdf0e10cSrcweir 	if ( !IsCaseMap() && !IsKern() )
443cdf0e10cSrcweir 		return Size( pOut->GetTextWidth( rTxt ), pOut->GetTextHeight() );
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 	Size aTxtSize;
446cdf0e10cSrcweir 	aTxtSize.setHeight( pOut->GetTextHeight() );
447cdf0e10cSrcweir 	if ( !IsCaseMap() )
448cdf0e10cSrcweir 		aTxtSize.setWidth( pOut->GetTextWidth( rTxt ) );
449cdf0e10cSrcweir 	else
450cdf0e10cSrcweir 		aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( rTxt ) ) );
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 	if( IsKern() && ( rTxt.Len() > 1 ) )
453cdf0e10cSrcweir 		aTxtSize.Width() += ( ( rTxt.Len()-1 ) * long( nKern ) );
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	return aTxtSize;
456cdf0e10cSrcweir }
457cdf0e10cSrcweir 
458cdf0e10cSrcweir Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const XubString &rTxt,
459cdf0e10cSrcweir 						 const sal_uInt16 nIdx, const sal_uInt16 nLen, sal_Int32* pDXArray ) const
460cdf0e10cSrcweir {
461cdf0e10cSrcweir 	if ( !IsCaseMap() && !IsKern() )
462cdf0e10cSrcweir 		return Size( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ),
463cdf0e10cSrcweir 					 pOut->GetTextHeight() );
464cdf0e10cSrcweir 
465cdf0e10cSrcweir 	Size aTxtSize;
466cdf0e10cSrcweir 	aTxtSize.setHeight( pOut->GetTextHeight() );
467cdf0e10cSrcweir 	if ( !IsCaseMap() )
468cdf0e10cSrcweir 		aTxtSize.setWidth( pOut->GetTextArray( rTxt, pDXArray, nIdx, nLen ) );
469cdf0e10cSrcweir 	else
470cdf0e10cSrcweir 		aTxtSize.setWidth( pOut->GetTextArray( CalcCaseMap( rTxt ),
471cdf0e10cSrcweir 						   pDXArray, nIdx, nLen ) );
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 	if( IsKern() && ( nLen > 1 ) )
474cdf0e10cSrcweir 	{
475cdf0e10cSrcweir 		aTxtSize.Width() += ( ( nLen-1 ) * long( nKern ) );
476cdf0e10cSrcweir 
477cdf0e10cSrcweir 		if ( pDXArray )
478cdf0e10cSrcweir 		{
479cdf0e10cSrcweir 			for ( xub_StrLen i = 0; i < nLen; i++ )
480cdf0e10cSrcweir 				pDXArray[i] += ( (i+1) * long( nKern ) );
481cdf0e10cSrcweir 			// Der letzte ist um ein nKern zu gross:
482cdf0e10cSrcweir 			pDXArray[nLen-1] -= nKern;
483cdf0e10cSrcweir 		}
484cdf0e10cSrcweir 	}
485cdf0e10cSrcweir 	return aTxtSize;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir /*************************************************************************
489cdf0e10cSrcweir  *					  SvxFont::GetTxtSize()
490cdf0e10cSrcweir  *************************************************************************/
491cdf0e10cSrcweir 
492cdf0e10cSrcweir Size SvxFont::GetTxtSize( const OutputDevice *pOut, const XubString &rTxt,
493cdf0e10cSrcweir 						 const xub_StrLen nIdx, const xub_StrLen nLen )
494cdf0e10cSrcweir {
495cdf0e10cSrcweir 	xub_StrLen nTmp = nLen;
496cdf0e10cSrcweir 	if ( nTmp == STRING_LEN )	// schon initialisiert?
497cdf0e10cSrcweir 		nTmp = rTxt.Len();
498cdf0e10cSrcweir 	Font aOldFont( ChgPhysFont((OutputDevice *)pOut) );
499cdf0e10cSrcweir 	Size aTxtSize;
500cdf0e10cSrcweir 	if( IsCapital() && rTxt.Len() )
501cdf0e10cSrcweir 	{
502cdf0e10cSrcweir 		aTxtSize = GetCapitalSize( pOut, rTxt, nIdx, nTmp );
503cdf0e10cSrcweir 	}
504cdf0e10cSrcweir 	else aTxtSize = GetPhysTxtSize(pOut,rTxt,nIdx,nTmp);
505cdf0e10cSrcweir 	((OutputDevice *)pOut)->SetFont( aOldFont );
506cdf0e10cSrcweir 	return aTxtSize;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
509cdf0e10cSrcweir /*************************************************************************
510cdf0e10cSrcweir  *					  SvxFont::DrawText()
511cdf0e10cSrcweir  *************************************************************************/
512cdf0e10cSrcweir 
513cdf0e10cSrcweir void SvxFont::DrawText( OutputDevice *pOut,
514cdf0e10cSrcweir 			   const Point &rPos, const XubString &rTxt,
515cdf0e10cSrcweir 			   const xub_StrLen nIdx, const xub_StrLen nLen ) const
516cdf0e10cSrcweir {
517cdf0e10cSrcweir 	if( !nLen || !rTxt.Len() )	return;
518cdf0e10cSrcweir 	xub_StrLen nTmp = nLen;
519cdf0e10cSrcweir 	if ( nTmp == STRING_LEN )	// schon initialisiert?
520cdf0e10cSrcweir 		nTmp = rTxt.Len();
521cdf0e10cSrcweir 	Point aPos( rPos );
522cdf0e10cSrcweir 	if ( nEsc )
523cdf0e10cSrcweir 	{
524cdf0e10cSrcweir 		Size aSize = (this->GetSize());
525cdf0e10cSrcweir 		aPos.Y() -= ((nEsc*long(aSize.Height()))/ 100L);
526cdf0e10cSrcweir 	}
527cdf0e10cSrcweir 	Font aOldFont( ChgPhysFont( pOut ) );
528cdf0e10cSrcweir 
529cdf0e10cSrcweir 	if ( IsCapital() )
530cdf0e10cSrcweir 		DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
531cdf0e10cSrcweir 	else
532cdf0e10cSrcweir 	{
533cdf0e10cSrcweir 		Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nTmp );
534cdf0e10cSrcweir 
535cdf0e10cSrcweir 		if ( !IsCaseMap() )
536cdf0e10cSrcweir 			pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
537cdf0e10cSrcweir 		else
538cdf0e10cSrcweir 			pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ),
539cdf0e10cSrcweir 								   nIdx, nTmp );
540cdf0e10cSrcweir 	}
541cdf0e10cSrcweir 	pOut->SetFont(aOldFont);
542cdf0e10cSrcweir }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir void SvxFont::QuickDrawText( OutputDevice *pOut,
545cdf0e10cSrcweir 	const Point &rPos, const XubString &rTxt,
546cdf0e10cSrcweir 	const xub_StrLen nIdx, const xub_StrLen nLen, const sal_Int32* pDXArray ) const
547cdf0e10cSrcweir {
548cdf0e10cSrcweir 	// Font muss ins OutputDevice selektiert sein...
549cdf0e10cSrcweir 	if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() )
550cdf0e10cSrcweir 	{
551cdf0e10cSrcweir 		pOut->DrawTextArray( rPos, rTxt, pDXArray, nIdx, nLen );
552cdf0e10cSrcweir 		return;
553cdf0e10cSrcweir 	}
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 	Point aPos( rPos );
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     if ( nEsc )
558cdf0e10cSrcweir     {
559cdf0e10cSrcweir         long nDiff = GetSize().Height();
560cdf0e10cSrcweir         nDiff *= nEsc;
561cdf0e10cSrcweir         nDiff /= 100;
562cdf0e10cSrcweir 
563cdf0e10cSrcweir         if ( !IsVertical() )
564cdf0e10cSrcweir 		    aPos.Y() -= nDiff;
565cdf0e10cSrcweir         else
566cdf0e10cSrcweir             aPos.X() += nDiff;
567cdf0e10cSrcweir     }
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 	if( IsCapital() )
570cdf0e10cSrcweir 	{
571cdf0e10cSrcweir 		DBG_ASSERT( !pDXArray, "DrawCapital nicht fuer TextArray!" );
572cdf0e10cSrcweir 		DrawCapital( pOut, aPos, rTxt, nIdx, nLen );
573cdf0e10cSrcweir 	}
574cdf0e10cSrcweir 	else
575cdf0e10cSrcweir 	{
576cdf0e10cSrcweir 		if ( IsKern() && !pDXArray )
577cdf0e10cSrcweir 		{
578cdf0e10cSrcweir 			Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen );
579cdf0e10cSrcweir 
580cdf0e10cSrcweir 			if ( !IsCaseMap() )
581cdf0e10cSrcweir 				pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen );
582cdf0e10cSrcweir 			else
583cdf0e10cSrcweir 				pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen );
584cdf0e10cSrcweir 		}
585cdf0e10cSrcweir 		else
586cdf0e10cSrcweir 		{
587cdf0e10cSrcweir 			if ( !IsCaseMap() )
588cdf0e10cSrcweir 				pOut->DrawTextArray( aPos, rTxt, pDXArray, nIdx, nLen );
589cdf0e10cSrcweir 			else
590cdf0e10cSrcweir 				pOut->DrawTextArray( aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen );
591cdf0e10cSrcweir 		}
592cdf0e10cSrcweir 	}
593cdf0e10cSrcweir }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir // -----------------------------------------------------------------------
596cdf0e10cSrcweir 
597cdf0e10cSrcweir void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter,
598cdf0e10cSrcweir 						const Point &rPos, const XubString &rTxt,
599cdf0e10cSrcweir 						const xub_StrLen nIdx, const xub_StrLen nLen ) const
600cdf0e10cSrcweir {
601cdf0e10cSrcweir 	if ( !nLen || !rTxt.Len() )
602cdf0e10cSrcweir 		return;
603cdf0e10cSrcweir 	xub_StrLen nTmp = nLen;
604cdf0e10cSrcweir 
605cdf0e10cSrcweir 	if ( nTmp == STRING_LEN )	// schon initialisiert?
606cdf0e10cSrcweir 		nTmp = rTxt.Len();
607cdf0e10cSrcweir 	Point aPos( rPos );
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 	if ( nEsc )
610cdf0e10cSrcweir 	{
611cdf0e10cSrcweir 		short nTmpEsc;
612cdf0e10cSrcweir 		if( DFLT_ESC_AUTO_SUPER == nEsc )
613cdf0e10cSrcweir 			nTmpEsc = 33;
614cdf0e10cSrcweir 		else if( DFLT_ESC_AUTO_SUB == nEsc )
615cdf0e10cSrcweir 			nTmpEsc = -20;
616cdf0e10cSrcweir 		else
617cdf0e10cSrcweir 			nTmpEsc = nEsc;
618cdf0e10cSrcweir 		Size aSize = ( this->GetSize() );
619cdf0e10cSrcweir 		aPos.Y() -= ( ( nTmpEsc * long( aSize.Height() ) ) / 100L );
620cdf0e10cSrcweir 	}
621cdf0e10cSrcweir 	Font aOldFont( ChgPhysFont( pOut ) );
622cdf0e10cSrcweir 	Font aOldPrnFont( ChgPhysFont( pPrinter ) );
623cdf0e10cSrcweir 
624cdf0e10cSrcweir 	if ( IsCapital() )
625cdf0e10cSrcweir 		DrawCapital( pOut, aPos, rTxt, nIdx, nTmp );
626cdf0e10cSrcweir 	else
627cdf0e10cSrcweir 	{
628cdf0e10cSrcweir 		Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp );
629cdf0e10cSrcweir 
630cdf0e10cSrcweir 		if ( !IsCaseMap() )
631cdf0e10cSrcweir 			pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp );
632cdf0e10cSrcweir 		else
633cdf0e10cSrcweir 		{
634cdf0e10cSrcweir 			// #108210#
635cdf0e10cSrcweir 			const XubString aNewText = CalcCaseMap(rTxt);
636cdf0e10cSrcweir 			sal_Bool bCaseMapLengthDiffers(aNewText.Len() != rTxt.Len());
637cdf0e10cSrcweir 
638cdf0e10cSrcweir 			if(bCaseMapLengthDiffers)
639cdf0e10cSrcweir 			{
640cdf0e10cSrcweir 				// If strings differ work preparing the necessary snippet to address that
641cdf0e10cSrcweir 				// potential difference
642cdf0e10cSrcweir 				const XubString aSnippet(rTxt, nIdx, nTmp);
643cdf0e10cSrcweir                 XubString _aNewText = CalcCaseMap(aSnippet);
644cdf0e10cSrcweir 
645cdf0e10cSrcweir                 pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.Len() );
646cdf0e10cSrcweir 			}
647cdf0e10cSrcweir 			else
648cdf0e10cSrcweir 			{
649cdf0e10cSrcweir 				pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp );
650cdf0e10cSrcweir 			}
651cdf0e10cSrcweir 		}
652cdf0e10cSrcweir 	}
653cdf0e10cSrcweir 	pOut->SetFont(aOldFont);
654cdf0e10cSrcweir 	pPrinter->SetFont( aOldPrnFont );
655cdf0e10cSrcweir }
656cdf0e10cSrcweir 
657cdf0e10cSrcweir // -----------------------------------------------------------------------
658cdf0e10cSrcweir 
659cdf0e10cSrcweir SvxFont& SvxFont::operator=( const Font& rFont )
660cdf0e10cSrcweir {
661cdf0e10cSrcweir 	Font::operator=( rFont );
662cdf0e10cSrcweir 	return *this;
663cdf0e10cSrcweir }
664cdf0e10cSrcweir 
665cdf0e10cSrcweir SvxFont& SvxFont::operator=( const SvxFont& rFont )
666cdf0e10cSrcweir {
667cdf0e10cSrcweir 	Font::operator=( rFont );
668cdf0e10cSrcweir 	eLang = rFont.eLang;
669cdf0e10cSrcweir 	eCaseMap = rFont.eCaseMap;
670cdf0e10cSrcweir 	nEsc = rFont.nEsc;
671cdf0e10cSrcweir 	nPropr = rFont.nPropr;
672cdf0e10cSrcweir 	nKern = rFont.nKern;
673cdf0e10cSrcweir 	return *this;
674cdf0e10cSrcweir }
675cdf0e10cSrcweir 
676cdf0e10cSrcweir 
677cdf0e10cSrcweir /*************************************************************************
678cdf0e10cSrcweir  *					  class SvxDoGetCapitalSize
679cdf0e10cSrcweir  * wird von SvxFont::GetCapitalSize() zur Berechnung der TxtSize bei
680cdf0e10cSrcweir  * eingestellten Kapitaelchen benutzt.
681cdf0e10cSrcweir  *************************************************************************/
682cdf0e10cSrcweir 
683cdf0e10cSrcweir class SvxDoGetCapitalSize : public SvxDoCapitals
684cdf0e10cSrcweir {
685cdf0e10cSrcweir protected:
686cdf0e10cSrcweir 	SvxFont*	pFont;
687cdf0e10cSrcweir 	Size 		aTxtSize;
688cdf0e10cSrcweir 	short    	nKern;
689cdf0e10cSrcweir public:
690cdf0e10cSrcweir       SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut,
691cdf0e10cSrcweir                            const XubString &_rTxt, const xub_StrLen _nIdx,
692cdf0e10cSrcweir                            const xub_StrLen _nLen, const short _nKrn )
693cdf0e10cSrcweir             : SvxDoCapitals( (OutputDevice*)_pOut, _rTxt, _nIdx, _nLen ),
694cdf0e10cSrcweir               pFont( _pFnt ),
695cdf0e10cSrcweir               nKern( _nKrn )
696cdf0e10cSrcweir 			{ }
697cdf0e10cSrcweir 
698cdf0e10cSrcweir 	virtual void Do( const XubString &rTxt, const xub_StrLen nIdx,
699cdf0e10cSrcweir 					 const xub_StrLen nLen, const sal_Bool bUpper );
700cdf0e10cSrcweir 
701cdf0e10cSrcweir 	inline const Size &GetSize() const { return aTxtSize; };
702cdf0e10cSrcweir };
703cdf0e10cSrcweir 
704cdf0e10cSrcweir void SvxDoGetCapitalSize::Do( const XubString &_rTxt, const xub_StrLen _nIdx,
705cdf0e10cSrcweir                               const xub_StrLen _nLen, const sal_Bool bUpper )
706cdf0e10cSrcweir {
707cdf0e10cSrcweir 	Size aPartSize;
708cdf0e10cSrcweir 	if ( !bUpper )
709cdf0e10cSrcweir 	{
710cdf0e10cSrcweir 		sal_uInt8 nProp = pFont->GetPropr();
711cdf0e10cSrcweir 		pFont->SetProprRel( KAPITAELCHENPROP );
712cdf0e10cSrcweir 		pFont->SetPhysFont( pOut );
713cdf0e10cSrcweir         aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
714cdf0e10cSrcweir 		aPartSize.setHeight( pOut->GetTextHeight() );
715cdf0e10cSrcweir 		aTxtSize.Height() = aPartSize.Height();
716cdf0e10cSrcweir 		pFont->SetPropr( nProp );
717cdf0e10cSrcweir 		pFont->SetPhysFont( pOut );
718cdf0e10cSrcweir 	}
719cdf0e10cSrcweir 	else
720cdf0e10cSrcweir 	{
721cdf0e10cSrcweir         aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
722cdf0e10cSrcweir 		aPartSize.setHeight( pOut->GetTextHeight() );
723cdf0e10cSrcweir 	}
724cdf0e10cSrcweir 	aTxtSize.Width() += aPartSize.Width();
725cdf0e10cSrcweir     aTxtSize.Width() += ( _nLen * long( nKern ) );
726cdf0e10cSrcweir }
727cdf0e10cSrcweir 
728cdf0e10cSrcweir /*************************************************************************
729cdf0e10cSrcweir  *					  SvxFont::GetCapitalSize()
730cdf0e10cSrcweir  * berechnet TxtSize, wenn Kapitaelchen eingestellt sind.
731cdf0e10cSrcweir  *************************************************************************/
732cdf0e10cSrcweir 
733cdf0e10cSrcweir Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const XubString &rTxt,
734cdf0e10cSrcweir 							 const xub_StrLen nIdx, const xub_StrLen nLen) const
735cdf0e10cSrcweir {
736cdf0e10cSrcweir 	// Start:
737cdf0e10cSrcweir 	SvxDoGetCapitalSize aDo( (SvxFont *)this, pOut, rTxt, nIdx, nLen, nKern );
738cdf0e10cSrcweir 	DoOnCapitals( aDo );
739cdf0e10cSrcweir 	Size aTxtSize( aDo.GetSize() );
740cdf0e10cSrcweir 
741cdf0e10cSrcweir 	// End:
742cdf0e10cSrcweir 	if( !aTxtSize.Height() )
743cdf0e10cSrcweir 	{
744cdf0e10cSrcweir 		aTxtSize.setWidth( 0 );
745cdf0e10cSrcweir 		aTxtSize.setHeight( pOut->GetTextHeight() );
746cdf0e10cSrcweir 	}
747cdf0e10cSrcweir 	return aTxtSize;
748cdf0e10cSrcweir }
749cdf0e10cSrcweir 
750cdf0e10cSrcweir /*************************************************************************
751cdf0e10cSrcweir  *					   class SvxDoDrawCapital
752cdf0e10cSrcweir  * wird von SvxFont::DrawCapital zur Ausgabe von Kapitaelchen benutzt.
753cdf0e10cSrcweir  *************************************************************************/
754cdf0e10cSrcweir 
755cdf0e10cSrcweir class SvxDoDrawCapital : public SvxDoCapitals
756cdf0e10cSrcweir {
757cdf0e10cSrcweir protected:
758cdf0e10cSrcweir 	SvxFont *pFont;
759cdf0e10cSrcweir 	Point aPos;
760cdf0e10cSrcweir 	Point aSpacePos;
761cdf0e10cSrcweir 	short nKern;
762cdf0e10cSrcweir public:
763cdf0e10cSrcweir     SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const XubString &_rTxt,
764cdf0e10cSrcweir                       const xub_StrLen _nIdx, const xub_StrLen _nLen,
765cdf0e10cSrcweir                       const Point &rPos, const short nKrn )
766cdf0e10cSrcweir         : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ),
767cdf0e10cSrcweir 		  pFont( pFnt ),
768cdf0e10cSrcweir 		  aPos( rPos ),
769cdf0e10cSrcweir 		  aSpacePos( rPos ),
770cdf0e10cSrcweir 		  nKern( nKrn )
771cdf0e10cSrcweir 		{ }
772cdf0e10cSrcweir 	virtual void DoSpace( const sal_Bool bDraw );
773cdf0e10cSrcweir 	virtual void SetSpace();
774cdf0e10cSrcweir 	virtual void Do( const XubString &rTxt, const xub_StrLen nIdx,
775cdf0e10cSrcweir 					 const xub_StrLen nLen, const sal_Bool bUpper );
776cdf0e10cSrcweir };
777cdf0e10cSrcweir 
778cdf0e10cSrcweir void SvxDoDrawCapital::DoSpace( const sal_Bool bDraw )
779cdf0e10cSrcweir {
780cdf0e10cSrcweir 	if ( bDraw || pFont->IsWordLineMode() )
781cdf0e10cSrcweir 	{
782cdf0e10cSrcweir 		sal_uInt16 nDiff = (sal_uInt16)(aPos.X() - aSpacePos.X());
783cdf0e10cSrcweir 		if ( nDiff )
784cdf0e10cSrcweir 		{
785cdf0e10cSrcweir 			sal_Bool bWordWise = pFont->IsWordLineMode();
786cdf0e10cSrcweir 			sal_Bool bTrans = pFont->IsTransparent();
787cdf0e10cSrcweir 			pFont->SetWordLineMode( sal_False );
788cdf0e10cSrcweir 			pFont->SetTransparent( sal_True );
789cdf0e10cSrcweir 			pFont->SetPhysFont( pOut );
790cdf0e10cSrcweir 			pOut->DrawStretchText( aSpacePos, nDiff, XubString( sDoubleSpace,
791cdf0e10cSrcweir 							RTL_TEXTENCODING_MS_1252 ), 0, 2 );
792cdf0e10cSrcweir 			pFont->SetWordLineMode( bWordWise );
793cdf0e10cSrcweir 			pFont->SetTransparent( bTrans );
794cdf0e10cSrcweir 			pFont->SetPhysFont( pOut );
795cdf0e10cSrcweir 		}
796cdf0e10cSrcweir 	}
797cdf0e10cSrcweir }
798cdf0e10cSrcweir 
799cdf0e10cSrcweir void SvxDoDrawCapital::SetSpace()
800cdf0e10cSrcweir {
801cdf0e10cSrcweir 	if ( pFont->IsWordLineMode() )
802cdf0e10cSrcweir 		aSpacePos.X() = aPos.X();
803cdf0e10cSrcweir }
804cdf0e10cSrcweir 
805cdf0e10cSrcweir void SvxDoDrawCapital::Do( const XubString &_rTxt, const xub_StrLen _nIdx,
806cdf0e10cSrcweir                            const xub_StrLen _nLen, const sal_Bool bUpper)
807cdf0e10cSrcweir {
808cdf0e10cSrcweir 	sal_uInt8 nProp = 0;
809cdf0e10cSrcweir 	Size aPartSize;
810cdf0e10cSrcweir 
811cdf0e10cSrcweir 	// Einstellen der gewuenschten Fonts
812cdf0e10cSrcweir 	FontUnderline eUnder = pFont->GetUnderline();
813cdf0e10cSrcweir 	FontStrikeout eStrike = pFont->GetStrikeout();
814cdf0e10cSrcweir 	pFont->SetUnderline( UNDERLINE_NONE );
815cdf0e10cSrcweir 	pFont->SetStrikeout( STRIKEOUT_NONE );
816cdf0e10cSrcweir 	if ( !bUpper )
817cdf0e10cSrcweir 	{
818cdf0e10cSrcweir 		nProp = pFont->GetPropr();
819cdf0e10cSrcweir 		pFont->SetProprRel( KAPITAELCHENPROP );
820cdf0e10cSrcweir 	}
821cdf0e10cSrcweir 	pFont->SetPhysFont( pOut );
822cdf0e10cSrcweir 
823cdf0e10cSrcweir     aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) );
824cdf0e10cSrcweir 	aPartSize.setHeight( pOut->GetTextHeight() );
825cdf0e10cSrcweir 	long nWidth = aPartSize.Width();
826cdf0e10cSrcweir 	if ( nKern )
827cdf0e10cSrcweir 	{
828cdf0e10cSrcweir 		aPos.X() += (nKern/2);
829cdf0e10cSrcweir         if ( _nLen ) nWidth += (_nLen*long(nKern));
830cdf0e10cSrcweir 	}
831cdf0e10cSrcweir     pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen);
832cdf0e10cSrcweir 
833cdf0e10cSrcweir 	// Font restaurieren
834cdf0e10cSrcweir 	pFont->SetUnderline( eUnder );
835cdf0e10cSrcweir 	pFont->SetStrikeout( eStrike );
836cdf0e10cSrcweir 	if ( !bUpper )
837cdf0e10cSrcweir 		pFont->SetPropr( nProp );
838cdf0e10cSrcweir 	pFont->SetPhysFont( pOut );
839cdf0e10cSrcweir 
840cdf0e10cSrcweir 	aPos.X() += nWidth-(nKern/2);
841cdf0e10cSrcweir }
842cdf0e10cSrcweir 
843cdf0e10cSrcweir /*************************************************************************
844cdf0e10cSrcweir  * SvxFont::DrawCapital() gibt Kapitaelchen aus.
845cdf0e10cSrcweir  *************************************************************************/
846cdf0e10cSrcweir 
847cdf0e10cSrcweir void SvxFont::DrawCapital( OutputDevice *pOut,
848cdf0e10cSrcweir 			   const Point &rPos, const XubString &rTxt,
849cdf0e10cSrcweir 			   const xub_StrLen nIdx, const xub_StrLen nLen ) const
850cdf0e10cSrcweir {
851cdf0e10cSrcweir 	SvxDoDrawCapital aDo( (SvxFont *)this,pOut,rTxt,nIdx,nLen,rPos,nKern );
852cdf0e10cSrcweir 	DoOnCapitals( aDo );
853cdf0e10cSrcweir }
854cdf0e10cSrcweir 
855cdf0e10cSrcweir #endif // !REDUCEDSVXFONT
856cdf0e10cSrcweir 
857cdf0e10cSrcweir 
858