xref: /aoo41x/main/sw/source/core/txtnode/swfont.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <hintids.hxx>
33 
34 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
35 #include <com/sun/star/i18n/ScriptType.hdl>
36 #endif
37 #ifndef _OUTDEV_HXX //autogen
38 #include <vcl/outdev.hxx>
39 #endif
40 #include <unotools/localedatawrapper.hxx>
41 #include <editeng/unolingu.hxx>
42 #include <editeng/brshitem.hxx>
43 #include <editeng/wrlmitem.hxx>
44 #include <editeng/blnkitem.hxx>
45 #include <editeng/nhypitem.hxx>
46 #include <editeng/kernitem.hxx>
47 #include <editeng/cmapitem.hxx>
48 #include <editeng/langitem.hxx>
49 #include <editeng/escpitem.hxx>
50 #include <editeng/akrnitem.hxx>
51 #include <editeng/shdditem.hxx>
52 #include <editeng/charreliefitem.hxx>
53 #ifndef _SVX_CNTRITEM_HXX //autogen
54 #include <editeng/cntritem.hxx>
55 #endif
56 #include <editeng/colritem.hxx>
57 #include <editeng/cscoitem.hxx>
58 #include <editeng/crsditem.hxx>
59 #include <editeng/udlnitem.hxx>
60 #include <editeng/wghtitem.hxx>
61 #include <editeng/postitem.hxx>
62 #include <editeng/fhgtitem.hxx>
63 #include <editeng/fontitem.hxx>
64 #ifndef _SVX_EMPHITEM_HXX //autogen
65 #include <editeng/emphitem.hxx>
66 #endif
67 #include <editeng/charscaleitem.hxx>
68 #include <editeng/charrotateitem.hxx>
69 #include <editeng/twolinesitem.hxx>
70 #include <editeng/charhiddenitem.hxx>
71 #include <IDocumentSettingAccess.hxx>
72 #include <vcl/window.hxx>
73 #include <charatr.hxx>
74 #include <viewsh.hxx>		// Bildschirmabgleich
75 #include <swfont.hxx>
76 #include <fntcache.hxx>     // FontCache
77 #include <txtfrm.hxx>       // SwTxtFrm
78 #include <scriptinfo.hxx>
79 
80 #if defined(WNT) || defined(PM2)
81 #define FNT_LEADING_HACK
82 #endif
83 
84 #if defined(WNT)
85 #define FNT_ATM_HACK
86 #endif
87 
88 #ifdef DBG_UTIL
89 // globale Variable
90 SvStatistics aSvStat;
91 #endif
92 
93 using namespace ::com::sun::star;
94 
95 /************************************************************************
96  * Hintergrundbrush setzen, z.B. bei Zeichenvorlagen
97  ***********************************************************************/
98 
99 void SwFont::SetBackColor( Color* pNewColor )
100 {
101 	delete pBackColor;
102 	pBackColor = pNewColor;
103 	bFntChg = sal_True;
104 	aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0;
105 }
106 
107 // maps directions for vertical layout
108 sal_uInt16 MapDirection( sal_uInt16 nDir, const sal_Bool bVertFormat )
109 {
110     if ( bVertFormat )
111     {
112         switch ( nDir )
113         {
114         case 0 :
115             nDir = 2700;
116             break;
117         case 900 :
118             nDir = 0;
119             break;
120         case 2700 :
121             nDir = 1800;
122             break;
123 #if OSL_DEBUG_LEVEL > 1
124         default :
125             ASSERT( sal_False, "Unsupported direction" );
126             break;
127 #endif
128         }
129     }
130     return nDir;
131 }
132 
133 // maps the absolute direction set at the font to its logical conterpart
134 // in the rotated environment
135 sal_uInt16 UnMapDirection( sal_uInt16 nDir, const sal_Bool bVertFormat )
136 {
137     if ( bVertFormat )
138     {
139         switch ( nDir )
140         {
141         case 0 :
142             nDir = 900;
143             break;
144         case 1800 :
145             nDir = 2700;
146             break;
147         case 2700 :
148             nDir = 0;
149             break;
150 #if OSL_DEBUG_LEVEL > 1
151         default :
152             ASSERT( sal_False, "Unsupported direction" );
153             break;
154 #endif
155         }
156     }
157     return nDir;
158 }
159 
160 sal_uInt16 SwFont::GetOrientation( const sal_Bool bVertFormat ) const
161 {
162     return UnMapDirection( aSub[nActual].GetOrientation(), bVertFormat );
163 }
164 
165 void SwFont::SetVertical( sal_uInt16 nDir, const sal_Bool bVertFormat )
166 {
167     // map direction if frame has vertical layout
168     nDir = MapDirection( nDir, bVertFormat );
169 
170     if( nDir != aSub[0].GetOrientation() )
171 	{
172 		bFntChg = sal_True;
173 		aSub[0].SetVertical( nDir, bVertFormat );
174         aSub[1].SetVertical( nDir, bVertFormat || nDir > 1000 );
175 		aSub[2].SetVertical( nDir, bVertFormat );
176 	}
177 }
178 
179 /*************************************************************************
180  Escapement:
181 	frEsc:  Fraction, Grad des Escapements
182 	Esc = resultierendes Escapement
183 	A1 = Original-Ascent			(nOrgAscent)
184 	A2 = verkleinerter Ascent		(nEscAscent)
185 	Ax = resultierender Ascent		(GetAscent())
186 	H1 = Original-Hoehe 			(nOrgHeight)
187 	H2 = verkleinerter Hoehe		(nEscHeight)
188 	Hx = resultierender Hoehe		(GetHeight())
189 	Bx = resultierende Baseline fuer die Textausgabe (CalcPos())
190 		 (Vorsicht: Y - A1!)
191 
192 	Escapement:
193 		Esc = H1 * frEsc;
194 
195 	Hochstellung:
196 		Ax = A2 + Esc;
197 		Hx = H2 + Esc;
198 		Bx = A1 - Esc;
199 
200 	Tiefstellung:
201 		Ax = A1;
202 		Hx = A1 + Esc + (H2 - A2);
203 		Bx = A1 + Esc;
204 
205 *************************************************************************/
206 
207 /*************************************************************************
208  *					SwSubFont::CalcEscAscent( const sal_uInt16 nOldAscent )
209  *************************************************************************/
210 
211 // nEsc ist der Prozentwert
212 sal_uInt16 SwSubFont::CalcEscAscent( const sal_uInt16 nOldAscent ) const
213 {
214 	if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
215 		DFLT_ESC_AUTO_SUB != GetEscapement() )
216 	{
217 		const long nAscent = nOldAscent +
218 							 ( (long) nOrgHeight * GetEscapement() ) / 100L;
219 		if ( nAscent>0 )
220 			return ( Max( sal_uInt16 (nAscent), nOrgAscent ));
221 	}
222 	return nOrgAscent;
223 }
224 
225 /*************************************************************************
226  *                      SwFont::SetDiffFnt()
227  *************************************************************************/
228 
229 void SwFont::SetDiffFnt( const SfxItemSet *pAttrSet,
230                          const IDocumentSettingAccess *pIDocumentSettingAccess )
231 {
232 	delete pBackColor;
233 	pBackColor = NULL;
234 
235     if( pAttrSet )
236 	{
237 		const SfxPoolItem* pItem;
238 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONT,
239 			sal_True, &pItem ))
240 		{
241 			const SvxFontItem *pFont = (const SvxFontItem *)pItem;
242 			aSub[SW_LATIN].SetFamily( pFont->GetFamily() );
243 			aSub[SW_LATIN].Font::SetName( pFont->GetFamilyName() );
244 			aSub[SW_LATIN].Font::SetStyleName( pFont->GetStyleName() );
245 			aSub[SW_LATIN].Font::SetPitch( pFont->GetPitch() );
246 			aSub[SW_LATIN].Font::SetCharSet( pFont->GetCharSet() );
247 		}
248 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONTSIZE,
249 			sal_True, &pItem ))
250 		{
251 			const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
252 			aSub[SW_LATIN].SvxFont::SetPropr( 100 );
253 			aSub[SW_LATIN].aSize = aSub[SW_LATIN].Font::GetSize();
254 			Size aTmpSize = aSub[SW_LATIN].aSize;
255 			aTmpSize.Height() = pHeight->GetHeight();
256 			aSub[SW_LATIN].SetSize( aTmpSize );
257 		}
258 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_POSTURE,
259 			sal_True, &pItem ))
260 			aSub[SW_LATIN].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
261 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WEIGHT,
262 			sal_True, &pItem ))
263 			aSub[SW_LATIN].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
264 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_LANGUAGE,
265 			sal_True, &pItem ))
266 			aSub[SW_LATIN].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
267 
268 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONT,
269 			sal_True, &pItem ))
270 		{
271 			const SvxFontItem *pFont = (const SvxFontItem *)pItem;
272 			aSub[SW_CJK].SetFamily( pFont->GetFamily() );
273 			aSub[SW_CJK].Font::SetName( pFont->GetFamilyName() );
274 			aSub[SW_CJK].Font::SetStyleName( pFont->GetStyleName() );
275 			aSub[SW_CJK].Font::SetPitch( pFont->GetPitch() );
276 			aSub[SW_CJK].Font::SetCharSet( pFont->GetCharSet() );
277 		}
278 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONTSIZE,
279 			sal_True, &pItem ))
280 		{
281 			const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
282 			aSub[SW_CJK].SvxFont::SetPropr( 100 );
283 			aSub[SW_CJK].aSize = aSub[SW_CJK].Font::GetSize();
284 			Size aTmpSize = aSub[SW_CJK].aSize;
285 			aTmpSize.Height() = pHeight->GetHeight();
286 			aSub[SW_CJK].SetSize( aTmpSize );
287 		}
288 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_POSTURE,
289 			sal_True, &pItem ))
290 			aSub[SW_CJK].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
291 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_WEIGHT,
292 			sal_True, &pItem ))
293 			aSub[SW_CJK].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
294 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_LANGUAGE,
295 			sal_True, &pItem ))
296 		{
297 			LanguageType eNewLang = ((SvxLanguageItem*)pItem)->GetLanguage();
298 			aSub[SW_CJK].SetLanguage( eNewLang );
299 			aSub[SW_LATIN].SetCJKContextLanguage( eNewLang );
300 			aSub[SW_CJK].SetCJKContextLanguage( eNewLang );
301 			aSub[SW_CTL].SetCJKContextLanguage( eNewLang );
302 		}
303 
304 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONT,
305 			sal_True, &pItem ))
306 		{
307 			const SvxFontItem *pFont = (const SvxFontItem *)pItem;
308 			aSub[SW_CTL].SetFamily( pFont->GetFamily() );
309 			aSub[SW_CTL].Font::SetName( pFont->GetFamilyName() );
310 			aSub[SW_CTL].Font::SetStyleName( pFont->GetStyleName() );
311 			aSub[SW_CTL].Font::SetPitch( pFont->GetPitch() );
312 			aSub[SW_CTL].Font::SetCharSet( pFont->GetCharSet() );
313 		}
314 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONTSIZE,
315 			sal_True, &pItem ))
316 		{
317 			const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
318 			aSub[SW_CTL].SvxFont::SetPropr( 100 );
319 			aSub[SW_CTL].aSize = aSub[SW_CTL].Font::GetSize();
320 			Size aTmpSize = aSub[SW_CTL].aSize;
321 			aTmpSize.Height() = pHeight->GetHeight();
322 			aSub[SW_CTL].SetSize( aTmpSize );
323 		}
324 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_POSTURE,
325 			sal_True, &pItem ))
326 			aSub[SW_CTL].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
327 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_WEIGHT,
328 			sal_True, &pItem ))
329 			aSub[SW_CTL].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
330 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_LANGUAGE,
331 			sal_True, &pItem ))
332 			aSub[SW_CTL].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
333 
334 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_UNDERLINE,
335 			sal_True, &pItem ))
336 		{
337 			SetUnderline( ((SvxUnderlineItem*)pItem)->GetLineStyle() );
338 			SetUnderColor( ((SvxUnderlineItem*)pItem)->GetColor() );
339 		}
340 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_OVERLINE,
341 			sal_True, &pItem ))
342         {
343 			SetOverline( ((SvxOverlineItem*)pItem)->GetLineStyle() );
344 			SetOverColor( ((SvxOverlineItem*)pItem)->GetColor() );
345         }
346 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CROSSEDOUT,
347 			sal_True, &pItem ))
348 			SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
349 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_COLOR,
350 			sal_True, &pItem ))
351 			SetColor( ((SvxColorItem*)pItem)->GetValue() );
352 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_EMPHASIS_MARK,
353 			sal_True, &pItem ))
354 			SetEmphasisMark( ((SvxEmphasisMarkItem*)pItem)->GetEmphasisMark() );
355 
356 		SetTransparent( sal_True );
357 		SetAlign( ALIGN_BASELINE );
358 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CONTOUR,
359 			sal_True, &pItem ))
360 			SetOutline( ((SvxContourItem*)pItem)->GetValue() );
361 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED,
362 			sal_True, &pItem ))
363 			SetShadow( ((SvxShadowedItem*)pItem)->GetValue() );
364 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_RELIEF,
365 			sal_True, &pItem ))
366 			SetRelief( (FontRelief)((SvxCharReliefItem*)pItem)->GetValue() );
367 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED,
368 			sal_True, &pItem ))
369 			SetPropWidth(((SvxShadowedItem*)pItem)->GetValue() ? 50 : 100 );
370 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_AUTOKERN,
371 			sal_True, &pItem ))
372 		{
373 			if( ((SvxAutoKernItem*)pItem)->GetValue() )
374             {
375                 SetAutoKern( ( !pIDocumentSettingAccess ||
376                                !pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION) ) ?
377                                 KERNING_FONTSPECIFIC :
378                                 KERNING_ASIAN );
379             }
380 			else
381     			SetAutoKern( 0 );
382 		}
383 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WORDLINEMODE,
384 			sal_True, &pItem ))
385 			SetWordLineMode( ((SvxWordLineModeItem*)pItem)->GetValue() );
386 
387 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ESCAPEMENT,
388 			sal_True, &pItem ))
389 		{
390 			const SvxEscapementItem *pEsc = (const SvxEscapementItem *)pItem;
391 			SetEscapement( pEsc->GetEsc() );
392 			if( aSub[SW_LATIN].IsEsc() )
393 				SetProportion( pEsc->GetProp() );
394 		}
395 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CASEMAP,
396 			sal_True, &pItem ))
397 			SetCaseMap( ((SvxCaseMapItem*)pItem)->GetCaseMap() );
398 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_KERNING,
399 			sal_True, &pItem ))
400 			SetFixKerning( ((SvxKerningItem*)pItem)->GetValue() );
401 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_NOHYPHEN,
402 			sal_True, &pItem ))
403 			SetNoHyph( ((SvxNoHyphenItem*)pItem)->GetValue() );
404 		if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BLINK,
405 			sal_True, &pItem ))
406 			SetBlink( ((SvxBlinkItem*)pItem)->GetValue() );
407         if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ROTATE,
408             sal_True, &pItem ))
409             SetVertical( ((SvxCharRotateItem*)pItem)->GetValue() );
410         if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND,
411             sal_True, &pItem ))
412             pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() );
413         else
414             pBackColor = NULL;
415         const SfxPoolItem* pTwoLinesItem = 0;
416         if( SFX_ITEM_SET ==
417                 pAttrSet->GetItemState( RES_CHRATR_TWO_LINES, sal_True, &pTwoLinesItem ))
418             if ( ((SvxTwoLinesItem*)pTwoLinesItem)->GetValue() )
419                 SetVertical( 0 );
420 	}
421 	else
422 	{
423 		Invalidate();
424 		bNoHyph = sal_False;
425 		bBlink = sal_False;
426 	}
427 	bPaintBlank = sal_False;
428 	bPaintWrong = sal_False;
429 	ASSERT( aSub[SW_LATIN].IsTransparent(), "SwFont: Transparent revolution" );
430 }
431 
432 /*************************************************************************
433  *						class SwFont
434  *************************************************************************/
435 
436 SwFont::SwFont( const SwFont &rFont )
437 {
438 	aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
439 	aSub[SW_CJK] = rFont.aSub[SW_CJK];
440 	aSub[SW_CTL] = rFont.aSub[SW_CTL];
441     nActual = rFont.nActual;
442 	pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
443 	aUnderColor = rFont.GetUnderColor();
444 	aOverColor  = rFont.GetOverColor();
445     nToxCnt = 0;
446     nRefCnt = 0;
447     m_nMetaCount = 0;
448 	bFntChg = rFont.bFntChg;
449 	bOrgChg = rFont.bOrgChg;
450 	bPaintBlank = rFont.bPaintBlank;
451 	bPaintWrong = sal_False;
452 	bURL = rFont.bURL;
453 	bGreyWave = rFont.bGreyWave;
454 	bNoColReplace = rFont.bNoColReplace;
455 	bNoHyph = rFont.bNoHyph;
456 	bBlink = rFont.bBlink;
457 }
458 
459 SwFont::SwFont( const SwAttrSet* pAttrSet,
460                 const IDocumentSettingAccess* pIDocumentSettingAccess )
461 {
462     nActual = SW_LATIN;
463     nToxCnt = 0;
464     nRefCnt = 0;
465     m_nMetaCount = 0;
466     bPaintBlank = sal_False;
467     bPaintWrong = sal_False;
468     bURL = sal_False;
469     bGreyWave = sal_False;
470     bNoColReplace = sal_False;
471     bNoHyph = pAttrSet->GetNoHyphenHere().GetValue();
472     bBlink = pAttrSet->GetBlink().GetValue();
473     bOrgChg = sal_True;
474     {
475         const SvxFontItem& rFont = pAttrSet->GetFont();
476         aSub[SW_LATIN].SetFamily( rFont.GetFamily() );
477         aSub[SW_LATIN].SetName( rFont.GetFamilyName() );
478         aSub[SW_LATIN].SetStyleName( rFont.GetStyleName() );
479         aSub[SW_LATIN].SetPitch( rFont.GetPitch() );
480         aSub[SW_LATIN].SetCharSet( rFont.GetCharSet() );
481         aSub[SW_LATIN].SvxFont::SetPropr( 100 );   // 100% der FontSize
482         Size aTmpSize = aSub[SW_LATIN].aSize;
483         aTmpSize.Height() = pAttrSet->GetSize().GetHeight();
484         aSub[SW_LATIN].SetSize( aTmpSize );
485         aSub[SW_LATIN].SetItalic( pAttrSet->GetPosture().GetPosture() );
486         aSub[SW_LATIN].SetWeight( pAttrSet->GetWeight().GetWeight() );
487         aSub[SW_LATIN].SetLanguage( pAttrSet->GetLanguage().GetLanguage() );
488     }
489 
490     {
491         const SvxFontItem& rFont = pAttrSet->GetCJKFont();
492         aSub[SW_CJK].SetFamily( rFont.GetFamily() );
493         aSub[SW_CJK].SetName( rFont.GetFamilyName() );
494         aSub[SW_CJK].SetStyleName( rFont.GetStyleName() );
495         aSub[SW_CJK].SetPitch( rFont.GetPitch() );
496         aSub[SW_CJK].SetCharSet( rFont.GetCharSet() );
497         aSub[SW_CJK].SvxFont::SetPropr( 100 );   // 100% der FontSize
498         Size aTmpSize = aSub[SW_CJK].aSize;
499         aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight();
500         aSub[SW_CJK].SetSize( aTmpSize );
501         aSub[SW_CJK].SetItalic( pAttrSet->GetCJKPosture().GetPosture() );
502         aSub[SW_CJK].SetWeight( pAttrSet->GetCJKWeight().GetWeight() );
503         LanguageType eNewLang = pAttrSet->GetCJKLanguage().GetLanguage();
504         aSub[SW_CJK].SetLanguage( eNewLang );
505         aSub[SW_LATIN].SetCJKContextLanguage( eNewLang );
506         aSub[SW_CJK].SetCJKContextLanguage( eNewLang );
507         aSub[SW_CTL].SetCJKContextLanguage( eNewLang );
508     }
509 
510     {
511         const SvxFontItem& rFont = pAttrSet->GetCTLFont();
512         aSub[SW_CTL].SetFamily( rFont.GetFamily() );
513         aSub[SW_CTL].SetName( rFont.GetFamilyName() );
514         aSub[SW_CTL].SetStyleName( rFont.GetStyleName() );
515         aSub[SW_CTL].SetPitch( rFont.GetPitch() );
516         aSub[SW_CTL].SetCharSet( rFont.GetCharSet() );
517         aSub[SW_CTL].SvxFont::SetPropr( 100 );   // 100% der FontSize
518         Size aTmpSize = aSub[SW_CTL].aSize;
519         aTmpSize.Height() = pAttrSet->GetCTLSize().GetHeight();
520         aSub[SW_CTL].SetSize( aTmpSize );
521         aSub[SW_CTL].SetItalic( pAttrSet->GetCTLPosture().GetPosture() );
522         aSub[SW_CTL].SetWeight( pAttrSet->GetCTLWeight().GetWeight() );
523         aSub[SW_CTL].SetLanguage( pAttrSet->GetCTLLanguage().GetLanguage() );
524     }
525 
526     const FontUnderline eUnderline = pAttrSet->GetUnderline().GetLineStyle();
527     if ( pAttrSet->GetCharHidden().GetValue() )
528         SetUnderline( UNDERLINE_DOTTED );
529     else
530         SetUnderline( eUnderline );
531     SetUnderColor( pAttrSet->GetUnderline().GetColor() );
532     SetOverline( pAttrSet->GetOverline().GetLineStyle() );
533     SetOverColor( pAttrSet->GetOverline().GetColor() );
534     SetEmphasisMark( pAttrSet->GetEmphasisMark().GetEmphasisMark() );
535     SetStrikeout( pAttrSet->GetCrossedOut().GetStrikeout() );
536     SetColor( pAttrSet->GetColor().GetValue() );
537     SetTransparent( sal_True );
538     SetAlign( ALIGN_BASELINE );
539     SetOutline( pAttrSet->GetContour().GetValue() );
540     SetShadow( pAttrSet->GetShadowed().GetValue() );
541     SetPropWidth( pAttrSet->GetCharScaleW().GetValue() );
542     SetRelief( (FontRelief)pAttrSet->GetCharRelief().GetValue() );
543 	if( pAttrSet->GetAutoKern().GetValue() )
544     {
545         SetAutoKern( ( !pIDocumentSettingAccess ||
546                        !pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION) ) ?
547                         KERNING_FONTSPECIFIC :
548                         KERNING_ASIAN );
549     }
550 	else
551     	SetAutoKern( 0 );
552     SetWordLineMode( pAttrSet->GetWordLineMode().GetValue() );
553     const SvxEscapementItem &rEsc = pAttrSet->GetEscapement();
554     SetEscapement( rEsc.GetEsc() );
555     if( aSub[SW_LATIN].IsEsc() )
556         SetProportion( rEsc.GetProp() );
557     SetCaseMap( pAttrSet->GetCaseMap().GetCaseMap() );
558     SetFixKerning( pAttrSet->GetKerning().GetValue() );
559     const SfxPoolItem* pItem;
560     if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND,
561         sal_True, &pItem ))
562         pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() );
563     else
564         pBackColor = NULL;
565     const SvxTwoLinesItem& rTwoLinesItem = pAttrSet->Get2Lines();
566     if ( ! rTwoLinesItem.GetValue() )
567         SetVertical( pAttrSet->GetCharRotate().GetValue() );
568     else
569         SetVertical( 0 );
570 }
571 
572 SwSubFont& SwSubFont::operator=( const SwSubFont &rFont )
573 {
574 	SvxFont::operator=( rFont );
575 	pMagic = rFont.pMagic;
576 	nFntIndex = rFont.nFntIndex;
577 	nOrgHeight = rFont.nOrgHeight;
578 	nOrgAscent = rFont.nOrgAscent;
579 	nPropWidth = rFont.nPropWidth;
580 	aSize = rFont.aSize;
581 	return *this;
582 }
583 
584 SwFont& SwFont::operator=( const SwFont &rFont )
585 {
586 	aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
587 	aSub[SW_CJK] = rFont.aSub[SW_CJK];
588 	aSub[SW_CTL] = rFont.aSub[SW_CTL];
589     nActual = rFont.nActual;
590 	delete pBackColor;
591 	pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
592 	aUnderColor = rFont.GetUnderColor();
593 	aOverColor  = rFont.GetOverColor();
594     nToxCnt = 0;
595     nRefCnt = 0;
596     m_nMetaCount = 0;
597 	bFntChg = rFont.bFntChg;
598 	bOrgChg = rFont.bOrgChg;
599 	bPaintBlank = rFont.bPaintBlank;
600 	bPaintWrong = sal_False;
601 	bURL = rFont.bURL;
602 	bGreyWave = rFont.bGreyWave;
603 	bNoColReplace = rFont.bNoColReplace;
604 	bNoHyph = rFont.bNoHyph;
605 	bBlink = rFont.bBlink;
606 	return *this;
607 }
608 
609 /*************************************************************************
610  *						SwFont::GoMagic()
611  *************************************************************************/
612 
613 void SwFont::GoMagic( ViewShell *pSh, sal_uInt8 nWhich )
614 {
615 	SwFntAccess aFntAccess( aSub[nWhich].pMagic, aSub[nWhich].nFntIndex,
616 							&aSub[nWhich], pSh, sal_True );
617 }
618 
619 /*************************************************************************
620  *						SwSubFont::IsSymbol()
621  *************************************************************************/
622 
623 sal_Bool SwSubFont::IsSymbol( ViewShell *pSh )
624 {
625 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, sal_False );
626 	return aFntAccess.Get()->IsSymbol();
627 }
628 
629 /*************************************************************************
630  *						SwSubFont::ChgFnt()
631  *************************************************************************/
632 
633 sal_Bool SwSubFont::ChgFnt( ViewShell *pSh, OutputDevice& rOut )
634 {
635     if ( pLastFont )
636 		pLastFont->Unlock();
637 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, sal_True );
638 	SV_STAT( nChangeFont );
639 
640 	pLastFont = aFntAccess.Get();
641 
642     pLastFont->SetDevFont( pSh, rOut );
643 
644 	pLastFont->Lock();
645 	return UNDERLINE_NONE != GetUnderline() ||
646            UNDERLINE_NONE != GetOverline()  ||
647            STRIKEOUT_NONE != GetStrikeout();
648 }
649 
650 /*************************************************************************
651  *					  SwFont::ChgPhysFnt()
652  *************************************************************************/
653 
654 void SwFont::ChgPhysFnt( ViewShell *pSh, OutputDevice& rOut )
655 {
656 	if( bOrgChg && aSub[nActual].IsEsc() )
657 	{
658 		const sal_uInt8 nOldProp = aSub[nActual].GetPropr();
659         SetProportion( 100 );
660         ChgFnt( pSh, rOut );
661 		SwFntAccess aFntAccess( aSub[nActual].pMagic, aSub[nActual].nFntIndex,
662 								&aSub[nActual], pSh );
663         aSub[nActual].nOrgHeight = aFntAccess.Get()->GetFontHeight( pSh, rOut );
664         aSub[nActual].nOrgAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
665 		SetProportion( nOldProp );
666 		bOrgChg = sal_False;
667 	}
668 
669 	if( bFntChg )
670 	{
671         ChgFnt( pSh, rOut );
672 		bFntChg = bOrgChg;
673 	}
674     if( rOut.GetTextLineColor() != aUnderColor )
675         rOut.SetTextLineColor( aUnderColor );
676     if( rOut.GetOverlineColor() != aOverColor )
677         rOut.SetOverlineColor( aOverColor );
678 }
679 
680 /*************************************************************************
681  *						SwFont::CalcEscHeight()
682  *         Height = MaxAscent + MaxDescent
683  *      MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) );
684  *     MaxDescent = Max (T1_height-T1_ascent,
685  * 						 T2_height-T2_ascent - (Esc * T1_height)
686  *************************************************************************/
687 
688 sal_uInt16 SwSubFont::CalcEscHeight( const sal_uInt16 nOldHeight,
689 							  const sal_uInt16 nOldAscent  ) const
690 {
691 	if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
692 		DFLT_ESC_AUTO_SUB != GetEscapement() )
693 	{
694 		long nDescent = nOldHeight - nOldAscent -
695 							 ( (long) nOrgHeight * GetEscapement() ) / 100L;
696 		const sal_uInt16 nDesc = ( nDescent>0 ) ? Max ( sal_uInt16(nDescent),
697 				   sal_uInt16(nOrgHeight - nOrgAscent) ) : nOrgHeight - nOrgAscent;
698 		return ( nDesc + CalcEscAscent( nOldAscent ) );
699 	}
700 	return nOrgHeight;
701 }
702 
703 short SwSubFont::_CheckKerning( )
704 {
705 	short nKernx = - short( Font::GetSize().Height() / 6 );
706 
707 	if ( nKernx < GetFixKerning() )
708 		return GetFixKerning();
709 	return nKernx;
710 }
711 
712 /*************************************************************************
713  *                    SwSubFont::GetAscent()
714  *************************************************************************/
715 
716 sal_uInt16 SwSubFont::GetAscent( ViewShell *pSh, const OutputDevice& rOut )
717 {
718 	sal_uInt16 nAscent;
719 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
720     nAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
721 	if( GetEscapement() )
722 		nAscent = CalcEscAscent( nAscent );
723 	return nAscent;
724 }
725 
726 /*************************************************************************
727  *					  SwSubFont::GetHeight()
728  *************************************************************************/
729 
730 sal_uInt16 SwSubFont::GetHeight( ViewShell *pSh, const OutputDevice& rOut )
731 {
732 	SV_STAT( nGetTextSize );
733 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
734     const sal_uInt16 nHeight = aFntAccess.Get()->GetFontHeight( pSh, rOut );
735 	if ( GetEscapement() )
736 	{
737         const sal_uInt16 nAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
738 		return CalcEscHeight( nHeight, nAscent ); // + nLeading;
739 	}
740 	return nHeight; // + nLeading;
741 }
742 
743 /*************************************************************************
744  *					  SwSubFont::_GetTxtSize()
745  *************************************************************************/
746 Size SwSubFont::_GetTxtSize( SwDrawTextInfo& rInf )
747 {
748     // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber
749     // sicher ist sicher ...
750     if ( !pLastFont || pLastFont->GetOwner()!=pMagic ||
751          !IsSameInstance( rInf.GetpOut()->GetFont() ) )
752         ChgFnt( rInf.GetShell(), rInf.GetOut() );
753 
754     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
755 
756     Size aTxtSize;
757     xub_StrLen nLn = ( rInf.GetLen() == STRING_LEN ? rInf.GetText().Len()
758                                                    : rInf.GetLen() );
759     rInf.SetLen( nLn );
760     if( IsCapital() && nLn )
761         aTxtSize = GetCapitalSize( rInf );
762     else
763     {
764         SV_STAT( nGetTextSize );
765         long nOldKern = rInf.GetKern();
766         const XubString &rOldTxt = rInf.GetText();
767         rInf.SetKern( CheckKerning() );
768         if ( !IsCaseMap() )
769             aTxtSize = pLastFont->GetTextSize( rInf );
770         else
771         {
772             String aTmp = CalcCaseMap( rInf.GetText() );
773             const XubString &rOldStr = rInf.GetText();
774             sal_Bool bCaseMapLengthDiffers(aTmp.Len() != rOldStr.Len());
775 
776             if(bCaseMapLengthDiffers && rInf.GetLen())
777             {
778                 // #108203#
779                 // If the length of the original string and the CaseMapped one
780                 // are different, it is necessary to handle the given text part as
781                 // a single snippet since it�s size may differ, too.
782                 xub_StrLen nOldIdx(rInf.GetIdx());
783                 xub_StrLen nOldLen(rInf.GetLen());
784                 const XubString aSnippet(rOldStr, nOldIdx, nOldLen);
785                 XubString aNewText(CalcCaseMap(aSnippet));
786 
787                 rInf.SetText( aNewText );
788                 rInf.SetIdx( 0 );
789                 rInf.SetLen( aNewText.Len() );
790 
791                 aTxtSize = pLastFont->GetTextSize( rInf );
792 
793                 rInf.SetIdx( nOldIdx );
794                 rInf.SetLen( nOldLen );
795             }
796             else
797             {
798                 rInf.SetText( aTmp );
799                 aTxtSize = pLastFont->GetTextSize( rInf );
800             }
801 
802             rInf.SetText( rOldStr );
803         }
804         rInf.SetKern( nOldKern );
805         rInf.SetText( rOldTxt );
806         // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch
807         //        hochgestellt, muss seine effektive Hoehe melden.
808         if( GetEscapement() )
809         {
810             const sal_uInt16 nAscent = pLastFont->GetFontAscent( rInf.GetShell(),
811                                                              rInf.GetOut() );
812             aTxtSize.Height() =
813                 (long)CalcEscHeight( (sal_uInt16)aTxtSize.Height(), nAscent);
814         }
815     }
816 
817     if (1==rInf.GetLen() && CH_TXT_ATR_FIELDSTART==rInf.GetText().GetChar(rInf.GetIdx()))
818     {
819         xub_StrLen nOldIdx(rInf.GetIdx());
820         xub_StrLen nOldLen(rInf.GetLen());
821         String aNewText=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDSTART);
822         rInf.SetText( aNewText );
823         rInf.SetIdx( 0 );
824         rInf.SetLen( aNewText.Len() );
825         aTxtSize = pLastFont->GetTextSize( rInf );
826         rInf.SetIdx( nOldIdx );
827         rInf.SetLen( nOldLen );
828     }
829     else if (1==rInf.GetLen() && CH_TXT_ATR_FIELDEND==rInf.GetText().GetChar(rInf.GetIdx()))
830     {
831         xub_StrLen nOldIdx(rInf.GetIdx());
832         xub_StrLen nOldLen(rInf.GetLen());
833         String aNewText=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDEND);
834         rInf.SetText( aNewText );
835         rInf.SetIdx( 0 );
836         rInf.SetLen( aNewText.Len() );
837         aTxtSize = pLastFont->GetTextSize( rInf );
838         rInf.SetIdx( nOldIdx );
839         rInf.SetLen( nOldLen );
840     }
841 
842     return aTxtSize;
843 }
844 
845 /*************************************************************************
846  *					  SwSubFont::_DrawText()
847  *************************************************************************/
848 
849 void SwSubFont::_DrawText( SwDrawTextInfo &rInf, const sal_Bool bGrey )
850 {
851     rInf.SetGreyWave( bGrey );
852 	xub_StrLen nLn = rInf.GetText().Len();
853 	if( !rInf.GetLen() || !nLn )
854 		return;
855 	if( STRING_LEN == rInf.GetLen() )
856 		rInf.SetLen( nLn );
857 
858     FontUnderline nOldUnder = UNDERLINE_NONE;
859     SwUnderlineFont* pUnderFnt = 0;
860 
861     if( rInf.GetUnderFnt() )
862 	{
863 		nOldUnder = GetUnderline();
864 		SetUnderline( UNDERLINE_NONE );
865         pUnderFnt = rInf.GetUnderFnt();
866 	}
867 
868 	if( !pLastFont || pLastFont->GetOwner()!=pMagic )
869         ChgFnt( rInf.GetShell(), rInf.GetOut() );
870 
871     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
872 
873 	Point aPos( rInf.GetPos() );
874 	const Point &rOld = rInf.GetPos();
875 	rInf.SetPos( aPos );
876 
877 	if( GetEscapement() )
878         CalcEsc( rInf, aPos );
879 
880     rInf.SetKern( CheckKerning() + rInf.GetSperren() / SPACING_PRECISION_FACTOR );
881 
882 	if( IsCapital() )
883         DrawCapital( rInf );
884 	else
885 	{
886 		SV_STAT( nDrawText );
887 		if ( !IsCaseMap() )
888 			pLastFont->DrawText( rInf );
889 		else
890 		{
891 			const XubString &rOldStr = rInf.GetText();
892 			XubString aString( CalcCaseMap( rOldStr ) );
893 			sal_Bool bCaseMapLengthDiffers(aString.Len() != rOldStr.Len());
894 
895 			if(bCaseMapLengthDiffers && rInf.GetLen())
896 			{
897 				// #108203#
898 				// If the length of the original string and the CaseMapped one
899 				// are different, it is necessary to handle the given text part as
900 				// a single snippet since it�s size may differ, too.
901 				xub_StrLen nOldIdx(rInf.GetIdx());
902 				xub_StrLen nOldLen(rInf.GetLen());
903 				const XubString aSnippet(rOldStr, nOldIdx, nOldLen);
904 				XubString aNewText = CalcCaseMap(aSnippet);
905 
906 				rInf.SetText( aNewText );
907 				rInf.SetIdx( 0 );
908 				rInf.SetLen( aNewText.Len() );
909 
910 				pLastFont->DrawText( rInf );
911 
912 				rInf.SetIdx( nOldIdx );
913 				rInf.SetLen( nOldLen );
914 			}
915 			else
916 			{
917 				rInf.SetText( aString );
918 				pLastFont->DrawText( rInf );
919 			}
920 
921 			rInf.SetText( rOldStr );
922 		}
923 	}
924 
925     if( pUnderFnt && nOldUnder != UNDERLINE_NONE )
926 	{
927 static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
928         Size aFontSize = _GetTxtSize( rInf );
929         const XubString &rOldStr = rInf.GetText();
930         XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
931 
932         xub_StrLen nOldIdx = rInf.GetIdx();
933 		xub_StrLen nOldLen = rInf.GetLen();
934         long nSpace = 0;
935 		if( rInf.GetSpace() )
936 		{
937             xub_StrLen nTmpEnd = nOldIdx + nOldLen;
938 			if( nTmpEnd > rOldStr.Len() )
939 				nTmpEnd = rOldStr.Len();
940 
941             const SwScriptInfo* pSI = rInf.GetScriptInfo();
942 
943             const sal_Bool bAsianFont =
944                 ( rInf.GetFont() && SW_CJK == rInf.GetFont()->GetActual() );
945             for( xub_StrLen nTmp = nOldIdx; nTmp < nTmpEnd; ++nTmp )
946             {
947                 if( CH_BLANK == rOldStr.GetChar( nTmp ) || bAsianFont ||
948                     ( nTmp + 1 < rOldStr.Len() && pSI &&
949                       i18n::ScriptType::ASIAN == pSI->ScriptType( nTmp + 1 ) ) )
950 					++nSpace;
951             }
952 
953             // if next portion if a hole portion we do not consider any
954             // extra space added because the last character was ASIAN
955             if ( nSpace && rInf.IsSpaceStop() && bAsianFont )
956                  --nSpace;
957 
958             nSpace *= rInf.GetSpace() / SPACING_PRECISION_FACTOR;
959 		}
960 
961         rInf.SetWidth( sal_uInt16(aFontSize.Width() + nSpace) );
962         rInf.SetText( aStr );
963 		rInf.SetIdx( 0 );
964 		rInf.SetLen( 2 );
965         SetUnderline( nOldUnder );
966         rInf.SetUnderFnt( 0 );
967 
968         // set position for underline font
969         rInf.SetPos( pUnderFnt->GetPos() );
970 
971         pUnderFnt->GetFont()._DrawStretchText( rInf );
972 
973         rInf.SetUnderFnt( pUnderFnt );
974         rInf.SetText( rOldStr );
975 		rInf.SetIdx( nOldIdx );
976 		rInf.SetLen( nOldLen );
977 	}
978 
979     rInf.SetPos( rOld );
980 }
981 
982 void SwSubFont::_DrawStretchText( SwDrawTextInfo &rInf )
983 {
984 	if( !rInf.GetLen() || !rInf.GetText().Len() )
985 		return;
986 
987     FontUnderline nOldUnder = UNDERLINE_NONE;
988     SwUnderlineFont* pUnderFnt = 0;
989 
990     if( rInf.GetUnderFnt() )
991 	{
992 		nOldUnder = GetUnderline();
993 		SetUnderline( UNDERLINE_NONE );
994         pUnderFnt = rInf.GetUnderFnt();
995 	}
996 
997     if ( !pLastFont || pLastFont->GetOwner() != pMagic )
998         ChgFnt( rInf.GetShell(), rInf.GetOut() );
999 
1000     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
1001 
1002     rInf.ApplyAutoColor();
1003 
1004 	Point aPos( rInf.GetPos() );
1005 
1006 	if( GetEscapement() )
1007         CalcEsc( rInf, aPos );
1008 
1009     rInf.SetKern( CheckKerning() + rInf.GetSperren() / SPACING_PRECISION_FACTOR );
1010     const Point &rOld = rInf.GetPos();
1011     rInf.SetPos( aPos );
1012 
1013 	if( IsCapital() )
1014 		DrawStretchCapital( rInf );
1015 	else
1016 	{
1017 		SV_STAT( nDrawStretchText );
1018 
1019         if ( rInf.GetFrm() )
1020         {
1021             if ( rInf.GetFrm()->IsRightToLeft() )
1022                 rInf.GetFrm()->SwitchLTRtoRTL( aPos );
1023 
1024             if ( rInf.GetFrm()->IsVertical() )
1025                 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
1026         }
1027 
1028 		if ( !IsCaseMap() )
1029 			rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(),
1030 							rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
1031 		else
1032 			rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(), CalcCaseMap(
1033 							rInf.GetText() ), rInf.GetIdx(), rInf.GetLen() );
1034 	}
1035 
1036     if( pUnderFnt && nOldUnder != UNDERLINE_NONE )
1037 	{
1038 static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
1039 		const XubString &rOldStr = rInf.GetText();
1040 		XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
1041 		xub_StrLen nOldIdx = rInf.GetIdx();
1042 		xub_StrLen nOldLen = rInf.GetLen();
1043 		rInf.SetText( aStr );
1044 		rInf.SetIdx( 0 );
1045 		rInf.SetLen( 2 );
1046 		SetUnderline( nOldUnder );
1047         rInf.SetUnderFnt( 0 );
1048 
1049         // set position for underline font
1050         rInf.SetPos( pUnderFnt->GetPos() );
1051 
1052         pUnderFnt->GetFont()._DrawStretchText( rInf );
1053 
1054         rInf.SetUnderFnt( pUnderFnt );
1055         rInf.SetText( rOldStr );
1056 		rInf.SetIdx( nOldIdx );
1057 		rInf.SetLen( nOldLen );
1058 	}
1059 
1060     rInf.SetPos( rOld );
1061 }
1062 
1063 /*************************************************************************
1064  *					  SwSubFont::_GetCrsrOfst()
1065  *************************************************************************/
1066 
1067 xub_StrLen SwSubFont::_GetCrsrOfst( SwDrawTextInfo& rInf )
1068 {
1069 	if ( !pLastFont || pLastFont->GetOwner()!=pMagic )
1070         ChgFnt( rInf.GetShell(), rInf.GetOut() );
1071 
1072     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
1073 
1074 	xub_StrLen nLn = rInf.GetLen() == STRING_LEN ? rInf.GetText().Len()
1075 												 : rInf.GetLen();
1076 	rInf.SetLen( nLn );
1077 	xub_StrLen nCrsr = 0;
1078 	if( IsCapital() && nLn )
1079 		nCrsr = GetCapitalCrsrOfst( rInf );
1080 	else
1081 	{
1082 		const XubString &rOldTxt = rInf.GetText();
1083         long nOldKern = rInf.GetKern();
1084 		rInf.SetKern( CheckKerning() );
1085 		SV_STAT( nGetTextSize );
1086 		if ( !IsCaseMap() )
1087 			nCrsr = pLastFont->GetCrsrOfst( rInf );
1088 		else
1089 		{
1090 			String aTmp = CalcCaseMap( rInf.GetText() );
1091 			rInf.SetText( aTmp );
1092 			nCrsr = pLastFont->GetCrsrOfst( rInf );
1093 		}
1094 		rInf.SetKern( nOldKern );
1095 		rInf.SetText( rOldTxt );
1096 	}
1097 	return nCrsr;
1098 }
1099 
1100 /*************************************************************************
1101  *                    SwSubFont::CalcEsc()
1102  *************************************************************************/
1103 
1104 void SwSubFont::CalcEsc( SwDrawTextInfo& rInf, Point& rPos )
1105 {
1106     long nOfst;
1107 
1108     sal_uInt16 nDir = UnMapDirection(
1109                 GetOrientation(), rInf.GetFrm() && rInf.GetFrm()->IsVertical() );
1110 
1111     switch ( GetEscapement() )
1112     {
1113     case DFLT_ESC_AUTO_SUB :
1114         nOfst = nOrgHeight - nOrgAscent -
1115             pLastFont->GetFontHeight( rInf.GetShell(), rInf.GetOut() ) +
1116             pLastFont->GetFontAscent( rInf.GetShell(), rInf.GetOut() );
1117 
1118         switch ( nDir )
1119         {
1120         case 0 :
1121             rPos.Y() += nOfst;
1122             break;
1123         case 900 :
1124             rPos.X() += nOfst;
1125             break;
1126         case 2700 :
1127             rPos.X() -= nOfst;
1128             break;
1129         }
1130 
1131         break;
1132     case DFLT_ESC_AUTO_SUPER :
1133         nOfst = pLastFont->GetFontAscent( rInf.GetShell(), rInf.GetOut() ) -
1134                 nOrgAscent;
1135 
1136 
1137         switch ( nDir )
1138         {
1139         case 0 :
1140             rPos.Y() += nOfst;
1141             break;
1142         case 900 :
1143             rPos.X() += nOfst;
1144             break;
1145         case 2700 :
1146             rPos.X() -= nOfst;
1147             break;
1148         }
1149 
1150         break;
1151     default :
1152         nOfst = ((long)nOrgHeight * GetEscapement()) / 100L;
1153 
1154         switch ( nDir )
1155         {
1156         case 0 :
1157             rPos.Y() -= nOfst;
1158             break;
1159         case 900 :
1160             rPos.X() -= nOfst;
1161             break;
1162         case 2700 :
1163             rPos.X() += nOfst;
1164             break;
1165         }
1166     }
1167 }
1168 
1169 // used during painting of small capitals
1170 void SwDrawTextInfo::Shift( sal_uInt16 nDir )
1171 {
1172     ASSERT( bPos, "DrawTextInfo: Undefined Position" );
1173     ASSERT( bSize, "DrawTextInfo: Undefined Width" );
1174 
1175     const sal_Bool bBidiPor = ( GetFrm() && GetFrm()->IsRightToLeft() ) !=
1176                           ( 0 != ( TEXT_LAYOUT_BIDI_RTL & GetpOut()->GetLayoutMode() ) );
1177 
1178     nDir = bBidiPor ?
1179             1800 :
1180             UnMapDirection( nDir, GetFrm() && GetFrm()->IsVertical() );
1181 
1182     switch ( nDir )
1183     {
1184     case 0 :
1185         ((Point*)pPos)->X() += GetSize().Width();
1186         break;
1187     case 900 :
1188         ASSERT( ((Point*)pPos)->Y() >= GetSize().Width(), "Going underground" );
1189         ((Point*)pPos)->Y() -= GetSize().Width();
1190         break;
1191     case 1800 :
1192         ((Point*)pPos)->X() -= GetSize().Width();
1193         break;
1194     case 2700 :
1195         ((Point*)pPos)->Y() += GetSize().Width();
1196         break;
1197     }
1198 }
1199 
1200 /*************************************************************************
1201  *                      SwUnderlineFont::~SwUnderlineFont
1202  *
1203  * Used for the "continuous underline" feature.
1204  *************************************************************************/
1205 
1206 SwUnderlineFont::SwUnderlineFont( SwFont& rFnt, const Point& rPoint )
1207         : aPos( rPoint ), pFnt( &rFnt )
1208 {
1209 };
1210 
1211 SwUnderlineFont::~SwUnderlineFont()
1212 {
1213      delete pFnt;
1214 }
1215 
1216 //Helper for filters to find true lineheight of a font
1217 long AttrSetToLineHeight( const IDocumentSettingAccess& rIDocumentSettingAccess,
1218                           const SwAttrSet &rSet,
1219                           const OutputDevice &rOut, sal_Int16 nScript)
1220 {
1221     SwFont aFont(&rSet, &rIDocumentSettingAccess);
1222     sal_uInt8 nActual;
1223     switch (nScript)
1224     {
1225         default:
1226         case i18n::ScriptType::LATIN:
1227             nActual = SW_LATIN;
1228             break;
1229         case i18n::ScriptType::ASIAN:
1230             nActual = SW_CJK;
1231             break;
1232         case i18n::ScriptType::COMPLEX:
1233             nActual = SW_CTL;
1234             break;
1235     }
1236     aFont.SetActual(nActual);
1237 
1238     OutputDevice &rMutableOut = const_cast<OutputDevice &>(rOut);
1239     const Font aOldFont(rMutableOut.GetFont());
1240 
1241     rMutableOut.SetFont(aFont.GetActualFont());
1242     long nHeight = rMutableOut.GetTextHeight();
1243 
1244     rMutableOut.SetFont(aOldFont);
1245     return nHeight;
1246 }
1247