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/brushitem.hxx>
27 : #include <editeng/wrlmitem.hxx>
28 : #include <editeng/blinkitem.hxx>
29 : #include <editeng/nhypitem.hxx>
30 : #include <editeng/kernitem.hxx>
31 : #include <editeng/cmapitem.hxx>
32 : #include <editeng/langitem.hxx>
33 : #include <editeng/escapementitem.hxx>
34 : #include <editeng/autokernitem.hxx>
35 : #include <editeng/shdditem.hxx>
36 : #include <editeng/charreliefitem.hxx>
37 : #include <editeng/contouritem.hxx>
38 : #include <editeng/colritem.hxx>
39 : #include <editeng/charsetcoloritem.hxx>
40 : #include <editeng/crossedoutitem.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/emphasismarkitem.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 1464 : void SwFont::SetBackColor( Color* pNewColor )
72 : {
73 1464 : delete pBackColor;
74 1464 : pBackColor = pNewColor;
75 1464 : bFntChg = sal_True;
76 1464 : aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0;
77 1464 : }
78 :
79 : // maps directions for vertical layout
80 10513 : sal_uInt16 MapDirection( sal_uInt16 nDir, const sal_Bool bVertFormat )
81 : {
82 10513 : if ( bVertFormat )
83 : {
84 2 : switch ( nDir )
85 : {
86 : case 0 :
87 2 : nDir = 2700;
88 2 : 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 10513 : return nDir;
103 : }
104 :
105 : // maps the absolute direction set at the font to its logical conterpart
106 : // in the rotated environment
107 2510 : sal_uInt16 UnMapDirection( sal_uInt16 nDir, const sal_Bool bVertFormat )
108 : {
109 2510 : 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 2510 : return nDir;
130 : }
131 :
132 1772 : sal_uInt16 SwFont::GetOrientation( const sal_Bool bVertFormat ) const
133 : {
134 1772 : return UnMapDirection( aSub[nActual].GetOrientation(), bVertFormat );
135 : }
136 :
137 10513 : void SwFont::SetVertical( sal_uInt16 nDir, const sal_Bool bVertFormat )
138 : {
139 : // map direction if frame has vertical layout
140 10513 : nDir = MapDirection( nDir, bVertFormat );
141 :
142 10513 : if( nDir != aSub[0].GetOrientation() )
143 : {
144 765 : bFntChg = sal_True;
145 765 : aSub[0].SetVertical( nDir, bVertFormat );
146 765 : aSub[1].SetVertical( nDir, bVertFormat || nDir > 1000 );
147 765 : aSub[2].SetVertical( nDir, bVertFormat );
148 : }
149 10513 : }
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 4589 : sal_uInt16 SwSubFont::CalcEscAscent( const sal_uInt16 nOldAscent ) const
185 : {
186 8988 : if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
187 4399 : DFLT_ESC_AUTO_SUB != GetEscapement() )
188 : {
189 4397 : const long nAscent = nOldAscent +
190 4397 : ( (long) nOrgHeight * GetEscapement() ) / 100L;
191 4397 : if ( nAscent>0 )
192 4397 : return ( std::max( sal_uInt16 (nAscent), nOrgAscent ));
193 : }
194 192 : return nOrgAscent;
195 : }
196 :
197 : /*************************************************************************
198 : * SwFont::SetDiffFnt()
199 : *************************************************************************/
200 :
201 500 : void SwFont::SetDiffFnt( const SfxItemSet *pAttrSet,
202 : const IDocumentSettingAccess *pIDocumentSettingAccess )
203 : {
204 500 : delete pBackColor;
205 500 : pBackColor = NULL;
206 :
207 500 : if( pAttrSet )
208 : {
209 : const SfxPoolItem* pItem;
210 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONT,
211 500 : sal_True, &pItem ))
212 : {
213 60 : const SvxFontItem *pFont = (const SvxFontItem *)pItem;
214 60 : aSub[SW_LATIN].SetFamily( pFont->GetFamily() );
215 60 : aSub[SW_LATIN].Font::SetName( pFont->GetFamilyName() );
216 60 : aSub[SW_LATIN].Font::SetStyleName( pFont->GetStyleName() );
217 60 : aSub[SW_LATIN].Font::SetPitch( pFont->GetPitch() );
218 60 : aSub[SW_LATIN].Font::SetCharSet( pFont->GetCharSet() );
219 : }
220 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_FONTSIZE,
221 500 : sal_True, &pItem ))
222 : {
223 146 : const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
224 146 : aSub[SW_LATIN].SvxFont::SetPropr( 100 );
225 146 : aSub[SW_LATIN].aSize = aSub[SW_LATIN].Font::GetSize();
226 146 : Size aTmpSize = aSub[SW_LATIN].aSize;
227 146 : aTmpSize.Height() = pHeight->GetHeight();
228 146 : aSub[SW_LATIN].SetSize( aTmpSize );
229 : }
230 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_POSTURE,
231 500 : sal_True, &pItem ))
232 30 : aSub[SW_LATIN].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
233 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WEIGHT,
234 500 : sal_True, &pItem ))
235 2 : aSub[SW_LATIN].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
236 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_LANGUAGE,
237 500 : sal_True, &pItem ))
238 0 : aSub[SW_LATIN].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
239 :
240 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONT,
241 500 : 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 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_FONTSIZE,
251 500 : sal_True, &pItem ))
252 : {
253 144 : const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
254 144 : aSub[SW_CJK].SvxFont::SetPropr( 100 );
255 144 : aSub[SW_CJK].aSize = aSub[SW_CJK].Font::GetSize();
256 144 : Size aTmpSize = aSub[SW_CJK].aSize;
257 144 : aTmpSize.Height() = pHeight->GetHeight();
258 144 : aSub[SW_CJK].SetSize( aTmpSize );
259 : }
260 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_POSTURE,
261 500 : sal_True, &pItem ))
262 30 : aSub[SW_CJK].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
263 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_WEIGHT,
264 500 : sal_True, &pItem ))
265 0 : aSub[SW_CJK].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
266 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CJK_LANGUAGE,
267 500 : 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 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONT,
277 500 : sal_True, &pItem ))
278 : {
279 60 : const SvxFontItem *pFont = (const SvxFontItem *)pItem;
280 60 : aSub[SW_CTL].SetFamily( pFont->GetFamily() );
281 60 : aSub[SW_CTL].Font::SetName( pFont->GetFamilyName() );
282 60 : aSub[SW_CTL].Font::SetStyleName( pFont->GetStyleName() );
283 60 : aSub[SW_CTL].Font::SetPitch( pFont->GetPitch() );
284 60 : aSub[SW_CTL].Font::SetCharSet( pFont->GetCharSet() );
285 : }
286 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_FONTSIZE,
287 500 : sal_True, &pItem ))
288 : {
289 144 : const SvxFontHeightItem *pHeight = (const SvxFontHeightItem *)pItem;
290 144 : aSub[SW_CTL].SvxFont::SetPropr( 100 );
291 144 : aSub[SW_CTL].aSize = aSub[SW_CTL].Font::GetSize();
292 144 : Size aTmpSize = aSub[SW_CTL].aSize;
293 144 : aTmpSize.Height() = pHeight->GetHeight();
294 144 : aSub[SW_CTL].SetSize( aTmpSize );
295 : }
296 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_POSTURE,
297 500 : sal_True, &pItem ))
298 30 : aSub[SW_CTL].Font::SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
299 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_WEIGHT,
300 500 : sal_True, &pItem ))
301 0 : aSub[SW_CTL].Font::SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
302 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CTL_LANGUAGE,
303 500 : sal_True, &pItem ))
304 0 : aSub[SW_CTL].SetLanguage( ((SvxLanguageItem*)pItem)->GetLanguage() );
305 :
306 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_UNDERLINE,
307 500 : sal_True, &pItem ))
308 : {
309 146 : SetUnderline( ((SvxUnderlineItem*)pItem)->GetLineStyle() );
310 146 : SetUnderColor( ((SvxUnderlineItem*)pItem)->GetColor() );
311 : }
312 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_OVERLINE,
313 500 : sal_True, &pItem ))
314 : {
315 0 : SetOverline( ((SvxOverlineItem*)pItem)->GetLineStyle() );
316 0 : SetOverColor( ((SvxOverlineItem*)pItem)->GetColor() );
317 : }
318 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CROSSEDOUT,
319 500 : sal_True, &pItem ))
320 0 : SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
321 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_COLOR,
322 500 : sal_True, &pItem ))
323 8 : SetColor( ((SvxColorItem*)pItem)->GetValue() );
324 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_EMPHASIS_MARK,
325 500 : sal_True, &pItem ))
326 138 : SetEmphasisMark( ((SvxEmphasisMarkItem*)pItem)->GetEmphasisMark() );
327 :
328 500 : SetTransparent( sal_True );
329 500 : SetAlign( ALIGN_BASELINE );
330 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CONTOUR,
331 500 : sal_True, &pItem ))
332 0 : SetOutline( ((SvxContourItem*)pItem)->GetValue() );
333 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED,
334 500 : sal_True, &pItem ))
335 0 : SetShadow( ((SvxShadowedItem*)pItem)->GetValue() );
336 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_RELIEF,
337 500 : sal_True, &pItem ))
338 0 : SetRelief( (FontRelief)((SvxCharReliefItem*)pItem)->GetValue() );
339 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_SHADOWED,
340 500 : sal_True, &pItem ))
341 0 : SetPropWidth(((SvxShadowedItem*)pItem)->GetValue() ? 50 : 100 );
342 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_AUTOKERN,
343 500 : sal_True, &pItem ))
344 : {
345 0 : if( ((SvxAutoKernItem*)pItem)->GetValue() )
346 : {
347 0 : 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 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_WORDLINEMODE,
356 500 : sal_True, &pItem ))
357 0 : SetWordLineMode( ((SvxWordLineModeItem*)pItem)->GetValue() );
358 :
359 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ESCAPEMENT,
360 500 : sal_True, &pItem ))
361 : {
362 160 : const SvxEscapementItem *pEsc = (const SvxEscapementItem *)pItem;
363 160 : SetEscapement( pEsc->GetEsc() );
364 160 : if( aSub[SW_LATIN].IsEsc() )
365 160 : SetProportion( pEsc->GetProp() );
366 : }
367 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_CASEMAP,
368 500 : sal_True, &pItem ))
369 8 : SetCaseMap( ((SvxCaseMapItem*)pItem)->GetCaseMap() );
370 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_KERNING,
371 500 : sal_True, &pItem ))
372 0 : SetFixKerning( ((SvxKerningItem*)pItem)->GetValue() );
373 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_NOHYPHEN,
374 500 : sal_True, &pItem ))
375 0 : SetNoHyph( ((SvxNoHyphenItem*)pItem)->GetValue() );
376 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BLINK,
377 500 : sal_True, &pItem ))
378 0 : SetBlink( ((SvxBlinkItem*)pItem)->GetValue() );
379 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_ROTATE,
380 500 : sal_True, &pItem ))
381 0 : SetVertical( ((SvxCharRotateItem*)pItem)->GetValue() );
382 500 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND,
383 500 : sal_True, &pItem ))
384 0 : pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() );
385 : else
386 500 : pBackColor = NULL;
387 500 : const SfxPoolItem* pTwoLinesItem = 0;
388 500 : if( SFX_ITEM_SET ==
389 500 : 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 500 : bPaintBlank = sal_False;
400 500 : bPaintWrong = sal_False;
401 : OSL_ENSURE( aSub[SW_LATIN].IsTransparent(), "SwFont: Transparent revolution" );
402 500 : }
403 :
404 : /*************************************************************************
405 : * class SwFont
406 : *************************************************************************/
407 :
408 104748 : SwFont::SwFont( const SwFont &rFont )
409 : {
410 104748 : aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
411 104748 : aSub[SW_CJK] = rFont.aSub[SW_CJK];
412 104748 : aSub[SW_CTL] = rFont.aSub[SW_CTL];
413 104748 : nActual = rFont.nActual;
414 104748 : pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
415 104748 : aUnderColor = rFont.GetUnderColor();
416 104748 : aOverColor = rFont.GetOverColor();
417 104748 : nToxCnt = 0;
418 104748 : nRefCnt = 0;
419 104748 : m_nMetaCount = 0;
420 104748 : bFntChg = rFont.bFntChg;
421 104748 : bOrgChg = rFont.bOrgChg;
422 104748 : bPaintBlank = rFont.bPaintBlank;
423 104748 : bPaintWrong = sal_False;
424 104748 : bURL = rFont.bURL;
425 104748 : bGreyWave = rFont.bGreyWave;
426 104748 : bNoColReplace = rFont.bNoColReplace;
427 104748 : bNoHyph = rFont.bNoHyph;
428 104748 : bBlink = rFont.bBlink;
429 104748 : }
430 :
431 7773 : SwFont::SwFont( const SwAttrSet* pAttrSet,
432 7773 : const IDocumentSettingAccess* pIDocumentSettingAccess )
433 : {
434 7773 : nActual = SW_LATIN;
435 7773 : nToxCnt = 0;
436 7773 : nRefCnt = 0;
437 7773 : m_nMetaCount = 0;
438 7773 : bPaintBlank = sal_False;
439 7773 : bPaintWrong = sal_False;
440 7773 : bURL = sal_False;
441 7773 : bGreyWave = sal_False;
442 7773 : bNoColReplace = sal_False;
443 7773 : bNoHyph = pAttrSet->GetNoHyphenHere().GetValue();
444 7773 : bBlink = pAttrSet->GetBlink().GetValue();
445 7773 : bOrgChg = sal_True;
446 : {
447 7773 : const SvxFontItem& rFont = pAttrSet->GetFont();
448 7773 : aSub[SW_LATIN].SetFamily( rFont.GetFamily() );
449 7773 : aSub[SW_LATIN].SetName( rFont.GetFamilyName() );
450 7773 : aSub[SW_LATIN].SetStyleName( rFont.GetStyleName() );
451 7773 : aSub[SW_LATIN].SetPitch( rFont.GetPitch() );
452 7773 : aSub[SW_LATIN].SetCharSet( rFont.GetCharSet() );
453 7773 : aSub[SW_LATIN].SvxFont::SetPropr( 100 ); // 100% der FontSize
454 7773 : Size aTmpSize = aSub[SW_LATIN].aSize;
455 7773 : aTmpSize.Height() = pAttrSet->GetSize().GetHeight();
456 7773 : aSub[SW_LATIN].SetSize( aTmpSize );
457 7773 : aSub[SW_LATIN].SetItalic( pAttrSet->GetPosture().GetPosture() );
458 7773 : aSub[SW_LATIN].SetWeight( pAttrSet->GetWeight().GetWeight() );
459 7773 : aSub[SW_LATIN].SetLanguage( pAttrSet->GetLanguage().GetLanguage() );
460 : }
461 :
462 : {
463 7773 : const SvxFontItem& rFont = pAttrSet->GetCJKFont();
464 7773 : aSub[SW_CJK].SetFamily( rFont.GetFamily() );
465 7773 : aSub[SW_CJK].SetName( rFont.GetFamilyName() );
466 7773 : aSub[SW_CJK].SetStyleName( rFont.GetStyleName() );
467 7773 : aSub[SW_CJK].SetPitch( rFont.GetPitch() );
468 7773 : aSub[SW_CJK].SetCharSet( rFont.GetCharSet() );
469 7773 : aSub[SW_CJK].SvxFont::SetPropr( 100 ); // 100% der FontSize
470 7773 : Size aTmpSize = aSub[SW_CJK].aSize;
471 7773 : aTmpSize.Height() = pAttrSet->GetCJKSize().GetHeight();
472 7773 : aSub[SW_CJK].SetSize( aTmpSize );
473 7773 : aSub[SW_CJK].SetItalic( pAttrSet->GetCJKPosture().GetPosture() );
474 7773 : aSub[SW_CJK].SetWeight( pAttrSet->GetCJKWeight().GetWeight() );
475 7773 : LanguageType eNewLang = pAttrSet->GetCJKLanguage().GetLanguage();
476 7773 : aSub[SW_CJK].SetLanguage( eNewLang );
477 7773 : aSub[SW_LATIN].SetCJKContextLanguage( eNewLang );
478 7773 : aSub[SW_CJK].SetCJKContextLanguage( eNewLang );
479 7773 : aSub[SW_CTL].SetCJKContextLanguage( eNewLang );
480 : }
481 :
482 : {
483 7773 : const SvxFontItem& rFont = pAttrSet->GetCTLFont();
484 7773 : aSub[SW_CTL].SetFamily( rFont.GetFamily() );
485 7773 : aSub[SW_CTL].SetName( rFont.GetFamilyName() );
486 7773 : aSub[SW_CTL].SetStyleName( rFont.GetStyleName() );
487 7773 : aSub[SW_CTL].SetPitch( rFont.GetPitch() );
488 7773 : aSub[SW_CTL].SetCharSet( rFont.GetCharSet() );
489 7773 : aSub[SW_CTL].SvxFont::SetPropr( 100 ); // 100% der FontSize
490 7773 : Size aTmpSize = aSub[SW_CTL].aSize;
491 7773 : aTmpSize.Height() = pAttrSet->GetCTLSize().GetHeight();
492 7773 : aSub[SW_CTL].SetSize( aTmpSize );
493 7773 : aSub[SW_CTL].SetItalic( pAttrSet->GetCTLPosture().GetPosture() );
494 7773 : aSub[SW_CTL].SetWeight( pAttrSet->GetCTLWeight().GetWeight() );
495 7773 : aSub[SW_CTL].SetLanguage( pAttrSet->GetCTLLanguage().GetLanguage() );
496 : }
497 :
498 7773 : const FontUnderline eUnderline = pAttrSet->GetUnderline().GetLineStyle();
499 7773 : if ( pAttrSet->GetCharHidden().GetValue() )
500 175 : SetUnderline( UNDERLINE_DOTTED );
501 : else
502 7598 : SetUnderline( eUnderline );
503 7773 : SetUnderColor( pAttrSet->GetUnderline().GetColor() );
504 7773 : SetOverline( pAttrSet->GetOverline().GetLineStyle() );
505 7773 : SetOverColor( pAttrSet->GetOverline().GetColor() );
506 7773 : SetEmphasisMark( pAttrSet->GetEmphasisMark().GetEmphasisMark() );
507 7773 : SetStrikeout( pAttrSet->GetCrossedOut().GetStrikeout() );
508 7773 : SetColor( pAttrSet->GetColor().GetValue() );
509 7773 : SetTransparent( sal_True );
510 7773 : SetAlign( ALIGN_BASELINE );
511 7773 : SetOutline( pAttrSet->GetContour().GetValue() );
512 7773 : SetShadow( pAttrSet->GetShadowed().GetValue() );
513 7773 : SetPropWidth( pAttrSet->GetCharScaleW().GetValue() );
514 7773 : SetRelief( (FontRelief)pAttrSet->GetCharRelief().GetValue() );
515 7773 : if( pAttrSet->GetAutoKern().GetValue() )
516 : {
517 4955 : SetAutoKern( ( !pIDocumentSettingAccess ||
518 4955 : !pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION) ) ?
519 : KERNING_FONTSPECIFIC :
520 9901 : KERNING_ASIAN );
521 : }
522 : else
523 2818 : SetAutoKern( 0 );
524 7773 : SetWordLineMode( pAttrSet->GetWordLineMode().GetValue() );
525 7773 : const SvxEscapementItem &rEsc = pAttrSet->GetEscapement();
526 7773 : SetEscapement( rEsc.GetEsc() );
527 7773 : if( aSub[SW_LATIN].IsEsc() )
528 1893 : SetProportion( rEsc.GetProp() );
529 7773 : SetCaseMap( pAttrSet->GetCaseMap().GetCaseMap() );
530 7773 : SetFixKerning( pAttrSet->GetKerning().GetValue() );
531 : const SfxPoolItem* pItem;
532 7773 : if( SFX_ITEM_SET == pAttrSet->GetItemState( RES_CHRATR_BACKGROUND,
533 7773 : sal_True, &pItem ))
534 1601 : pBackColor = new Color( ((SvxBrushItem*)pItem)->GetColor() );
535 : else
536 6172 : pBackColor = NULL;
537 7773 : const SvxTwoLinesItem& rTwoLinesItem = pAttrSet->Get2Lines();
538 7773 : if ( ! rTwoLinesItem.GetValue() )
539 6816 : SetVertical( pAttrSet->GetCharRotate().GetValue() );
540 : else
541 957 : SetVertical( 0 );
542 7773 : if( pIDocumentSettingAccess && pIDocumentSettingAccess->get( IDocumentSettingAccess::SMALL_CAPS_PERCENTAGE_66 ))
543 : {
544 141 : aSub[ SW_LATIN ].smallCapsPercentage66 = true;
545 141 : aSub[ SW_CJK ].smallCapsPercentage66 = true;
546 141 : aSub[ SW_CTL ].smallCapsPercentage66 = true;
547 : }
548 7773 : }
549 :
550 331899 : SwSubFont& SwSubFont::operator=( const SwSubFont &rFont )
551 : {
552 331899 : SvxFont::operator=( rFont );
553 331899 : pMagic = rFont.pMagic;
554 331899 : nFntIndex = rFont.nFntIndex;
555 331899 : nOrgHeight = rFont.nOrgHeight;
556 331899 : nOrgAscent = rFont.nOrgAscent;
557 331899 : nPropWidth = rFont.nPropWidth;
558 331899 : aSize = rFont.aSize;
559 331899 : smallCapsPercentage66 = rFont.smallCapsPercentage66;
560 331899 : return *this;
561 : }
562 :
563 5885 : SwFont& SwFont::operator=( const SwFont &rFont )
564 : {
565 5885 : aSub[SW_LATIN] = rFont.aSub[SW_LATIN];
566 5885 : aSub[SW_CJK] = rFont.aSub[SW_CJK];
567 5885 : aSub[SW_CTL] = rFont.aSub[SW_CTL];
568 5885 : nActual = rFont.nActual;
569 5885 : delete pBackColor;
570 5885 : pBackColor = rFont.pBackColor ? new Color( *rFont.pBackColor ) : NULL;
571 5885 : aUnderColor = rFont.GetUnderColor();
572 5885 : aOverColor = rFont.GetOverColor();
573 5885 : nToxCnt = 0;
574 5885 : nRefCnt = 0;
575 5885 : m_nMetaCount = 0;
576 5885 : bFntChg = rFont.bFntChg;
577 5885 : bOrgChg = rFont.bOrgChg;
578 5885 : bPaintBlank = rFont.bPaintBlank;
579 5885 : bPaintWrong = sal_False;
580 5885 : bURL = rFont.bURL;
581 5885 : bGreyWave = rFont.bGreyWave;
582 5885 : bNoColReplace = rFont.bNoColReplace;
583 5885 : bNoHyph = rFont.bNoHyph;
584 5885 : bBlink = rFont.bBlink;
585 5885 : return *this;
586 : }
587 :
588 : /*************************************************************************
589 : * SwFont::GoMagic()
590 : *************************************************************************/
591 :
592 4570 : void SwFont::GoMagic( ViewShell *pSh, sal_uInt8 nWhich )
593 : {
594 : SwFntAccess aFntAccess( aSub[nWhich].pMagic, aSub[nWhich].nFntIndex,
595 4570 : &aSub[nWhich], pSh, sal_True );
596 4570 : }
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 147028 : sal_Bool SwSubFont::ChgFnt( ViewShell *pSh, OutputDevice& rOut )
613 : {
614 147028 : if ( pLastFont )
615 145619 : pLastFont->Unlock();
616 147028 : SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh, sal_True );
617 : SV_STAT( nChangeFont );
618 :
619 147028 : pLastFont = aFntAccess.Get();
620 :
621 147028 : pLastFont->SetDevFont( pSh, rOut );
622 :
623 147028 : pLastFont->Lock();
624 286682 : return UNDERLINE_NONE != GetUnderline() ||
625 286682 : UNDERLINE_NONE != GetOverline() ||
626 286682 : STRIKEOUT_NONE != GetStrikeout();
627 : }
628 :
629 : /*************************************************************************
630 : * SwFont::ChgPhysFnt()
631 : *************************************************************************/
632 :
633 102052 : void SwFont::ChgPhysFnt( ViewShell *pSh, OutputDevice& rOut )
634 : {
635 102052 : if( bOrgChg && aSub[nActual].IsEsc() )
636 : {
637 3483 : const sal_uInt8 nOldProp = aSub[nActual].GetPropr();
638 3483 : SetProportion( 100 );
639 3483 : ChgFnt( pSh, rOut );
640 : SwFntAccess aFntAccess( aSub[nActual].pMagic, aSub[nActual].nFntIndex,
641 3483 : &aSub[nActual], pSh );
642 3483 : aSub[nActual].nOrgHeight = aFntAccess.Get()->GetFontHeight( pSh, rOut );
643 3483 : aSub[nActual].nOrgAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
644 3483 : SetProportion( nOldProp );
645 3483 : bOrgChg = sal_False;
646 : }
647 :
648 102052 : if( bFntChg )
649 : {
650 102051 : ChgFnt( pSh, rOut );
651 102051 : bFntChg = bOrgChg;
652 : }
653 102052 : if( rOut.GetTextLineColor() != aUnderColor )
654 178 : rOut.SetTextLineColor( aUnderColor );
655 102052 : if( rOut.GetOverlineColor() != aOverColor )
656 102 : rOut.SetOverlineColor( aOverColor );
657 102052 : }
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 3530 : sal_uInt16 SwSubFont::CalcEscHeight( const sal_uInt16 nOldHeight,
668 : const sal_uInt16 nOldAscent ) const
669 : {
670 6762 : if( DFLT_ESC_AUTO_SUPER != GetEscapement() &&
671 3232 : DFLT_ESC_AUTO_SUB != GetEscapement() )
672 : {
673 3222 : long nDescent = nOldHeight - nOldAscent -
674 3222 : ( (long) nOrgHeight * GetEscapement() ) / 100L;
675 : const sal_uInt16 nDesc = ( nDescent>0 ) ? std::max ( sal_uInt16(nDescent),
676 3222 : sal_uInt16(nOrgHeight - nOrgAscent) ) : nOrgHeight - nOrgAscent;
677 3222 : return ( nDesc + CalcEscAscent( nOldAscent ) );
678 : }
679 308 : return nOrgHeight;
680 : }
681 :
682 10 : short SwSubFont::_CheckKerning( )
683 : {
684 10 : short nKernx = - short( Font::GetSize().Height() / 6 );
685 :
686 10 : if ( nKernx < GetFixKerning() )
687 10 : return GetFixKerning();
688 0 : return nKernx;
689 : }
690 :
691 : /*************************************************************************
692 : * SwSubFont::GetAscent()
693 : *************************************************************************/
694 :
695 50794 : sal_uInt16 SwSubFont::GetAscent( ViewShell *pSh, const OutputDevice& rOut )
696 : {
697 : sal_uInt16 nAscent;
698 50794 : SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
699 50794 : nAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
700 50794 : if( GetEscapement() )
701 1367 : nAscent = CalcEscAscent( nAscent );
702 50794 : return nAscent;
703 : }
704 :
705 : /*************************************************************************
706 : * SwSubFont::GetHeight()
707 : *************************************************************************/
708 :
709 63488 : sal_uInt16 SwSubFont::GetHeight( ViewShell *pSh, const OutputDevice& rOut )
710 : {
711 : SV_STAT( nGetTextSize );
712 63488 : SwFntAccess aFntAccess( pMagic, nFntIndex, this, pSh );
713 63488 : const sal_uInt16 nHeight = aFntAccess.Get()->GetFontHeight( pSh, rOut );
714 63488 : if ( GetEscapement() )
715 : {
716 3246 : const sal_uInt16 nAscent = aFntAccess.Get()->GetFontAscent( pSh, rOut );
717 3246 : return CalcEscHeight( nHeight, nAscent ); // + nLeading;
718 : }
719 60242 : return nHeight; // + nLeading;
720 : }
721 :
722 : /*************************************************************************
723 : * SwSubFont::_GetTxtSize()
724 : *************************************************************************/
725 25069 : Size SwSubFont::_GetTxtSize( SwDrawTextInfo& rInf )
726 : {
727 : // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber
728 : // sicher ist sicher ...
729 50129 : if ( !pLastFont || pLastFont->GetOwner()!=pMagic ||
730 25060 : !IsSameInstance( rInf.GetpOut()->GetFont() ) )
731 23131 : ChgFnt( rInf.GetShell(), rInf.GetOut() );
732 :
733 25069 : SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
734 :
735 25069 : Size aTxtSize;
736 25069 : xub_StrLen nLn = ( rInf.GetLen() == STRING_LEN ? rInf.GetText().getLength()
737 25069 : : rInf.GetLen() );
738 25069 : rInf.SetLen( nLn );
739 25069 : if( IsCapital() && nLn )
740 15 : aTxtSize = GetCapitalSize( rInf );
741 : else
742 : {
743 : SV_STAT( nGetTextSize );
744 25054 : long nOldKern = rInf.GetKern();
745 25054 : const XubString &rOldTxt = rInf.GetText();
746 25054 : rInf.SetKern( CheckKerning() );
747 25054 : if ( !IsCaseMap() )
748 24891 : aTxtSize = pLastFont->GetTextSize( rInf );
749 : else
750 : {
751 163 : String aTmp = CalcCaseMap( rInf.GetText() );
752 326 : const XubString &rOldStr = rInf.GetText();
753 163 : bool bCaseMapLengthDiffers(aTmp.Len() != rOldStr.Len());
754 :
755 163 : 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 163 : rInf.SetText( aTmp );
778 163 : aTxtSize = pLastFont->GetTextSize( rInf );
779 : }
780 :
781 326 : rInf.SetText( rOldStr );
782 : }
783 25054 : rInf.SetKern( nOldKern );
784 25054 : rInf.SetText( rOldTxt );
785 : // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch
786 : // hochgestellt, muss seine effektive Hoehe melden.
787 25054 : if( GetEscapement() )
788 : {
789 284 : const sal_uInt16 nAscent = pLastFont->GetFontAscent( rInf.GetShell(),
790 568 : rInf.GetOut() );
791 284 : aTxtSize.Height() =
792 284 : (long)CalcEscHeight( (sal_uInt16)aTxtSize.Height(), nAscent);
793 25054 : }
794 : }
795 :
796 25069 : if (1==rInf.GetLen() && CH_TXT_ATR_FIELDSTART==rInf.GetText()[rInf.GetIdx()])
797 : {
798 0 : xub_StrLen nOldIdx(rInf.GetIdx());
799 0 : xub_StrLen nOldLen(rInf.GetLen());
800 0 : 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 25069 : else if (1==rInf.GetLen() && CH_TXT_ATR_FIELDEND==rInf.GetText()[ rInf.GetIdx() ])
809 : {
810 0 : xub_StrLen nOldIdx(rInf.GetIdx());
811 0 : xub_StrLen nOldLen(rInf.GetLen());
812 0 : 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 25069 : return aTxtSize;
822 : }
823 :
824 : /*************************************************************************
825 : * SwSubFont::_DrawText()
826 : *************************************************************************/
827 :
828 11205 : void SwSubFont::_DrawText( SwDrawTextInfo &rInf, const sal_Bool bGrey )
829 : {
830 11205 : rInf.SetGreyWave( bGrey );
831 11205 : xub_StrLen nLn = rInf.GetText().getLength();
832 11205 : if( !rInf.GetLen() || !nLn )
833 11205 : return;
834 11205 : if( STRING_LEN == rInf.GetLen() )
835 9 : rInf.SetLen( nLn );
836 :
837 11205 : FontUnderline nOldUnder = UNDERLINE_NONE;
838 11205 : SwUnderlineFont* pUnderFnt = 0;
839 :
840 11205 : if( rInf.GetUnderFnt() )
841 : {
842 44 : nOldUnder = GetUnderline();
843 44 : SetUnderline( UNDERLINE_NONE );
844 44 : pUnderFnt = rInf.GetUnderFnt();
845 : }
846 :
847 11205 : if( !pLastFont || pLastFont->GetOwner()!=pMagic )
848 44 : ChgFnt( rInf.GetShell(), rInf.GetOut() );
849 :
850 11205 : SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
851 :
852 11205 : Point aPos( rInf.GetPos() );
853 :
854 11205 : if( GetEscapement() )
855 195 : CalcEsc( rInf, aPos );
856 :
857 11205 : const Point &rOld = rInf.GetPos();
858 11205 : rInf.SetPos( aPos );
859 11205 : rInf.SetKern( CheckKerning() + rInf.GetSperren() / SPACING_PRECISION_FACTOR );
860 :
861 11205 : if( IsCapital() )
862 0 : DrawCapital( rInf );
863 : else
864 : {
865 : SV_STAT( nDrawText );
866 11205 : if ( !IsCaseMap() )
867 11106 : pLastFont->DrawText( rInf );
868 : else
869 : {
870 99 : const XubString &rOldStr = rInf.GetText();
871 198 : XubString aString( CalcCaseMap( rOldStr ) );
872 99 : bool bCaseMapLengthDiffers(aString.Len() != rOldStr.Len());
873 :
874 99 : 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 99 : rInf.SetText( aString );
897 99 : pLastFont->DrawText( rInf );
898 : }
899 :
900 198 : rInf.SetText( rOldStr );
901 : }
902 : }
903 :
904 11205 : if( pUnderFnt && nOldUnder != UNDERLINE_NONE )
905 : {
906 : static sal_Char const sDoubleSpace[] = " ";
907 44 : Size aFontSize = _GetTxtSize( rInf );
908 44 : const XubString &rOldStr = rInf.GetText();
909 88 : XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
910 :
911 44 : xub_StrLen nOldIdx = rInf.GetIdx();
912 44 : xub_StrLen nOldLen = rInf.GetLen();
913 44 : long nSpace = 0;
914 44 : 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 44 : rInf.SetWidth( sal_uInt16(aFontSize.Width() + nSpace) );
941 44 : rInf.SetText( aStr );
942 44 : rInf.SetIdx( 0 );
943 44 : rInf.SetLen( 2 );
944 44 : SetUnderline( nOldUnder );
945 44 : rInf.SetUnderFnt( 0 );
946 :
947 : // set position for underline font
948 44 : rInf.SetPos( pUnderFnt->GetPos() );
949 :
950 44 : pUnderFnt->GetFont()._DrawStretchText( rInf );
951 :
952 44 : rInf.SetUnderFnt( pUnderFnt );
953 44 : rInf.SetText( rOldStr );
954 44 : rInf.SetIdx( nOldIdx );
955 88 : rInf.SetLen( nOldLen );
956 : }
957 :
958 11205 : rInf.SetPos( rOld );
959 : }
960 :
961 49 : void SwSubFont::_DrawStretchText( SwDrawTextInfo &rInf )
962 : {
963 49 : if( !rInf.GetLen() || !rInf.GetText().getLength() )
964 49 : return;
965 :
966 49 : FontUnderline nOldUnder = UNDERLINE_NONE;
967 49 : SwUnderlineFont* pUnderFnt = 0;
968 :
969 49 : if( rInf.GetUnderFnt() )
970 : {
971 0 : nOldUnder = GetUnderline();
972 0 : SetUnderline( UNDERLINE_NONE );
973 0 : pUnderFnt = rInf.GetUnderFnt();
974 : }
975 :
976 49 : if ( !pLastFont || pLastFont->GetOwner() != pMagic )
977 44 : ChgFnt( rInf.GetShell(), rInf.GetOut() );
978 :
979 49 : SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
980 :
981 49 : rInf.ApplyAutoColor();
982 :
983 49 : Point aPos( rInf.GetPos() );
984 :
985 49 : if( GetEscapement() )
986 0 : CalcEsc( rInf, aPos );
987 :
988 49 : rInf.SetKern( CheckKerning() + rInf.GetSperren() / SPACING_PRECISION_FACTOR );
989 49 : const Point &rOld = rInf.GetPos();
990 49 : rInf.SetPos( aPos );
991 :
992 49 : if( IsCapital() )
993 0 : DrawStretchCapital( rInf );
994 : else
995 : {
996 : SV_STAT( nDrawStretchText );
997 :
998 49 : if ( rInf.GetFrm() )
999 : {
1000 49 : if ( rInf.GetFrm()->IsRightToLeft() )
1001 0 : rInf.GetFrm()->SwitchLTRtoRTL( aPos );
1002 :
1003 49 : if ( rInf.GetFrm()->IsVertical() )
1004 0 : rInf.GetFrm()->SwitchHorizontalToVertical( aPos );
1005 :
1006 49 : rInf.SetPos( aPos );
1007 : }
1008 :
1009 49 : if ( !IsCaseMap() )
1010 98 : rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(),
1011 147 : rInf.GetText(), rInf.GetIdx(), rInf.GetLen() );
1012 : else
1013 0 : rInf.GetOut().DrawStretchText( aPos, rInf.GetWidth(), CalcCaseMap(
1014 0 : rInf.GetText() ), rInf.GetIdx(), rInf.GetLen() );
1015 : }
1016 :
1017 49 : if( pUnderFnt && nOldUnder != UNDERLINE_NONE )
1018 : {
1019 : static sal_Char const sDoubleSpace[] = " ";
1020 0 : const XubString &rOldStr = rInf.GetText();
1021 0 : XubString aStr( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
1022 0 : xub_StrLen nOldIdx = rInf.GetIdx();
1023 0 : xub_StrLen nOldLen = rInf.GetLen();
1024 0 : rInf.SetText( aStr );
1025 0 : rInf.SetIdx( 0 );
1026 0 : rInf.SetLen( 2 );
1027 0 : SetUnderline( nOldUnder );
1028 0 : rInf.SetUnderFnt( 0 );
1029 :
1030 : // set position for underline font
1031 0 : rInf.SetPos( pUnderFnt->GetPos() );
1032 :
1033 0 : pUnderFnt->GetFont()._DrawStretchText( rInf );
1034 :
1035 0 : rInf.SetUnderFnt( pUnderFnt );
1036 0 : rInf.SetText( rOldStr );
1037 0 : rInf.SetIdx( nOldIdx );
1038 0 : rInf.SetLen( nOldLen );
1039 : }
1040 :
1041 49 : rInf.SetPos( rOld );
1042 : }
1043 :
1044 : /*************************************************************************
1045 : * SwSubFont::_GetCrsrOfst()
1046 : *************************************************************************/
1047 :
1048 0 : xub_StrLen SwSubFont::_GetCrsrOfst( SwDrawTextInfo& rInf )
1049 : {
1050 0 : if ( !pLastFont || pLastFont->GetOwner()!=pMagic )
1051 0 : ChgFnt( rInf.GetShell(), rInf.GetOut() );
1052 :
1053 0 : SwDigitModeModifier aDigitModeModifier( rInf.GetOut(), rInf.GetFont()->GetLanguage() );
1054 :
1055 0 : xub_StrLen nLn = rInf.GetLen() == STRING_LEN ? rInf.GetText().getLength()
1056 0 : : rInf.GetLen();
1057 0 : rInf.SetLen( nLn );
1058 0 : xub_StrLen nCrsr = 0;
1059 0 : if( IsCapital() && nLn )
1060 0 : nCrsr = GetCapitalCrsrOfst( rInf );
1061 : else
1062 : {
1063 0 : const XubString &rOldTxt = rInf.GetText();
1064 0 : long nOldKern = rInf.GetKern();
1065 0 : rInf.SetKern( CheckKerning() );
1066 : SV_STAT( nGetTextSize );
1067 0 : if ( !IsCaseMap() )
1068 0 : nCrsr = pLastFont->GetCrsrOfst( rInf );
1069 : else
1070 : {
1071 0 : String aTmp = CalcCaseMap( rInf.GetText() );
1072 0 : rInf.SetText( aTmp );
1073 0 : nCrsr = pLastFont->GetCrsrOfst( rInf );
1074 : }
1075 0 : rInf.SetKern( nOldKern );
1076 0 : rInf.SetText( rOldTxt );
1077 : }
1078 0 : return nCrsr;
1079 : }
1080 :
1081 : /*************************************************************************
1082 : * SwSubFont::CalcEsc()
1083 : *************************************************************************/
1084 :
1085 195 : void SwSubFont::CalcEsc( SwDrawTextInfo& rInf, Point& rPos )
1086 : {
1087 : long nOfst;
1088 :
1089 : sal_uInt16 nDir = UnMapDirection(
1090 195 : GetOrientation(), rInf.GetFrm() && rInf.GetFrm()->IsVertical() );
1091 :
1092 195 : switch ( GetEscapement() )
1093 : {
1094 : case DFLT_ESC_AUTO_SUB :
1095 0 : nOfst = nOrgHeight - nOrgAscent -
1096 0 : pLastFont->GetFontHeight( rInf.GetShell(), rInf.GetOut() ) +
1097 0 : pLastFont->GetFontAscent( rInf.GetShell(), rInf.GetOut() );
1098 :
1099 0 : switch ( nDir )
1100 : {
1101 : case 0 :
1102 0 : rPos.Y() += nOfst;
1103 0 : break;
1104 : case 900 :
1105 0 : rPos.X() += nOfst;
1106 0 : break;
1107 : case 2700 :
1108 0 : rPos.X() -= nOfst;
1109 0 : break;
1110 : }
1111 :
1112 0 : break;
1113 : case DFLT_ESC_AUTO_SUPER :
1114 79 : nOfst = pLastFont->GetFontAscent( rInf.GetShell(), rInf.GetOut() ) -
1115 79 : nOrgAscent;
1116 :
1117 :
1118 79 : switch ( nDir )
1119 : {
1120 : case 0 :
1121 79 : rPos.Y() += nOfst;
1122 79 : break;
1123 : case 900 :
1124 0 : rPos.X() += nOfst;
1125 0 : break;
1126 : case 2700 :
1127 0 : rPos.X() -= nOfst;
1128 0 : break;
1129 : }
1130 :
1131 79 : break;
1132 : default :
1133 116 : nOfst = ((long)nOrgHeight * GetEscapement()) / 100L;
1134 :
1135 116 : switch ( nDir )
1136 : {
1137 : case 0 :
1138 116 : rPos.Y() -= nOfst;
1139 116 : break;
1140 : case 900 :
1141 0 : rPos.X() -= nOfst;
1142 0 : break;
1143 : case 2700 :
1144 0 : rPos.X() += nOfst;
1145 0 : break;
1146 : }
1147 : }
1148 195 : }
1149 :
1150 : // used during painting of small capitals
1151 0 : void SwDrawTextInfo::Shift( sal_uInt16 nDir )
1152 : {
1153 : #ifdef DBG_UTIL
1154 : OSL_ENSURE( m_bPos, "DrawTextInfo: Undefined Position" );
1155 : OSL_ENSURE( m_bSize, "DrawTextInfo: Undefined Width" );
1156 : #endif
1157 :
1158 0 : const bool bBidiPor = ( GetFrm() && GetFrm()->IsRightToLeft() ) !=
1159 0 : ( 0 != ( TEXT_LAYOUT_BIDI_RTL & GetpOut()->GetLayoutMode() ) );
1160 :
1161 : nDir = bBidiPor ?
1162 : 1800 :
1163 0 : UnMapDirection( nDir, GetFrm() && GetFrm()->IsVertical() );
1164 :
1165 0 : switch ( nDir )
1166 : {
1167 : case 0 :
1168 0 : m_aPos.X() += GetSize().Width();
1169 0 : break;
1170 : case 900 :
1171 : OSL_ENSURE( m_aPos.Y() >= GetSize().Width(), "Going underground" );
1172 0 : m_aPos.Y() -= GetSize().Width();
1173 0 : break;
1174 : case 1800 :
1175 0 : m_aPos.X() -= GetSize().Width();
1176 0 : break;
1177 : case 2700 :
1178 0 : m_aPos.Y() += GetSize().Width();
1179 0 : break;
1180 : }
1181 0 : }
1182 :
1183 : /*************************************************************************
1184 : * SwUnderlineFont::~SwUnderlineFont
1185 : *
1186 : * Used for the "continuous underline" feature.
1187 : *************************************************************************/
1188 :
1189 43 : SwUnderlineFont::SwUnderlineFont( SwFont& rFnt, const Point& rPoint )
1190 43 : : aPos( rPoint ), pFnt( &rFnt )
1191 : {
1192 43 : };
1193 :
1194 43 : SwUnderlineFont::~SwUnderlineFont()
1195 : {
1196 43 : delete pFnt;
1197 43 : }
1198 :
1199 : //Helper for filters to find true lineheight of a font
1200 0 : long AttrSetToLineHeight( const IDocumentSettingAccess& rIDocumentSettingAccess,
1201 : const SwAttrSet &rSet,
1202 : const OutputDevice &rOut, sal_Int16 nScript)
1203 : {
1204 0 : SwFont aFont(&rSet, &rIDocumentSettingAccess);
1205 : sal_uInt8 nActual;
1206 0 : switch (nScript)
1207 : {
1208 : default:
1209 : case i18n::ScriptType::LATIN:
1210 0 : nActual = SW_LATIN;
1211 0 : break;
1212 : case i18n::ScriptType::ASIAN:
1213 0 : nActual = SW_CJK;
1214 0 : break;
1215 : case i18n::ScriptType::COMPLEX:
1216 0 : nActual = SW_CTL;
1217 0 : break;
1218 : }
1219 0 : aFont.SetActual(nActual);
1220 :
1221 0 : OutputDevice &rMutableOut = const_cast<OutputDevice &>(rOut);
1222 0 : const Font aOldFont(rMutableOut.GetFont());
1223 :
1224 0 : rMutableOut.SetFont(aFont.GetActualFont());
1225 0 : long nHeight = rMutableOut.GetTextHeight();
1226 :
1227 0 : rMutableOut.SetFont(aOldFont);
1228 0 : return nHeight;
1229 99 : }
1230 :
1231 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|