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