xref: /trunk/main/sw/source/core/txtnode/swfont.cxx (revision 6e988add)
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 
SetBackColor(Color * pNewColor)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
MapDirection(sal_uInt16 nDir,const sal_Bool bVertFormat)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
UnMapDirection(sal_uInt16 nDir,const sal_Bool bVertFormat)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 
GetOrientation(const sal_Bool bVertFormat) const156 sal_uInt16 SwFont::GetOrientation( const sal_Bool bVertFormat ) const
157 {
158     return UnMapDirection( aSub[nActual].GetOrientation(), bVertFormat );
159 }
160 
SetVertical(sal_uInt16 nDir,const sal_Bool bVertFormat)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 );
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
CalcEscAscent(const sal_uInt16 nOldAscent) const208 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 
SetDiffFnt(const SfxItemSet * pAttrSet,const IDocumentSettingAccess * pIDocumentSettingAccess)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 
SwFont(const SwFont & rFont)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     m_nInputFieldCount = 0;
445 	bFntChg = rFont.bFntChg;
446 	bOrgChg = rFont.bOrgChg;
447 	bPaintBlank = rFont.bPaintBlank;
448 	bPaintWrong = sal_False;
449 	bURL = rFont.bURL;
450 	bGreyWave = rFont.bGreyWave;
451 	bNoColReplace = rFont.bNoColReplace;
452 	bNoHyph = rFont.bNoHyph;
453 	bBlink = rFont.bBlink;
454 }
455 
SwFont(const SwAttrSet * pAttrSet,const IDocumentSettingAccess * pIDocumentSettingAccess)456 SwFont::SwFont( const SwAttrSet* pAttrSet,
457                 const IDocumentSettingAccess* pIDocumentSettingAccess )
458 {
459     nActual = SW_LATIN;
460     nToxCnt = 0;
461     nRefCnt = 0;
462     m_nMetaCount = 0;
463     m_nInputFieldCount = 0;
464     bPaintBlank = sal_False;
465     bPaintWrong = sal_False;
466     bURL = sal_False;
467     bGreyWave = sal_False;
468     bNoColReplace = sal_False;
469     bNoHyph = pAttrSet->GetNoHyphenHere().GetValue();
470     bBlink = pAttrSet->GetBlink().GetValue();
471     bOrgChg = sal_True;
472     {
473         const SvxFontItem& rFont = pAttrSet->GetFont();
474         aSub[SW_LATIN].SetFamily( rFont.GetFamily() );
475         aSub[SW_LATIN].SetName( rFont.GetFamilyName() );
476         aSub[SW_LATIN].SetStyleName( rFont.GetStyleName() );
477         aSub[SW_LATIN].SetPitch( rFont.GetPitch() );
478         aSub[SW_LATIN].SetCharSet( rFont.GetCharSet() );
479         aSub[SW_LATIN].SvxFont::SetPropr( 100 );   // 100% der FontSize
480         Size aTmpSize = aSub[SW_LATIN].aSize;
481         aTmpSize.Height() = pAttrSet->GetSize().GetHeight();
482         aSub[SW_LATIN].SetSize( aTmpSize );
483         aSub[SW_LATIN].SetItalic( pAttrSet->GetPosture().GetPosture() );
484         aSub[SW_LATIN].SetWeight( pAttrSet->GetWeight().GetWeight() );
485         aSub[SW_LATIN].SetLanguage( pAttrSet->GetLanguage().GetLanguage() );
486     }
487 
488     {
489         const SvxFontItem& rFont = pAttrSet->GetCJKFont();
490         aSub[SW_CJK].SetFamily( rFont.GetFamily() );
491         aSub[SW_CJK].SetName( rFont.GetFamilyName() );
492         aSub[SW_CJK].SetStyleName( rFont.GetStyleName() );
493         aSub[SW_CJK].SetPitch( rFont.GetPitch() );
494         aSub[SW_CJK].SetCharSet( rFont.GetCharSet() );
495         aSub[SW_CJK].SvxFont::SetPropr( 100 );   // 100% der FontSize
496         Size aTmpSize = aSub[SW_CJK].aSize;
497         aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight();
498         aSub[SW_CJK].SetSize( aTmpSize );
499         aSub[SW_CJK].SetItalic( pAttrSet->GetCJKPosture().GetPosture() );
500         aSub[SW_CJK].SetWeight( pAttrSet->GetCJKWeight().GetWeight() );
501         LanguageType eNewLang = pAttrSet->GetCJKLanguage().GetLanguage();
502         aSub[SW_CJK].SetLanguage( eNewLang );
503         aSub[SW_LATIN].SetCJKContextLanguage( eNewLang );
504         aSub[SW_CJK].SetCJKContextLanguage( eNewLang );
505         aSub[SW_CTL].SetCJKContextLanguage( eNewLang );
506     }
507 
508     {
509         const SvxFontItem& rFont = pAttrSet->GetCTLFont();
510         aSub[SW_CTL].SetFamily( rFont.GetFamily() );
511         aSub[SW_CTL].SetName( rFont.GetFamilyName() );
512         aSub[SW_CTL].SetStyleName( rFont.GetStyleName() );
513         aSub[SW_CTL].SetPitch( rFont.GetPitch() );
514         aSub[SW_CTL].SetCharSet( rFont.GetCharSet() );
515         aSub[SW_CTL].SvxFont::SetPropr( 100 );   // 100% der FontSize
516         Size aTmpSize = aSub[SW_CTL].aSize;
517         aTmpSize.Height() = pAttrSet->GetCTLSize().GetHeight();
518         aSub[SW_CTL].SetSize( aTmpSize );
519         aSub[SW_CTL].SetItalic( pAttrSet->GetCTLPosture().GetPosture() );
520         aSub[SW_CTL].SetWeight( pAttrSet->GetCTLWeight().GetWeight() );
521         aSub[SW_CTL].SetLanguage( pAttrSet->GetCTLLanguage().GetLanguage() );
522     }
523 
524     const FontUnderline eUnderline = pAttrSet->GetUnderline().GetLineStyle();
525     if ( pAttrSet->GetCharHidden().GetValue() )
526         SetUnderline( UNDERLINE_DOTTED );
527     else
528         SetUnderline( eUnderline );
529     SetUnderColor( pAttrSet->GetUnderline().GetColor() );
530     SetOverline( pAttrSet->GetOverline().GetLineStyle() );
531     SetOverColor( pAttrSet->GetOverline().GetColor() );
532     SetEmphasisMark( pAttrSet->GetEmphasisMark().GetEmphasisMark() );
533     SetStrikeout( pAttrSet->GetCrossedOut().GetStrikeout() );
534     SetColor( pAttrSet->GetColor().GetValue() );
535     SetTransparent( sal_True );
536     SetAlign( ALIGN_BASELINE );
537     SetOutline( pAttrSet->GetContour().GetValue() );
538     SetShadow( pAttrSet->GetShadowed().GetValue() );
539     SetPropWidth( pAttrSet->GetCharScaleW().GetValue() );
540     SetRelief( (FontRelief)pAttrSet->GetCharRelief().GetValue() );
541 	if( pAttrSet->GetAutoKern().GetValue() )
542     {
543         SetAutoKern( ( !pIDocumentSettingAccess ||
544                        !pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION) ) ?
545                         KERNING_FONTSPECIFIC :
546                         KERNING_ASIAN );
547     }
548 	else
549     	SetAutoKern( 0 );
550     SetWordLineMode( pAttrSet->GetWordLineMode().GetValue() );
551     const SvxEscapementItem &rEsc = pAttrSet->GetEscapement();
552     SetEscapement( rEsc.GetEsc() );
553     if( aSub[SW_LATIN].IsEsc() )
554         SetProportion( rEsc.GetProp() );
555     SetCaseMap( pAttrSet->GetCaseMap().GetCaseMap() );
556     SetFixKerning( pAttrSet->GetKerning().GetValue() );
557     const SfxPoolItem* pItem;
558     if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND,
559         sal_True, &pItem ))
560         pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() );
561     else
562         pBackColor = NULL;
563     const SvxTwoLinesItem& rTwoLinesItem = pAttrSet->Get2Lines();
564     if ( ! rTwoLinesItem.GetValue() )
565         SetVertical( pAttrSet->GetCharRotate().GetValue() );
566     else
567         SetVertical( 0 );
568 }
569 
operator =(const SwSubFont & rFont)570 SwSubFont& SwSubFont::operator=( const SwSubFont &rFont )
571 {
572 	SvxFont::operator=( rFont );
573 	pMagic = rFont.pMagic;
574 	nFntIndex = rFont.nFntIndex;
575 	nOrgHeight = rFont.nOrgHeight;
576 	nOrgAscent = rFont.nOrgAscent;
577 	nPropWidth = rFont.nPropWidth;
578 	aSize = rFont.aSize;
579 	return *this;
580 }
581 
operator =(const SwFont & rFont)582 SwFont& SwFont::operator=( const SwFont &rFont )
583 {
584 	aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
585 	aSub[SW_CJK] = rFont.aSub[SW_CJK];
586 	aSub[SW_CTL] = rFont.aSub[SW_CTL];
587     nActual = rFont.nActual;
588 	delete pBackColor;
589 	pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
590 	aUnderColor = rFont.GetUnderColor();
591 	aOverColor  = rFont.GetOverColor();
592     nToxCnt = 0;
593     nRefCnt = 0;
594     m_nMetaCount = 0;
595     m_nInputFieldCount = 0;
596 	bFntChg = rFont.bFntChg;
597 	bOrgChg = rFont.bOrgChg;
598 	bPaintBlank = rFont.bPaintBlank;
599 	bPaintWrong = sal_False;
600 	bURL = rFont.bURL;
601 	bGreyWave = rFont.bGreyWave;
602 	bNoColReplace = rFont.bNoColReplace;
603 	bNoHyph = rFont.bNoHyph;
604 	bBlink = rFont.bBlink;
605 	return *this;
606 }
607 
608 /*************************************************************************
609  *						SwFont::GoMagic()
610  *************************************************************************/
611 
GoMagic(ViewShell * pSh,sal_uInt8 nWhich)612 void SwFont::GoMagic( ViewShell *pSh, sal_uInt8 nWhich )
613 {
614 	SwFntAccess aFntAccess( aSub[nWhich].pMagic, aSub[nWhich].nFntIndex,
615 							&aSub[nWhich], pSh, sal_True );
616 }
617 
618 /*************************************************************************
619  *						SwSubFont::IsSymbol()
620  *************************************************************************/
621 
IsSymbol(ViewShell * pSh)622 sal_Bool SwSubFont::IsSymbol( ViewShell *pSh )
623 {
624 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, sal_False );
625 	return aFntAccess.Get()->IsSymbol();
626 }
627 
628 /*************************************************************************
629  *						SwSubFont::ChgFnt()
630  *************************************************************************/
631 
ChgFnt(ViewShell * pSh,OutputDevice & rOut)632 sal_Bool SwSubFont::ChgFnt( ViewShell *pSh, OutputDevice& rOut )
633 {
634     if ( pLastFont )
635 		pLastFont->Unlock();
636 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, sal_True );
637 	SV_STAT( nChangeFont );
638 
639 	pLastFont = aFntAccess.Get();
640 
641     pLastFont->SetDevFont( pSh, rOut );
642 
643 	pLastFont->Lock();
644 	return UNDERLINE_NONE != GetUnderline() ||
645            UNDERLINE_NONE != GetOverline()  ||
646            STRIKEOUT_NONE != GetStrikeout();
647 }
648 
649 /*************************************************************************
650  *					  SwFont::ChgPhysFnt()
651  *************************************************************************/
652 
ChgPhysFnt(ViewShell * pSh,OutputDevice & rOut)653 void SwFont::ChgPhysFnt( ViewShell *pSh, OutputDevice& rOut )
654 {
655 	if( bOrgChg && aSub[nActual].IsEsc() )
656 	{
657 		const sal_uInt8 nOldProp = aSub[nActual].GetPropr();
658         SetProportion( 100 );
659         ChgFnt( pSh, rOut );
660 		SwFntAccess aFntAccess( aSub[nActual].pMagic, aSub[nActual].nFntIndex,
661 								&aSub[nActual], pSh );
662         aSub[nActual].nOrgHeight = aFntAccess.Get()->GetFontHeight( pSh, rOut );
663         aSub[nActual].nOrgAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
664 		SetProportion( nOldProp );
665 		bOrgChg = sal_False;
666 	}
667 
668 	if( bFntChg )
669 	{
670         ChgFnt( pSh, rOut );
671 		bFntChg = bOrgChg;
672 	}
673     if( rOut.GetTextLineColor() != aUnderColor )
674         rOut.SetTextLineColor( aUnderColor );
675     if( rOut.GetOverlineColor() != aOverColor )
676         rOut.SetOverlineColor( aOverColor );
677 }
678 
679 /*************************************************************************
680  *						SwFont::CalcEscHeight()
681  *         Height = MaxAscent + MaxDescent
682  *      MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) );
683  *     MaxDescent = Max (T1_height-T1_ascent,
684  * 						 T2_height-T2_ascent - (Esc * T1_height)
685  *************************************************************************/
686 
CalcEscHeight(const sal_uInt16 nOldHeight,const sal_uInt16 nOldAscent) const687 sal_uInt16 SwSubFont::CalcEscHeight( const sal_uInt16 nOldHeight,
688 							  const sal_uInt16 nOldAscent  ) const
689 {
690 	if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
691 		DFLT_ESC_AUTO_SUB != GetEscapement() )
692 	{
693 		long nDescent = nOldHeight - nOldAscent -
694 							 ( (long) nOrgHeight * GetEscapement() ) / 100L;
695 		const sal_uInt16 nDesc = ( nDescent>0 ) ? Max ( sal_uInt16(nDescent),
696 				   sal_uInt16(nOrgHeight - nOrgAscent) ) : nOrgHeight - nOrgAscent;
697 		return ( nDesc + CalcEscAscent( nOldAscent ) );
698 	}
699 	return nOrgHeight;
700 }
701 
_CheckKerning()702 short SwSubFont::_CheckKerning( )
703 {
704 	short nKernx = - short( Font::GetSize().Height() / 6 );
705 
706 	if ( nKernx < GetFixKerning() )
707 		return GetFixKerning();
708 	return nKernx;
709 }
710 
711 /*************************************************************************
712  *                    SwSubFont::GetAscent()
713  *************************************************************************/
714 
GetAscent(ViewShell * pSh,const OutputDevice & rOut)715 sal_uInt16 SwSubFont::GetAscent( ViewShell *pSh, const OutputDevice& rOut )
716 {
717 	sal_uInt16 nAscent;
718 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
719     nAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
720 	if( GetEscapement() )
721 		nAscent = CalcEscAscent( nAscent );
722 	return nAscent;
723 }
724 
725 /*************************************************************************
726  *					  SwSubFont::GetHeight()
727  *************************************************************************/
728 
GetHeight(ViewShell * pSh,const OutputDevice & rOut)729 sal_uInt16 SwSubFont::GetHeight( ViewShell *pSh, const OutputDevice& rOut )
730 {
731 	SV_STAT( nGetTextSize );
732 	SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
733     const sal_uInt16 nHeight = aFntAccess.Get()->GetFontHeight( pSh, rOut );
734 	if ( GetEscapement() )
735 	{
736         const sal_uInt16 nAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
737 		return CalcEscHeight( nHeight, nAscent ); // + nLeading;
738 	}
739 	return nHeight; // + nLeading;
740 }
741 
742 /*************************************************************************
743  *					  SwSubFont::_GetTxtSize()
744  *************************************************************************/
_GetTxtSize(SwDrawTextInfo & rInf)745 Size SwSubFont::_GetTxtSize( SwDrawTextInfo& rInf )
746 {
747     // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber
748     // sicher ist sicher ...
749     if ( !pLastFont || pLastFont->GetOwner()!=pMagic ||
750          !IsSameInstance( rInf.GetpOut()->GetFont() ) )
751         ChgFnt( rInf.GetShell(), rInf.GetOut() );
752 
753     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
754 
755     Size aTxtSize;
756     xub_StrLen nLn = ( rInf.GetLen() == STRING_LEN ? rInf.GetText().Len()
757                                                    : rInf.GetLen() );
758     rInf.SetLen( nLn );
759     if( IsCapital() && nLn )
760         aTxtSize = GetCapitalSize( rInf );
761     else
762     {
763         SV_STAT( nGetTextSize );
764         long nOldKern = rInf.GetKern();
765         const XubString &rOldTxt = rInf.GetText();
766         rInf.SetKern( CheckKerning() );
767         if ( !IsCaseMap() )
768             aTxtSize = pLastFont->GetTextSize( rInf );
769         else
770         {
771             String aTmp = CalcCaseMap( rInf.GetText() );
772             const XubString &rOldStr = rInf.GetText();
773             sal_Bool bCaseMapLengthDiffers(aTmp.Len() != rOldStr.Len());
774 
775             if(bCaseMapLengthDiffers && rInf.GetLen())
776             {
777                 // #108203#
778                 // If the length of the original string and the CaseMapped one
779                 // are different, it is necessary to handle the given text part as
780                 // a single snippet since it�s size may differ, too.
781                 xub_StrLen nOldIdx(rInf.GetIdx());
782                 xub_StrLen nOldLen(rInf.GetLen());
783                 const XubString aSnippet(rOldStr, nOldIdx, nOldLen);
784                 XubString aNewText(CalcCaseMap(aSnippet));
785 
786                 rInf.SetText( aNewText );
787                 rInf.SetIdx( 0 );
788                 rInf.SetLen( aNewText.Len() );
789 
790                 aTxtSize = pLastFont->GetTextSize( rInf );
791 
792                 rInf.SetIdx( nOldIdx );
793                 rInf.SetLen( nOldLen );
794             }
795             else
796             {
797                 rInf.SetText( aTmp );
798                 aTxtSize = pLastFont->GetTextSize( rInf );
799             }
800 
801             rInf.SetText( rOldStr );
802         }
803         rInf.SetKern( nOldKern );
804         rInf.SetText( rOldTxt );
805         // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch
806         //        hochgestellt, muss seine effektive Hoehe melden.
807         if( GetEscapement() )
808         {
809             const sal_uInt16 nAscent = pLastFont->GetFontAscent( rInf.GetShell(),
810                                                              rInf.GetOut() );
811             aTxtSize.Height() =
812                 (long)CalcEscHeight( (sal_uInt16)aTxtSize.Height(), nAscent);
813         }
814     }
815 
816     if (1==rInf.GetLen() && CH_TXT_ATR_FIELDSTART==rInf.GetText().GetChar(rInf.GetIdx()))
817     {
818         xub_StrLen nOldIdx(rInf.GetIdx());
819         xub_StrLen nOldLen(rInf.GetLen());
820         String aNewText=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDSTART);
821         rInf.SetText( aNewText );
822         rInf.SetIdx( 0 );
823         rInf.SetLen( aNewText.Len() );
824         aTxtSize = pLastFont->GetTextSize( rInf );
825         rInf.SetIdx( nOldIdx );
826         rInf.SetLen( nOldLen );
827     }
828     else if (1==rInf.GetLen() && CH_TXT_ATR_FIELDEND==rInf.GetText().GetChar(rInf.GetIdx()))
829     {
830         xub_StrLen nOldIdx(rInf.GetIdx());
831         xub_StrLen nOldLen(rInf.GetLen());
832         String aNewText=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDEND);
833         rInf.SetText( aNewText );
834         rInf.SetIdx( 0 );
835         rInf.SetLen( aNewText.Len() );
836         aTxtSize = pLastFont->GetTextSize( rInf );
837         rInf.SetIdx( nOldIdx );
838         rInf.SetLen( nOldLen );
839     }
840 
841     return aTxtSize;
842 }
843 
844 /*************************************************************************
845  *					  SwSubFont::_DrawText()
846  *************************************************************************/
847 
_DrawText(SwDrawTextInfo & rInf,const sal_Bool bGrey)848 void SwSubFont::_DrawText( SwDrawTextInfo &rInf, const sal_Bool bGrey )
849 {
850     rInf.SetGreyWave( bGrey );
851 	xub_StrLen nLn = rInf.GetText().Len();
852 	if( !rInf.GetLen() || !nLn )
853 		return;
854 	if( STRING_LEN == rInf.GetLen() )
855 		rInf.SetLen( nLn );
856 
857     FontUnderline nOldUnder = UNDERLINE_NONE;
858     SwUnderlineFont* pUnderFnt = 0;
859 
860     if( rInf.GetUnderFnt() )
861 	{
862 		nOldUnder = GetUnderline();
863 		SetUnderline( UNDERLINE_NONE );
864         pUnderFnt = rInf.GetUnderFnt();
865 	}
866 
867 	if( !pLastFont || pLastFont->GetOwner()!=pMagic )
868         ChgFnt( rInf.GetShell(), rInf.GetOut() );
869 
870     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
871 
872 	Point aPos( rInf.GetPos() );
873 	const Point &rOld = rInf.GetPos();
874 	rInf.SetPos( aPos );
875 
876 	if( GetEscapement() )
877         CalcEsc( rInf, aPos );
878 
879     rInf.SetKern( CheckKerning() + rInf.GetSperren() / SPACING_PRECISION_FACTOR );
880 
881 	if( IsCapital() )
882         DrawCapital( rInf );
883 	else
884 	{
885 		SV_STAT( nDrawText );
886 		if ( !IsCaseMap() )
887 			pLastFont->DrawText( rInf );
888 		else
889 		{
890 			const XubString &rOldStr = rInf.GetText();
891 			XubString aString( CalcCaseMap( rOldStr ) );
892 			sal_Bool bCaseMapLengthDiffers(aString.Len() != rOldStr.Len());
893 
894 			if(bCaseMapLengthDiffers && rInf.GetLen())
895 			{
896 				// #108203#
897 				// If the length of the original string and the CaseMapped one
898 				// are different, it is necessary to handle the given text part as
899 				// a single snippet since it�s size may differ, too.
900 				xub_StrLen nOldIdx(rInf.GetIdx());
901 				xub_StrLen nOldLen(rInf.GetLen());
902 				const XubString aSnippet(rOldStr, nOldIdx, nOldLen);
903 				XubString aNewText = CalcCaseMap(aSnippet);
904 
905 				rInf.SetText( aNewText );
906 				rInf.SetIdx( 0 );
907 				rInf.SetLen( aNewText.Len() );
908 
909 				pLastFont->DrawText( rInf );
910 
911 				rInf.SetIdx( nOldIdx );
912 				rInf.SetLen( nOldLen );
913 			}
914 			else
915 			{
916 				rInf.SetText( aString );
917 				pLastFont->DrawText( rInf );
918 			}
919 
920 			rInf.SetText( rOldStr );
921 		}
922 	}
923 
924     if( pUnderFnt && nOldUnder != UNDERLINE_NONE )
925 	{
926 static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
927         Size aFontSize = _GetTxtSize( rInf );
928         const XubString &rOldStr = rInf.GetText();
929         XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
930 
931         xub_StrLen nOldIdx = rInf.GetIdx();
932 		xub_StrLen nOldLen = rInf.GetLen();
933         long nSpace = 0;
934 		if( rInf.GetSpace() )
935 		{
936             xub_StrLen nTmpEnd = nOldIdx + nOldLen;
937 			if( nTmpEnd > rOldStr.Len() )
938 				nTmpEnd = rOldStr.Len();
939 
940             const SwScriptInfo* pSI = rInf.GetScriptInfo();
941 
942             const sal_Bool bAsianFont =
943                 ( rInf.GetFont() && SW_CJK == rInf.GetFont()->GetActual() );
944             for( xub_StrLen nTmp = nOldIdx; nTmp < nTmpEnd; ++nTmp )
945             {
946                 if( CH_BLANK == rOldStr.GetChar( nTmp ) || bAsianFont ||
947                     ( nTmp + 1 < rOldStr.Len() && pSI &&
948                       i18n::ScriptType::ASIAN == pSI->ScriptType( nTmp + 1 ) ) )
949 					++nSpace;
950             }
951 
952             // if next portion if a hole portion we do not consider any
953             // extra space added because the last character was ASIAN
954             if ( nSpace && rInf.IsSpaceStop() && bAsianFont )
955                  --nSpace;
956 
957             nSpace *= rInf.GetSpace() / SPACING_PRECISION_FACTOR;
958 		}
959 
960         rInf.SetWidth( sal_uInt16(aFontSize.Width() + nSpace) );
961         rInf.SetText( aStr );
962 		rInf.SetIdx( 0 );
963 		rInf.SetLen( 2 );
964         SetUnderline( nOldUnder );
965         rInf.SetUnderFnt( 0 );
966 
967         // set position for underline font
968         rInf.SetPos( pUnderFnt->GetPos() );
969 
970         pUnderFnt->GetFont()._DrawStretchText( rInf );
971 
972         rInf.SetUnderFnt( pUnderFnt );
973         rInf.SetText( rOldStr );
974 		rInf.SetIdx( nOldIdx );
975 		rInf.SetLen( nOldLen );
976 	}
977 
978     rInf.SetPos( rOld );
979 }
980 
_DrawStretchText(SwDrawTextInfo & rInf)981 void SwSubFont::_DrawStretchText( SwDrawTextInfo &rInf )
982 {
983 	if( !rInf.GetLen() || !rInf.GetText().Len() )
984 		return;
985 
986     FontUnderline nOldUnder = UNDERLINE_NONE;
987     SwUnderlineFont* pUnderFnt = 0;
988 
989     if( rInf.GetUnderFnt() )
990 	{
991 		nOldUnder = GetUnderline();
992 		SetUnderline( UNDERLINE_NONE );
993         pUnderFnt = rInf.GetUnderFnt();
994 	}
995 
996     if ( !pLastFont || pLastFont->GetOwner() != pMagic )
997         ChgFnt( rInf.GetShell(), rInf.GetOut() );
998 
999     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
1000 
1001     rInf.ApplyAutoColor();
1002 
1003 	Point aPos( rInf.GetPos() );
1004 
1005 	if( GetEscapement() )
1006         CalcEsc( rInf, aPos );
1007 
1008     rInf.SetKern( CheckKerning() + rInf.GetSperren() / SPACING_PRECISION_FACTOR );
1009     const Point &rOld = rInf.GetPos();
1010     rInf.SetPos( aPos );
1011 
1012 	if( IsCapital() )
1013 		DrawStretchCapital( rInf );
1014 	else
1015 	{
1016 		SV_STAT( nDrawStretchText );
1017 
1018         if ( rInf.GetFrm() )
1019         {
1020             if ( rInf.GetFrm()->IsRightToLeft() )
1021                 rInf.GetFrm()->SwitchLTRtoRTL( aPos );
1022 
1023             if ( rInf.GetFrm()->IsVertical() )
1024                 rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
1025         }
1026 
1027 		if ( !IsCaseMap() )
1028 			rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(),
1029 							rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
1030 		else
1031 			rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(), CalcCaseMap(
1032 							rInf.GetText() ), rInf.GetIdx(), rInf.GetLen() );
1033 	}
1034 
1035     if( pUnderFnt && nOldUnder != UNDERLINE_NONE )
1036 	{
1037 static sal_Char __READONLY_DATA sDoubleSpace[] = "  ";
1038 		const XubString &rOldStr = rInf.GetText();
1039 		XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
1040 		xub_StrLen nOldIdx = rInf.GetIdx();
1041 		xub_StrLen nOldLen = rInf.GetLen();
1042 		rInf.SetText( aStr );
1043 		rInf.SetIdx( 0 );
1044 		rInf.SetLen( 2 );
1045 		SetUnderline( nOldUnder );
1046         rInf.SetUnderFnt( 0 );
1047 
1048         // set position for underline font
1049         rInf.SetPos( pUnderFnt->GetPos() );
1050 
1051         pUnderFnt->GetFont()._DrawStretchText( rInf );
1052 
1053         rInf.SetUnderFnt( pUnderFnt );
1054         rInf.SetText( rOldStr );
1055 		rInf.SetIdx( nOldIdx );
1056 		rInf.SetLen( nOldLen );
1057 	}
1058 
1059     rInf.SetPos( rOld );
1060 }
1061 
1062 /*************************************************************************
1063  *					  SwSubFont::_GetCrsrOfst()
1064  *************************************************************************/
1065 
_GetCrsrOfst(SwDrawTextInfo & rInf)1066 xub_StrLen SwSubFont::_GetCrsrOfst( SwDrawTextInfo& rInf )
1067 {
1068 	if ( !pLastFont || pLastFont->GetOwner()!=pMagic )
1069         ChgFnt( rInf.GetShell(), rInf.GetOut() );
1070 
1071     SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
1072 
1073 	xub_StrLen nLn = rInf.GetLen() == STRING_LEN ? rInf.GetText().Len()
1074 												 : rInf.GetLen();
1075 	rInf.SetLen( nLn );
1076 	xub_StrLen nCrsr = 0;
1077 	if( IsCapital() && nLn )
1078 		nCrsr = GetCapitalCrsrOfst( rInf );
1079 	else
1080 	{
1081 		const XubString &rOldTxt = rInf.GetText();
1082         long nOldKern = rInf.GetKern();
1083 		rInf.SetKern( CheckKerning() );
1084 		SV_STAT( nGetTextSize );
1085 		if ( !IsCaseMap() )
1086 			nCrsr = pLastFont->GetCrsrOfst( rInf );
1087 		else
1088 		{
1089 			String aTmp = CalcCaseMap( rInf.GetText() );
1090 			rInf.SetText( aTmp );
1091 			nCrsr = pLastFont->GetCrsrOfst( rInf );
1092 		}
1093 		rInf.SetKern( nOldKern );
1094 		rInf.SetText( rOldTxt );
1095 	}
1096 	return nCrsr;
1097 }
1098 
1099 /*************************************************************************
1100  *                    SwSubFont::CalcEsc()
1101  *************************************************************************/
1102 
CalcEsc(SwDrawTextInfo & rInf,Point & rPos)1103 void SwSubFont::CalcEsc( SwDrawTextInfo& rInf, Point& rPos )
1104 {
1105     long nOfst;
1106 
1107     sal_uInt16 nDir = UnMapDirection(
1108                 GetOrientation(), rInf.GetFrm() && rInf.GetFrm()->IsVertical() );
1109 
1110     switch ( GetEscapement() )
1111     {
1112     case DFLT_ESC_AUTO_SUB :
1113         nOfst = nOrgHeight - nOrgAscent -
1114             pLastFont->GetFontHeight( rInf.GetShell(), rInf.GetOut() ) +
1115             pLastFont->GetFontAscent( rInf.GetShell(), rInf.GetOut() );
1116 
1117         switch ( nDir )
1118         {
1119         case 0 :
1120             rPos.Y() += nOfst;
1121             break;
1122         case 900 :
1123             rPos.X() += nOfst;
1124             break;
1125         case 2700 :
1126             rPos.X() -= nOfst;
1127             break;
1128         }
1129 
1130         break;
1131     case DFLT_ESC_AUTO_SUPER :
1132         nOfst = pLastFont->GetFontAscent( rInf.GetShell(), rInf.GetOut() ) -
1133                 nOrgAscent;
1134 
1135 
1136         switch ( nDir )
1137         {
1138         case 0 :
1139             rPos.Y() += nOfst;
1140             break;
1141         case 900 :
1142             rPos.X() += nOfst;
1143             break;
1144         case 2700 :
1145             rPos.X() -= nOfst;
1146             break;
1147         }
1148 
1149         break;
1150     default :
1151         nOfst = ((long)nOrgHeight * GetEscapement()) / 100L;
1152 
1153         switch ( nDir )
1154         {
1155         case 0 :
1156             rPos.Y() -= nOfst;
1157             break;
1158         case 900 :
1159             rPos.X() -= nOfst;
1160             break;
1161         case 2700 :
1162             rPos.X() += nOfst;
1163             break;
1164         }
1165     }
1166 }
1167 
1168 // used during painting of small capitals
Shift(sal_uInt16 nDir)1169 void SwDrawTextInfo::Shift( sal_uInt16 nDir )
1170 {
1171     ASSERT( bPos, "DrawTextInfo: Undefined Position" );
1172     ASSERT( bSize, "DrawTextInfo: Undefined Width" );
1173 
1174     const sal_Bool bBidiPor = ( GetFrm() && GetFrm()->IsRightToLeft() ) !=
1175                           ( 0 != ( TEXT_LAYOUT_BIDI_RTL & GetpOut()->GetLayoutMode() ) );
1176 
1177     nDir = bBidiPor ?
1178             1800 :
1179             UnMapDirection( nDir, GetFrm() && GetFrm()->IsVertical() );
1180 
1181     switch ( nDir )
1182     {
1183     case 0 :
1184         ((Point*)pPos)->X() += GetSize().Width();
1185         break;
1186     case 900 :
1187         ASSERT( ((Point*)pPos)->Y() >= GetSize().Width(), "Going underground" );
1188         ((Point*)pPos)->Y() -= GetSize().Width();
1189         break;
1190     case 1800 :
1191         ((Point*)pPos)->X() -= GetSize().Width();
1192         break;
1193     case 2700 :
1194         ((Point*)pPos)->Y() += GetSize().Width();
1195         break;
1196     }
1197 }
1198 
1199 /*************************************************************************
1200  *                      SwUnderlineFont::~SwUnderlineFont
1201  *
1202  * Used for the "continuous underline" feature.
1203  *************************************************************************/
1204 
SwUnderlineFont(SwFont & rFnt,const Point & rPoint)1205 SwUnderlineFont::SwUnderlineFont( SwFont& rFnt, const Point& rPoint )
1206         : aPos( rPoint ), pFnt( &rFnt )
1207 {
1208 };
1209 
~SwUnderlineFont()1210 SwUnderlineFont::~SwUnderlineFont()
1211 {
1212      delete pFnt;
1213 }
1214 
1215 //Helper for filters to find true lineheight of a font
AttrSetToLineHeight(const IDocumentSettingAccess & rIDocumentSettingAccess,const SwAttrSet & rSet,const OutputDevice & rOut,sal_Int16 nScript)1216 long AttrSetToLineHeight( const IDocumentSettingAccess& rIDocumentSettingAccess,
1217                           const SwAttrSet &rSet,
1218                           const OutputDevice &rOut, sal_Int16 nScript)
1219 {
1220     SwFont aFont(&rSet, &rIDocumentSettingAccess);
1221     sal_uInt8 nActual;
1222     switch (nScript)
1223     {
1224         default:
1225         case i18n::ScriptType::LATIN:
1226             nActual = SW_LATIN;
1227             break;
1228         case i18n::ScriptType::ASIAN:
1229             nActual = SW_CJK;
1230             break;
1231         case i18n::ScriptType::COMPLEX:
1232             nActual = SW_CTL;
1233             break;
1234     }
1235     aFont.SetActual(nActual);
1236 
1237     OutputDevice &rMutableOut = const_cast<OutputDevice &>(rOut);
1238     const Font aOldFont(rMutableOut.GetFont());
1239 
1240     rMutableOut.SetFont(aFont.GetActualFont());
1241     long nHeight = rMutableOut.GetTextHeight();
1242 
1243     rMutableOut.SetFont(aOldFont);
1244     return nHeight;
1245 }
1246