1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: swfont.cxx,v $
10 * $Revision: 1.59.24.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
37 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
38 #include <com/sun/star/i18n/ScriptType.hdl>
40 #ifndef _OUTDEV_HXX //autogen
41 #include <vcl/outdev.hxx>
43 #include <unotools/localedatawrapper.hxx>
44 #include <svx/unolingu.hxx>
45 #include <svx/brshitem.hxx>
46 #include <svx/wrlmitem.hxx>
47 #include <svx/blnkitem.hxx>
48 #include <svx/nhypitem.hxx>
49 #include <svx/kernitem.hxx>
50 #include <svx/cmapitem.hxx>
51 #include <svx/langitem.hxx>
52 #include <svx/escpitem.hxx>
53 #include <svx/akrnitem.hxx>
54 #include <svx/shdditem.hxx>
55 #include <svx/charreliefitem.hxx>
56 #ifndef _SVX_CNTRITEM_HXX //autogen
57 #include <svx/cntritem.hxx>
59 #include <svx/colritem.hxx>
60 #include <svx/cscoitem.hxx>
61 #include <svx/crsditem.hxx>
62 #include <svx/udlnitem.hxx>
63 #include <svx/wghtitem.hxx>
64 #include <svx/postitem.hxx>
65 #include <svx/fhgtitem.hxx>
66 #include <svx/fontitem.hxx>
67 #ifndef _SVX_EMPHITEM_HXX //autogen
68 #include <svx/emphitem.hxx>
70 #include <svx/charscaleitem.hxx>
71 #include <svx/charrotateitem.hxx>
72 #include <svx/twolinesitem.hxx>
73 #include <svx/charhiddenitem.hxx>
74 #include <IDocumentSettingAccess.hxx>
75 #include <vcl/window.hxx>
76 #include <charatr.hxx>
77 #include <viewsh.hxx> // Bildschirmabgleich
79 #include <fntcache.hxx> // FontCache
80 #include <txtfrm.hxx> // SwTxtFrm
81 #include <scriptinfo.hxx>
83 #if defined(WIN) || defined(WNT) || defined(PM2)
84 #define FNT_LEADING_HACK
87 #if defined(WIN) || defined(WNT)
96 using namespace ::com::sun::star
;
98 /************************************************************************
99 * Hintergrundbrush setzen, z.B. bei Zeichenvorlagen
100 ***********************************************************************/
102 void SwFont::SetBackColor( Color
* pNewColor
)
105 pBackColor
= pNewColor
;
107 aSub
[SW_LATIN
].pMagic
= aSub
[SW_CJK
].pMagic
= aSub
[SW_CTL
].pMagic
= 0;
110 // maps directions for vertical layout
111 USHORT
MapDirection( USHORT nDir
, const BOOL bVertFormat
)
126 #if OSL_DEBUG_LEVEL > 1
128 ASSERT( sal_False
, "Unsupported direction" );
136 // maps the absolute direction set at the font to its logical conterpart
137 // in the rotated environment
138 USHORT
UnMapDirection( USHORT nDir
, const BOOL bVertFormat
)
153 #if OSL_DEBUG_LEVEL > 1
155 ASSERT( sal_False
, "Unsupported direction" );
163 USHORT
SwFont::GetOrientation( const BOOL bVertFormat
) const
165 return UnMapDirection( aSub
[nActual
].GetOrientation(), bVertFormat
);
168 void SwFont::SetVertical( USHORT nDir
, const BOOL bVertFormat
)
170 // map direction if frame has vertical layout
171 nDir
= MapDirection( nDir
, bVertFormat
);
173 if( nDir
!= aSub
[0].GetOrientation() )
176 aSub
[0].SetVertical( nDir
, bVertFormat
);
177 aSub
[1].SetVertical( nDir
, bVertFormat
|| nDir
> 1000 );
178 aSub
[2].SetVertical( nDir
, bVertFormat
);
182 /*************************************************************************
184 frEsc: Fraction, Grad des Escapements
185 Esc = resultierendes Escapement
186 A1 = Original-Ascent (nOrgAscent)
187 A2 = verkleinerter Ascent (nEscAscent)
188 Ax = resultierender Ascent (GetAscent())
189 H1 = Original-Hoehe (nOrgHeight)
190 H2 = verkleinerter Hoehe (nEscHeight)
191 Hx = resultierender Hoehe (GetHeight())
192 Bx = resultierende Baseline fuer die Textausgabe (CalcPos())
205 Hx = A1 + Esc + (H2 - A2);
208 *************************************************************************/
210 /*************************************************************************
211 * SwSubFont::CalcEscAscent( const USHORT nOldAscent )
212 *************************************************************************/
214 // nEsc ist der Prozentwert
215 USHORT
SwSubFont::CalcEscAscent( const USHORT nOldAscent
) const
217 if( DFLT_ESC_AUTO_SUPER
!= GetEscapement() &&
218 DFLT_ESC_AUTO_SUB
!= GetEscapement() )
220 const long nAscent
= nOldAscent
+
221 ( (long) nOrgHeight
* GetEscapement() ) / 100L;
223 return ( Max( USHORT (nAscent
), nOrgAscent
));
228 /*************************************************************************
229 * SwFont::SetDiffFnt()
230 *************************************************************************/
232 void SwFont::SetDiffFnt( const SfxItemSet
*pAttrSet
,
233 const IDocumentSettingAccess
*pIDocumentSettingAccess
)
240 const SfxPoolItem
* pItem
;
241 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_FONT
,
244 const SvxFontItem
*pFont
= (const SvxFontItem
*)pItem
;
245 aSub
[SW_LATIN
].SetFamily( pFont
->GetFamily() );
246 aSub
[SW_LATIN
].Font::SetName( pFont
->GetFamilyName() );
247 aSub
[SW_LATIN
].Font::SetStyleName( pFont
->GetStyleName() );
248 aSub
[SW_LATIN
].Font::SetPitch( pFont
->GetPitch() );
249 aSub
[SW_LATIN
].Font::SetCharSet( pFont
->GetCharSet() );
251 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_FONTSIZE
,
254 const SvxFontHeightItem
*pHeight
= (const SvxFontHeightItem
*)pItem
;
255 aSub
[SW_LATIN
].SvxFont::SetPropr( 100 );
256 aSub
[SW_LATIN
].aSize
= aSub
[SW_LATIN
].Font::GetSize();
257 Size aTmpSize
= aSub
[SW_LATIN
].aSize
;
258 aTmpSize
.Height() = pHeight
->GetHeight();
259 aSub
[SW_LATIN
].SetSize( aTmpSize
);
261 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_POSTURE
,
263 aSub
[SW_LATIN
].Font::SetItalic( ((SvxPostureItem
*)pItem
)->GetPosture() );
264 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_WEIGHT
,
266 aSub
[SW_LATIN
].Font::SetWeight( ((SvxWeightItem
*)pItem
)->GetWeight() );
267 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_LANGUAGE
,
269 aSub
[SW_LATIN
].SetLanguage( ((SvxLanguageItem
*)pItem
)->GetLanguage() );
271 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CJK_FONT
,
274 const SvxFontItem
*pFont
= (const SvxFontItem
*)pItem
;
275 aSub
[SW_CJK
].SetFamily( pFont
->GetFamily() );
276 aSub
[SW_CJK
].Font::SetName( pFont
->GetFamilyName() );
277 aSub
[SW_CJK
].Font::SetStyleName( pFont
->GetStyleName() );
278 aSub
[SW_CJK
].Font::SetPitch( pFont
->GetPitch() );
279 aSub
[SW_CJK
].Font::SetCharSet( pFont
->GetCharSet() );
281 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CJK_FONTSIZE
,
284 const SvxFontHeightItem
*pHeight
= (const SvxFontHeightItem
*)pItem
;
285 aSub
[SW_CJK
].SvxFont::SetPropr( 100 );
286 aSub
[SW_CJK
].aSize
= aSub
[SW_CJK
].Font::GetSize();
287 Size aTmpSize
= aSub
[SW_CJK
].aSize
;
288 aTmpSize
.Height() = pHeight
->GetHeight();
289 aSub
[SW_CJK
].SetSize( aTmpSize
);
291 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CJK_POSTURE
,
293 aSub
[SW_CJK
].Font::SetItalic( ((SvxPostureItem
*)pItem
)->GetPosture() );
294 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CJK_WEIGHT
,
296 aSub
[SW_CJK
].Font::SetWeight( ((SvxWeightItem
*)pItem
)->GetWeight() );
297 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CJK_LANGUAGE
,
300 LanguageType eNewLang
= ((SvxLanguageItem
*)pItem
)->GetLanguage();
301 aSub
[SW_CJK
].SetLanguage( eNewLang
);
302 aSub
[SW_LATIN
].SetCJKContextLanguage( eNewLang
);
303 aSub
[SW_CJK
].SetCJKContextLanguage( eNewLang
);
304 aSub
[SW_CTL
].SetCJKContextLanguage( eNewLang
);
307 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CTL_FONT
,
310 const SvxFontItem
*pFont
= (const SvxFontItem
*)pItem
;
311 aSub
[SW_CTL
].SetFamily( pFont
->GetFamily() );
312 aSub
[SW_CTL
].Font::SetName( pFont
->GetFamilyName() );
313 aSub
[SW_CTL
].Font::SetStyleName( pFont
->GetStyleName() );
314 aSub
[SW_CTL
].Font::SetPitch( pFont
->GetPitch() );
315 aSub
[SW_CTL
].Font::SetCharSet( pFont
->GetCharSet() );
317 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CTL_FONTSIZE
,
320 const SvxFontHeightItem
*pHeight
= (const SvxFontHeightItem
*)pItem
;
321 aSub
[SW_CTL
].SvxFont::SetPropr( 100 );
322 aSub
[SW_CTL
].aSize
= aSub
[SW_CTL
].Font::GetSize();
323 Size aTmpSize
= aSub
[SW_CTL
].aSize
;
324 aTmpSize
.Height() = pHeight
->GetHeight();
325 aSub
[SW_CTL
].SetSize( aTmpSize
);
327 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CTL_POSTURE
,
329 aSub
[SW_CTL
].Font::SetItalic( ((SvxPostureItem
*)pItem
)->GetPosture() );
330 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CTL_WEIGHT
,
332 aSub
[SW_CTL
].Font::SetWeight( ((SvxWeightItem
*)pItem
)->GetWeight() );
333 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CTL_LANGUAGE
,
335 aSub
[SW_CTL
].SetLanguage( ((SvxLanguageItem
*)pItem
)->GetLanguage() );
337 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_UNDERLINE
,
340 SetUnderline( ((SvxUnderlineItem
*)pItem
)->GetLineStyle() );
341 SetUnderColor( ((SvxUnderlineItem
*)pItem
)->GetColor() );
343 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_OVERLINE
,
346 SetOverline( ((SvxOverlineItem
*)pItem
)->GetLineStyle() );
347 SetOverColor( ((SvxOverlineItem
*)pItem
)->GetColor() );
349 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CROSSEDOUT
,
351 SetStrikeout( ((SvxCrossedOutItem
*)pItem
)->GetStrikeout() );
352 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_COLOR
,
354 SetColor( ((SvxColorItem
*)pItem
)->GetValue() );
355 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_EMPHASIS_MARK
,
357 SetEmphasisMark( ((SvxEmphasisMarkItem
*)pItem
)->GetEmphasisMark() );
359 SetTransparent( TRUE
);
360 SetAlign( ALIGN_BASELINE
);
361 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CONTOUR
,
363 SetOutline( ((SvxContourItem
*)pItem
)->GetValue() );
364 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_SHADOWED
,
366 SetShadow( ((SvxShadowedItem
*)pItem
)->GetValue() );
367 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_RELIEF
,
369 SetRelief( (FontRelief
)((SvxCharReliefItem
*)pItem
)->GetValue() );
370 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_SHADOWED
,
372 SetPropWidth(((SvxShadowedItem
*)pItem
)->GetValue() ? 50 : 100 );
373 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_AUTOKERN
,
376 if( ((SvxAutoKernItem
*)pItem
)->GetValue() )
378 SetAutoKern( ( !pIDocumentSettingAccess
||
379 !pIDocumentSettingAccess
->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION
) ) ?
380 KERNING_FONTSPECIFIC
:
386 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_WORDLINEMODE
,
388 SetWordLineMode( ((SvxWordLineModeItem
*)pItem
)->GetValue() );
390 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_ESCAPEMENT
,
393 const SvxEscapementItem
*pEsc
= (const SvxEscapementItem
*)pItem
;
394 SetEscapement( pEsc
->GetEsc() );
395 if( aSub
[SW_LATIN
].IsEsc() )
396 SetProportion( pEsc
->GetProp() );
398 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_CASEMAP
,
400 SetCaseMap( ((SvxCaseMapItem
*)pItem
)->GetCaseMap() );
401 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_KERNING
,
403 SetFixKerning( ((SvxKerningItem
*)pItem
)->GetValue() );
404 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_NOHYPHEN
,
406 SetNoHyph( ((SvxNoHyphenItem
*)pItem
)->GetValue() );
407 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_BLINK
,
409 SetBlink( ((SvxBlinkItem
*)pItem
)->GetValue() );
410 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_ROTATE
,
412 SetVertical( ((SvxCharRotateItem
*)pItem
)->GetValue() );
413 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_BACKGROUND
,
415 pBackColor
= new Color( ((SvxBrushItem
*)pItem
)->GetColor() );
418 const SfxPoolItem
* pTwoLinesItem
= 0;
420 pAttrSet
->GetItemState( RES_CHRATR_TWO_LINES
, TRUE
, &pTwoLinesItem
))
421 if ( ((SvxTwoLinesItem
*)pTwoLinesItem
)->GetValue() )
432 ASSERT( aSub
[SW_LATIN
].IsTransparent(), "SwFont: Transparent revolution" );
435 /*************************************************************************
437 *************************************************************************/
439 SwFont::SwFont( const SwFont
&rFont
)
441 aSub
[SW_LATIN
] = rFont
.aSub
[SW_LATIN
];
442 aSub
[SW_CJK
] = rFont
.aSub
[SW_CJK
];
443 aSub
[SW_CTL
] = rFont
.aSub
[SW_CTL
];
444 nActual
= rFont
.nActual
;
445 pBackColor
= rFont
.pBackColor
? new Color( *rFont
.pBackColor
) : NULL
;
446 aUnderColor
= rFont
.GetUnderColor();
447 aOverColor
= rFont
.GetOverColor();
448 nToxCnt
= nRefCnt
= 0;
449 bFntChg
= rFont
.bFntChg
;
450 bOrgChg
= rFont
.bOrgChg
;
451 bPaintBlank
= rFont
.bPaintBlank
;
454 bGreyWave
= rFont
.bGreyWave
;
455 bNoColReplace
= rFont
.bNoColReplace
;
456 bNoHyph
= rFont
.bNoHyph
;
457 bBlink
= rFont
.bBlink
;
460 SwFont::SwFont( const SwAttrSet
* pAttrSet
,
461 const IDocumentSettingAccess
* pIDocumentSettingAccess
)
464 nToxCnt
= nRefCnt
= 0;
469 bNoColReplace
= FALSE
;
470 bNoHyph
= pAttrSet
->GetNoHyphenHere().GetValue();
471 bBlink
= pAttrSet
->GetBlink().GetValue();
474 const SvxFontItem
& rFont
= pAttrSet
->GetFont();
475 aSub
[SW_LATIN
].SetFamily( rFont
.GetFamily() );
476 aSub
[SW_LATIN
].SetName( rFont
.GetFamilyName() );
477 aSub
[SW_LATIN
].SetStyleName( rFont
.GetStyleName() );
478 aSub
[SW_LATIN
].SetPitch( rFont
.GetPitch() );
479 aSub
[SW_LATIN
].SetCharSet( rFont
.GetCharSet() );
480 aSub
[SW_LATIN
].SvxFont::SetPropr( 100 ); // 100% der FontSize
481 Size aTmpSize
= aSub
[SW_LATIN
].aSize
;
482 aTmpSize
.Height() = pAttrSet
->GetSize().GetHeight();
483 aSub
[SW_LATIN
].SetSize( aTmpSize
);
484 aSub
[SW_LATIN
].SetItalic( pAttrSet
->GetPosture().GetPosture() );
485 aSub
[SW_LATIN
].SetWeight( pAttrSet
->GetWeight().GetWeight() );
486 aSub
[SW_LATIN
].SetLanguage( pAttrSet
->GetLanguage().GetLanguage() );
490 const SvxFontItem
& rFont
= pAttrSet
->GetCJKFont();
491 aSub
[SW_CJK
].SetFamily( rFont
.GetFamily() );
492 aSub
[SW_CJK
].SetName( rFont
.GetFamilyName() );
493 aSub
[SW_CJK
].SetStyleName( rFont
.GetStyleName() );
494 aSub
[SW_CJK
].SetPitch( rFont
.GetPitch() );
495 aSub
[SW_CJK
].SetCharSet( rFont
.GetCharSet() );
496 aSub
[SW_CJK
].SvxFont::SetPropr( 100 ); // 100% der FontSize
497 Size aTmpSize
= aSub
[SW_CJK
].aSize
;
498 aTmpSize
.Height() = pAttrSet
->GetCJKSize().GetHeight();
499 aSub
[SW_CJK
].SetSize( aTmpSize
);
500 aSub
[SW_CJK
].SetItalic( pAttrSet
->GetCJKPosture().GetPosture() );
501 aSub
[SW_CJK
].SetWeight( pAttrSet
->GetCJKWeight().GetWeight() );
502 LanguageType eNewLang
= pAttrSet
->GetCJKLanguage().GetLanguage();
503 aSub
[SW_CJK
].SetLanguage( eNewLang
);
504 aSub
[SW_LATIN
].SetCJKContextLanguage( eNewLang
);
505 aSub
[SW_CJK
].SetCJKContextLanguage( eNewLang
);
506 aSub
[SW_CTL
].SetCJKContextLanguage( eNewLang
);
510 const SvxFontItem
& rFont
= pAttrSet
->GetCTLFont();
511 aSub
[SW_CTL
].SetFamily( rFont
.GetFamily() );
512 aSub
[SW_CTL
].SetName( rFont
.GetFamilyName() );
513 aSub
[SW_CTL
].SetStyleName( rFont
.GetStyleName() );
514 aSub
[SW_CTL
].SetPitch( rFont
.GetPitch() );
515 aSub
[SW_CTL
].SetCharSet( rFont
.GetCharSet() );
516 aSub
[SW_CTL
].SvxFont::SetPropr( 100 ); // 100% der FontSize
517 Size aTmpSize
= aSub
[SW_CTL
].aSize
;
518 aTmpSize
.Height() = pAttrSet
->GetCTLSize().GetHeight();
519 aSub
[SW_CTL
].SetSize( aTmpSize
);
520 aSub
[SW_CTL
].SetItalic( pAttrSet
->GetCTLPosture().GetPosture() );
521 aSub
[SW_CTL
].SetWeight( pAttrSet
->GetCTLWeight().GetWeight() );
522 aSub
[SW_CTL
].SetLanguage( pAttrSet
->GetCTLLanguage().GetLanguage() );
525 const FontUnderline eUnderline
= pAttrSet
->GetUnderline().GetLineStyle();
526 if ( pAttrSet
->GetCharHidden().GetValue() )
527 SetUnderline( UNDERLINE_DOTTED
);
529 SetUnderline( eUnderline
);
530 SetUnderColor( pAttrSet
->GetUnderline().GetColor() );
531 SetOverline( pAttrSet
->GetOverline().GetLineStyle() );
532 SetOverColor( pAttrSet
->GetOverline().GetColor() );
533 SetEmphasisMark( pAttrSet
->GetEmphasisMark().GetEmphasisMark() );
534 SetStrikeout( pAttrSet
->GetCrossedOut().GetStrikeout() );
535 SetColor( pAttrSet
->GetColor().GetValue() );
536 SetTransparent( TRUE
);
537 SetAlign( ALIGN_BASELINE
);
538 SetOutline( pAttrSet
->GetContour().GetValue() );
539 SetShadow( pAttrSet
->GetShadowed().GetValue() );
540 SetPropWidth( pAttrSet
->GetCharScaleW().GetValue() );
541 SetRelief( (FontRelief
)pAttrSet
->GetCharRelief().GetValue() );
542 if( pAttrSet
->GetAutoKern().GetValue() )
544 SetAutoKern( ( !pIDocumentSettingAccess
||
545 !pIDocumentSettingAccess
->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION
) ) ?
546 KERNING_FONTSPECIFIC
:
551 SetWordLineMode( pAttrSet
->GetWordLineMode().GetValue() );
552 const SvxEscapementItem
&rEsc
= pAttrSet
->GetEscapement();
553 SetEscapement( rEsc
.GetEsc() );
554 if( aSub
[SW_LATIN
].IsEsc() )
555 SetProportion( rEsc
.GetProp() );
556 SetCaseMap( pAttrSet
->GetCaseMap().GetCaseMap() );
557 SetFixKerning( pAttrSet
->GetKerning().GetValue() );
558 const SfxPoolItem
* pItem
;
559 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_BACKGROUND
,
561 pBackColor
= new Color( ((SvxBrushItem
*)pItem
)->GetColor() );
564 const SvxTwoLinesItem
& rTwoLinesItem
= pAttrSet
->Get2Lines();
565 if ( ! rTwoLinesItem
.GetValue() )
566 SetVertical( pAttrSet
->GetCharRotate().GetValue() );
571 SwSubFont
& SwSubFont::operator=( const SwSubFont
&rFont
)
573 SvxFont::operator=( rFont
);
574 pMagic
= rFont
.pMagic
;
575 nFntIndex
= rFont
.nFntIndex
;
576 nOrgHeight
= rFont
.nOrgHeight
;
577 nOrgAscent
= rFont
.nOrgAscent
;
578 nPropWidth
= rFont
.nPropWidth
;
583 SwFont
& SwFont::operator=( const SwFont
&rFont
)
585 aSub
[SW_LATIN
] = rFont
.aSub
[SW_LATIN
];
586 aSub
[SW_CJK
] = rFont
.aSub
[SW_CJK
];
587 aSub
[SW_CTL
] = rFont
.aSub
[SW_CTL
];
588 nActual
= rFont
.nActual
;
590 pBackColor
= rFont
.pBackColor
? new Color( *rFont
.pBackColor
) : NULL
;
591 aUnderColor
= rFont
.GetUnderColor();
592 aOverColor
= rFont
.GetOverColor();
593 nToxCnt
= nRefCnt
= 0;
594 bFntChg
= rFont
.bFntChg
;
595 bOrgChg
= rFont
.bOrgChg
;
596 bPaintBlank
= rFont
.bPaintBlank
;
599 bGreyWave
= rFont
.bGreyWave
;
600 bNoColReplace
= rFont
.bNoColReplace
;
601 bNoHyph
= rFont
.bNoHyph
;
602 bBlink
= rFont
.bBlink
;
606 /*************************************************************************
608 *************************************************************************/
610 void SwFont::GoMagic( ViewShell
*pSh
, BYTE nWhich
)
612 SwFntAccess
aFntAccess( aSub
[nWhich
].pMagic
, aSub
[nWhich
].nFntIndex
,
613 &aSub
[nWhich
], pSh
, TRUE
);
616 /*************************************************************************
617 * SwSubFont::IsSymbol()
618 *************************************************************************/
620 BOOL
SwSubFont::IsSymbol( ViewShell
*pSh
)
622 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
, FALSE
);
623 return aFntAccess
.Get()->IsSymbol();
626 /*************************************************************************
627 * SwSubFont::ChgFnt()
628 *************************************************************************/
630 BOOL
SwSubFont::ChgFnt( ViewShell
*pSh
, OutputDevice
& rOut
)
634 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
, TRUE
);
635 SV_STAT( nChangeFont
);
637 pLastFont
= aFntAccess
.Get();
639 pLastFont
->SetDevFont( pSh
, rOut
);
642 return UNDERLINE_NONE
!= GetUnderline() ||
643 UNDERLINE_NONE
!= GetOverline() ||
644 STRIKEOUT_NONE
!= GetStrikeout();
647 /*************************************************************************
648 * SwFont::ChgPhysFnt()
649 *************************************************************************/
651 void SwFont::ChgPhysFnt( ViewShell
*pSh
, OutputDevice
& rOut
)
653 if( bOrgChg
&& aSub
[nActual
].IsEsc() )
655 const BYTE nOldProp
= aSub
[nActual
].GetPropr();
656 SetProportion( 100 );
658 SwFntAccess
aFntAccess( aSub
[nActual
].pMagic
, aSub
[nActual
].nFntIndex
,
659 &aSub
[nActual
], pSh
);
660 aSub
[nActual
].nOrgHeight
= aFntAccess
.Get()->GetFontHeight( pSh
, rOut
);
661 aSub
[nActual
].nOrgAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
662 SetProportion( nOldProp
);
671 if( rOut
.GetTextLineColor() != aUnderColor
)
672 rOut
.SetTextLineColor( aUnderColor
);
673 if( rOut
.GetOverlineColor() != aOverColor
)
674 rOut
.SetOverlineColor( aOverColor
);
677 /*************************************************************************
678 * SwFont::CalcEscHeight()
679 * Height = MaxAscent + MaxDescent
680 * MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) );
681 * MaxDescent = Max (T1_height-T1_ascent,
682 * T2_height-T2_ascent - (Esc * T1_height)
683 *************************************************************************/
685 USHORT
SwSubFont::CalcEscHeight( const USHORT nOldHeight
,
686 const USHORT nOldAscent
) const
688 if( DFLT_ESC_AUTO_SUPER
!= GetEscapement() &&
689 DFLT_ESC_AUTO_SUB
!= GetEscapement() )
691 long nDescent
= nOldHeight
- nOldAscent
-
692 ( (long) nOrgHeight
* GetEscapement() ) / 100L;
693 const USHORT nDesc
= ( nDescent
>0 ) ? Max ( USHORT(nDescent
),
694 USHORT(nOrgHeight
- nOrgAscent
) ) : nOrgHeight
- nOrgAscent
;
695 return ( nDesc
+ CalcEscAscent( nOldAscent
) );
700 short SwSubFont::_CheckKerning( )
702 short nKernx
= - short( Font::GetSize().Height() / 6 );
704 if ( nKernx
< GetFixKerning() )
705 return GetFixKerning();
709 /*************************************************************************
710 * SwSubFont::GetAscent()
711 *************************************************************************/
713 USHORT
SwSubFont::GetAscent( ViewShell
*pSh
, const OutputDevice
& rOut
)
716 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
);
717 nAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
718 if( GetEscapement() )
719 nAscent
= CalcEscAscent( nAscent
);
723 /*************************************************************************
724 * SwSubFont::GetHeight()
725 *************************************************************************/
727 USHORT
SwSubFont::GetHeight( ViewShell
*pSh
, const OutputDevice
& rOut
)
729 SV_STAT( nGetTextSize
);
730 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
);
731 const USHORT nHeight
= aFntAccess
.Get()->GetFontHeight( pSh
, rOut
);
732 if ( GetEscapement() )
734 const USHORT nAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
735 return CalcEscHeight( nHeight
, nAscent
); // + nLeading;
737 return nHeight
; // + nLeading;
740 /*************************************************************************
741 * SwSubFont::_GetTxtSize()
742 *************************************************************************/
743 Size
SwSubFont::_GetTxtSize( SwDrawTextInfo
& rInf
)
745 // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber
746 // sicher ist sicher ...
747 if ( !pLastFont
|| pLastFont
->GetOwner()!=pMagic
||
748 !IsSameInstance( rInf
.GetpOut()->GetFont() ) )
749 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
751 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
754 xub_StrLen nLn
= ( rInf
.GetLen() == STRING_LEN
? rInf
.GetText().Len()
757 if( IsCapital() && nLn
)
758 aTxtSize
= GetCapitalSize( rInf
);
761 SV_STAT( nGetTextSize
);
762 long nOldKern
= rInf
.GetKern();
763 const XubString
&rOldTxt
= rInf
.GetText();
764 rInf
.SetKern( CheckKerning() );
766 aTxtSize
= pLastFont
->GetTextSize( rInf
);
769 String aTmp
= CalcCaseMap( rInf
.GetText() );
770 const XubString
&rOldStr
= rInf
.GetText();
771 sal_Bool
bCaseMapLengthDiffers(aTmp
.Len() != rOldStr
.Len());
773 if(bCaseMapLengthDiffers
&& rInf
.GetLen())
776 // If the length of the original string and the CaseMapped one
777 // are different, it is necessary to handle the given text part as
778 // a single snippet since it�s size may differ, too.
779 xub_StrLen
nOldIdx(rInf
.GetIdx());
780 xub_StrLen
nOldLen(rInf
.GetLen());
781 const XubString
aSnippet(rOldStr
, nOldIdx
, nOldLen
);
782 XubString
aNewText(CalcCaseMap(aSnippet
));
784 rInf
.SetText( aNewText
);
786 rInf
.SetLen( aNewText
.Len() );
788 aTxtSize
= pLastFont
->GetTextSize( rInf
);
790 rInf
.SetIdx( nOldIdx
);
791 rInf
.SetLen( nOldLen
);
795 rInf
.SetText( aTmp
);
796 aTxtSize
= pLastFont
->GetTextSize( rInf
);
799 rInf
.SetText( rOldStr
);
801 rInf
.SetKern( nOldKern
);
802 rInf
.SetText( rOldTxt
);
803 // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch
804 // hochgestellt, muss seine effektive Hoehe melden.
805 if( GetEscapement() )
807 const USHORT nAscent
= pLastFont
->GetFontAscent( rInf
.GetShell(),
810 (long)CalcEscHeight( (USHORT
)aTxtSize
.Height(), nAscent
);
814 if (1==rInf
.GetLen() && CH_TXT_ATR_FIELDSTART
==rInf
.GetText().GetChar(rInf
.GetIdx()))
816 xub_StrLen
nOldIdx(rInf
.GetIdx());
817 xub_StrLen
nOldLen(rInf
.GetLen());
818 String aNewText
=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDSTART
);
819 rInf
.SetText( aNewText
);
821 rInf
.SetLen( aNewText
.Len() );
822 aTxtSize
= pLastFont
->GetTextSize( rInf
);
823 rInf
.SetIdx( nOldIdx
);
824 rInf
.SetLen( nOldLen
);
826 else if (1==rInf
.GetLen() && CH_TXT_ATR_FIELDEND
==rInf
.GetText().GetChar(rInf
.GetIdx()))
828 xub_StrLen
nOldIdx(rInf
.GetIdx());
829 xub_StrLen
nOldLen(rInf
.GetLen());
830 String aNewText
=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDEND
);
831 rInf
.SetText( aNewText
);
833 rInf
.SetLen( aNewText
.Len() );
834 aTxtSize
= pLastFont
->GetTextSize( rInf
);
835 rInf
.SetIdx( nOldIdx
);
836 rInf
.SetLen( nOldLen
);
842 /*************************************************************************
843 * SwSubFont::_DrawText()
844 *************************************************************************/
846 void SwSubFont::_DrawText( SwDrawTextInfo
&rInf
, const BOOL bGrey
)
848 rInf
.SetGreyWave( bGrey
);
849 xub_StrLen nLn
= rInf
.GetText().Len();
850 if( !rInf
.GetLen() || !nLn
)
852 if( STRING_LEN
== rInf
.GetLen() )
855 FontUnderline nOldUnder
= UNDERLINE_NONE
;
856 SwUnderlineFont
* pUnderFnt
= 0;
858 if( rInf
.GetUnderFnt() )
860 nOldUnder
= GetUnderline();
861 SetUnderline( UNDERLINE_NONE
);
862 pUnderFnt
= rInf
.GetUnderFnt();
865 if( !pLastFont
|| pLastFont
->GetOwner()!=pMagic
)
866 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
868 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
870 Point
aPos( rInf
.GetPos() );
871 const Point
&rOld
= rInf
.GetPos();
874 if( GetEscapement() )
875 CalcEsc( rInf
, aPos
);
877 rInf
.SetKern( CheckKerning() + rInf
.GetSperren() / SPACING_PRECISION_FACTOR
);
883 SV_STAT( nDrawText
);
885 pLastFont
->DrawText( rInf
);
888 const XubString
&rOldStr
= rInf
.GetText();
889 XubString
aString( CalcCaseMap( rOldStr
) );
890 sal_Bool
bCaseMapLengthDiffers(aString
.Len() != rOldStr
.Len());
892 if(bCaseMapLengthDiffers
&& rInf
.GetLen())
895 // If the length of the original string and the CaseMapped one
896 // are different, it is necessary to handle the given text part as
897 // a single snippet since it�s size may differ, too.
898 xub_StrLen
nOldIdx(rInf
.GetIdx());
899 xub_StrLen
nOldLen(rInf
.GetLen());
900 const XubString
aSnippet(rOldStr
, nOldIdx
, nOldLen
);
901 XubString aNewText
= CalcCaseMap(aSnippet
);
903 rInf
.SetText( aNewText
);
905 rInf
.SetLen( aNewText
.Len() );
907 pLastFont
->DrawText( rInf
);
909 rInf
.SetIdx( nOldIdx
);
910 rInf
.SetLen( nOldLen
);
914 rInf
.SetText( aString
);
915 pLastFont
->DrawText( rInf
);
918 rInf
.SetText( rOldStr
);
922 if( pUnderFnt
&& nOldUnder
!= UNDERLINE_NONE
)
924 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
925 Size aFontSize
= _GetTxtSize( rInf
);
926 const XubString
&rOldStr
= rInf
.GetText();
927 XubString
aStr( sDoubleSpace
, RTL_TEXTENCODING_MS_1252
);
929 xub_StrLen nOldIdx
= rInf
.GetIdx();
930 xub_StrLen nOldLen
= rInf
.GetLen();
932 if( rInf
.GetSpace() )
934 xub_StrLen nTmpEnd
= nOldIdx
+ nOldLen
;
935 if( nTmpEnd
> rOldStr
.Len() )
936 nTmpEnd
= rOldStr
.Len();
938 const SwScriptInfo
* pSI
= rInf
.GetScriptInfo();
940 const sal_Bool bAsianFont
=
941 ( rInf
.GetFont() && SW_CJK
== rInf
.GetFont()->GetActual() );
942 for( xub_StrLen nTmp
= nOldIdx
; nTmp
< nTmpEnd
; ++nTmp
)
944 if( CH_BLANK
== rOldStr
.GetChar( nTmp
) || bAsianFont
||
945 ( nTmp
+ 1 < rOldStr
.Len() && pSI
&&
946 i18n::ScriptType::ASIAN
== pSI
->ScriptType( nTmp
+ 1 ) ) )
950 // if next portion if a hole portion we do not consider any
951 // extra space added because the last character was ASIAN
952 if ( nSpace
&& rInf
.IsSpaceStop() && bAsianFont
)
955 nSpace
*= rInf
.GetSpace() / SPACING_PRECISION_FACTOR
;
958 rInf
.SetWidth( USHORT(aFontSize
.Width() + nSpace
) );
959 rInf
.SetText( aStr
);
962 SetUnderline( nOldUnder
);
963 rInf
.SetUnderFnt( 0 );
965 // set position for underline font
966 rInf
.SetPos( pUnderFnt
->GetPos() );
968 pUnderFnt
->GetFont()._DrawStretchText( rInf
);
970 rInf
.SetUnderFnt( pUnderFnt
);
971 rInf
.SetText( rOldStr
);
972 rInf
.SetIdx( nOldIdx
);
973 rInf
.SetLen( nOldLen
);
979 void SwSubFont::_DrawStretchText( SwDrawTextInfo
&rInf
)
981 if( !rInf
.GetLen() || !rInf
.GetText().Len() )
984 FontUnderline nOldUnder
= UNDERLINE_NONE
;
985 SwUnderlineFont
* pUnderFnt
= 0;
987 if( rInf
.GetUnderFnt() )
989 nOldUnder
= GetUnderline();
990 SetUnderline( UNDERLINE_NONE
);
991 pUnderFnt
= rInf
.GetUnderFnt();
994 if ( !pLastFont
|| pLastFont
->GetOwner() != pMagic
)
995 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
997 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
999 rInf
.ApplyAutoColor();
1001 Point
aPos( rInf
.GetPos() );
1003 if( GetEscapement() )
1004 CalcEsc( rInf
, aPos
);
1006 rInf
.SetKern( CheckKerning() + rInf
.GetSperren() / SPACING_PRECISION_FACTOR
);
1007 const Point
&rOld
= rInf
.GetPos();
1008 rInf
.SetPos( aPos
);
1011 DrawStretchCapital( rInf
);
1014 SV_STAT( nDrawStretchText
);
1016 if ( rInf
.GetFrm() )
1018 if ( rInf
.GetFrm()->IsRightToLeft() )
1019 rInf
.GetFrm()->SwitchLTRtoRTL( aPos
);
1021 if ( rInf
.GetFrm()->IsVertical() )
1022 rInf
.GetFrm()->SwitchHorizontalToVertical( aPos
);
1026 rInf
.GetOut().DrawStretchText( aPos
, rInf
.GetWidth(),
1027 rInf
.GetText(), rInf
.GetIdx(), rInf
.GetLen() );
1029 rInf
.GetOut().DrawStretchText( aPos
, rInf
.GetWidth(), CalcCaseMap(
1030 rInf
.GetText() ), rInf
.GetIdx(), rInf
.GetLen() );
1033 if( pUnderFnt
&& nOldUnder
!= UNDERLINE_NONE
)
1035 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
1036 const XubString
&rOldStr
= rInf
.GetText();
1037 XubString
aStr( sDoubleSpace
, RTL_TEXTENCODING_MS_1252
);
1038 xub_StrLen nOldIdx
= rInf
.GetIdx();
1039 xub_StrLen nOldLen
= rInf
.GetLen();
1040 rInf
.SetText( aStr
);
1043 SetUnderline( nOldUnder
);
1044 rInf
.SetUnderFnt( 0 );
1046 // set position for underline font
1047 rInf
.SetPos( pUnderFnt
->GetPos() );
1049 pUnderFnt
->GetFont()._DrawStretchText( rInf
);
1051 rInf
.SetUnderFnt( pUnderFnt
);
1052 rInf
.SetText( rOldStr
);
1053 rInf
.SetIdx( nOldIdx
);
1054 rInf
.SetLen( nOldLen
);
1057 rInf
.SetPos( rOld
);
1060 /*************************************************************************
1061 * SwSubFont::_GetCrsrOfst()
1062 *************************************************************************/
1064 xub_StrLen
SwSubFont::_GetCrsrOfst( SwDrawTextInfo
& rInf
)
1066 if ( !pLastFont
|| pLastFont
->GetOwner()!=pMagic
)
1067 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
1069 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
1071 xub_StrLen nLn
= rInf
.GetLen() == STRING_LEN
? rInf
.GetText().Len()
1074 xub_StrLen nCrsr
= 0;
1075 if( IsCapital() && nLn
)
1076 nCrsr
= GetCapitalCrsrOfst( rInf
);
1079 const XubString
&rOldTxt
= rInf
.GetText();
1080 long nOldKern
= rInf
.GetKern();
1081 rInf
.SetKern( CheckKerning() );
1082 SV_STAT( nGetTextSize
);
1084 nCrsr
= pLastFont
->GetCrsrOfst( rInf
);
1087 String aTmp
= CalcCaseMap( rInf
.GetText() );
1088 rInf
.SetText( aTmp
);
1089 nCrsr
= pLastFont
->GetCrsrOfst( rInf
);
1091 rInf
.SetKern( nOldKern
);
1092 rInf
.SetText( rOldTxt
);
1097 /*************************************************************************
1098 * SwSubFont::CalcEsc()
1099 *************************************************************************/
1101 void SwSubFont::CalcEsc( SwDrawTextInfo
& rInf
, Point
& rPos
)
1105 USHORT nDir
= UnMapDirection(
1106 GetOrientation(), rInf
.GetFrm() && rInf
.GetFrm()->IsVertical() );
1108 switch ( GetEscapement() )
1110 case DFLT_ESC_AUTO_SUB
:
1111 nOfst
= nOrgHeight
- nOrgAscent
-
1112 pLastFont
->GetFontHeight( rInf
.GetShell(), rInf
.GetOut() ) +
1113 pLastFont
->GetFontAscent( rInf
.GetShell(), rInf
.GetOut() );
1129 case DFLT_ESC_AUTO_SUPER
:
1130 nOfst
= pLastFont
->GetFontAscent( rInf
.GetShell(), rInf
.GetOut() ) -
1149 nOfst
= ((long)nOrgHeight
* GetEscapement()) / 100L;
1166 // used during painting of small capitals
1167 void SwDrawTextInfo::Shift( USHORT nDir
)
1169 ASSERT( bPos
, "DrawTextInfo: Undefined Position" );
1170 ASSERT( bSize
, "DrawTextInfo: Undefined Width" );
1172 const BOOL bBidiPor
= ( GetFrm() && GetFrm()->IsRightToLeft() ) !=
1173 ( 0 != ( TEXT_LAYOUT_BIDI_RTL
& GetpOut()->GetLayoutMode() ) );
1177 UnMapDirection( nDir
, GetFrm() && GetFrm()->IsVertical() );
1182 ((Point
*)pPos
)->X() += GetSize().Width();
1185 ASSERT( ((Point
*)pPos
)->Y() >= GetSize().Width(), "Going underground" );
1186 ((Point
*)pPos
)->Y() -= GetSize().Width();
1189 ((Point
*)pPos
)->X() -= GetSize().Width();
1192 ((Point
*)pPos
)->Y() += GetSize().Width();
1197 /*************************************************************************
1198 * SwUnderlineFont::~SwUnderlineFont
1200 * Used for the "continuous underline" feature.
1201 *************************************************************************/
1203 SwUnderlineFont::SwUnderlineFont( SwFont
& rFnt
, const Point
& rPoint
)
1204 : aPos( rPoint
), pFnt( &rFnt
)
1208 SwUnderlineFont::~SwUnderlineFont()
1213 //Helper for filters to find true lineheight of a font
1214 long AttrSetToLineHeight( const IDocumentSettingAccess
& rIDocumentSettingAccess
,
1215 const SwAttrSet
&rSet
,
1216 const OutputDevice
&rOut
, sal_Int16 nScript
)
1218 SwFont
aFont(&rSet
, &rIDocumentSettingAccess
);
1223 case i18n::ScriptType::LATIN
:
1226 case i18n::ScriptType::ASIAN
:
1229 case i18n::ScriptType::COMPLEX
:
1233 aFont
.SetActual(nActual
);
1235 OutputDevice
&rMutableOut
= const_cast<OutputDevice
&>(rOut
);
1236 const Font
aOldFont(rMutableOut
.GetFont());
1238 rMutableOut
.SetFont(aFont
.GetActualFont());
1239 long nHeight
= rMutableOut
.GetTextHeight();
1241 rMutableOut
.SetFont(aOldFont
);