xref: /trunk/main/sw/source/core/txtnode/swfont.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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