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