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