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