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