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();
451 bFntChg
= rFont
.bFntChg
;
452 bOrgChg
= rFont
.bOrgChg
;
453 bPaintBlank
= rFont
.bPaintBlank
;
456 bGreyWave
= rFont
.bGreyWave
;
457 bNoColReplace
= rFont
.bNoColReplace
;
458 bNoHyph
= rFont
.bNoHyph
;
459 bBlink
= rFont
.bBlink
;
462 SwFont::SwFont( const SwAttrSet
* pAttrSet
,
463 const IDocumentSettingAccess
* pIDocumentSettingAccess
)
473 bNoColReplace
= FALSE
;
474 bNoHyph
= pAttrSet
->GetNoHyphenHere().GetValue();
475 bBlink
= pAttrSet
->GetBlink().GetValue();
478 const SvxFontItem
& rFont
= pAttrSet
->GetFont();
479 aSub
[SW_LATIN
].SetFamily( rFont
.GetFamily() );
480 aSub
[SW_LATIN
].SetName( rFont
.GetFamilyName() );
481 aSub
[SW_LATIN
].SetStyleName( rFont
.GetStyleName() );
482 aSub
[SW_LATIN
].SetPitch( rFont
.GetPitch() );
483 aSub
[SW_LATIN
].SetCharSet( rFont
.GetCharSet() );
484 aSub
[SW_LATIN
].SvxFont::SetPropr( 100 ); // 100% der FontSize
485 Size aTmpSize
= aSub
[SW_LATIN
].aSize
;
486 aTmpSize
.Height() = pAttrSet
->GetSize().GetHeight();
487 aSub
[SW_LATIN
].SetSize( aTmpSize
);
488 aSub
[SW_LATIN
].SetItalic( pAttrSet
->GetPosture().GetPosture() );
489 aSub
[SW_LATIN
].SetWeight( pAttrSet
->GetWeight().GetWeight() );
490 aSub
[SW_LATIN
].SetLanguage( pAttrSet
->GetLanguage().GetLanguage() );
494 const SvxFontItem
& rFont
= pAttrSet
->GetCJKFont();
495 aSub
[SW_CJK
].SetFamily( rFont
.GetFamily() );
496 aSub
[SW_CJK
].SetName( rFont
.GetFamilyName() );
497 aSub
[SW_CJK
].SetStyleName( rFont
.GetStyleName() );
498 aSub
[SW_CJK
].SetPitch( rFont
.GetPitch() );
499 aSub
[SW_CJK
].SetCharSet( rFont
.GetCharSet() );
500 aSub
[SW_CJK
].SvxFont::SetPropr( 100 ); // 100% der FontSize
501 Size aTmpSize
= aSub
[SW_CJK
].aSize
;
502 aTmpSize
.Height() = pAttrSet
->GetCJKSize().GetHeight();
503 aSub
[SW_CJK
].SetSize( aTmpSize
);
504 aSub
[SW_CJK
].SetItalic( pAttrSet
->GetCJKPosture().GetPosture() );
505 aSub
[SW_CJK
].SetWeight( pAttrSet
->GetCJKWeight().GetWeight() );
506 LanguageType eNewLang
= pAttrSet
->GetCJKLanguage().GetLanguage();
507 aSub
[SW_CJK
].SetLanguage( eNewLang
);
508 aSub
[SW_LATIN
].SetCJKContextLanguage( eNewLang
);
509 aSub
[SW_CJK
].SetCJKContextLanguage( eNewLang
);
510 aSub
[SW_CTL
].SetCJKContextLanguage( eNewLang
);
514 const SvxFontItem
& rFont
= pAttrSet
->GetCTLFont();
515 aSub
[SW_CTL
].SetFamily( rFont
.GetFamily() );
516 aSub
[SW_CTL
].SetName( rFont
.GetFamilyName() );
517 aSub
[SW_CTL
].SetStyleName( rFont
.GetStyleName() );
518 aSub
[SW_CTL
].SetPitch( rFont
.GetPitch() );
519 aSub
[SW_CTL
].SetCharSet( rFont
.GetCharSet() );
520 aSub
[SW_CTL
].SvxFont::SetPropr( 100 ); // 100% der FontSize
521 Size aTmpSize
= aSub
[SW_CTL
].aSize
;
522 aTmpSize
.Height() = pAttrSet
->GetCTLSize().GetHeight();
523 aSub
[SW_CTL
].SetSize( aTmpSize
);
524 aSub
[SW_CTL
].SetItalic( pAttrSet
->GetCTLPosture().GetPosture() );
525 aSub
[SW_CTL
].SetWeight( pAttrSet
->GetCTLWeight().GetWeight() );
526 aSub
[SW_CTL
].SetLanguage( pAttrSet
->GetCTLLanguage().GetLanguage() );
529 const FontUnderline eUnderline
= pAttrSet
->GetUnderline().GetLineStyle();
530 if ( pAttrSet
->GetCharHidden().GetValue() )
531 SetUnderline( UNDERLINE_DOTTED
);
533 SetUnderline( eUnderline
);
534 SetUnderColor( pAttrSet
->GetUnderline().GetColor() );
535 SetOverline( pAttrSet
->GetOverline().GetLineStyle() );
536 SetOverColor( pAttrSet
->GetOverline().GetColor() );
537 SetEmphasisMark( pAttrSet
->GetEmphasisMark().GetEmphasisMark() );
538 SetStrikeout( pAttrSet
->GetCrossedOut().GetStrikeout() );
539 SetColor( pAttrSet
->GetColor().GetValue() );
540 SetTransparent( TRUE
);
541 SetAlign( ALIGN_BASELINE
);
542 SetOutline( pAttrSet
->GetContour().GetValue() );
543 SetShadow( pAttrSet
->GetShadowed().GetValue() );
544 SetPropWidth( pAttrSet
->GetCharScaleW().GetValue() );
545 SetRelief( (FontRelief
)pAttrSet
->GetCharRelief().GetValue() );
546 if( pAttrSet
->GetAutoKern().GetValue() )
548 SetAutoKern( ( !pIDocumentSettingAccess
||
549 !pIDocumentSettingAccess
->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION
) ) ?
550 KERNING_FONTSPECIFIC
:
555 SetWordLineMode( pAttrSet
->GetWordLineMode().GetValue() );
556 const SvxEscapementItem
&rEsc
= pAttrSet
->GetEscapement();
557 SetEscapement( rEsc
.GetEsc() );
558 if( aSub
[SW_LATIN
].IsEsc() )
559 SetProportion( rEsc
.GetProp() );
560 SetCaseMap( pAttrSet
->GetCaseMap().GetCaseMap() );
561 SetFixKerning( pAttrSet
->GetKerning().GetValue() );
562 const SfxPoolItem
* pItem
;
563 if( SFX_ITEM_SET
== pAttrSet
->GetItemState( RES_CHRATR_BACKGROUND
,
565 pBackColor
= new Color( ((SvxBrushItem
*)pItem
)->GetColor() );
568 const SvxTwoLinesItem
& rTwoLinesItem
= pAttrSet
->Get2Lines();
569 if ( ! rTwoLinesItem
.GetValue() )
570 SetVertical( pAttrSet
->GetCharRotate().GetValue() );
575 SwSubFont
& SwSubFont::operator=( const SwSubFont
&rFont
)
577 SvxFont::operator=( rFont
);
578 pMagic
= rFont
.pMagic
;
579 nFntIndex
= rFont
.nFntIndex
;
580 nOrgHeight
= rFont
.nOrgHeight
;
581 nOrgAscent
= rFont
.nOrgAscent
;
582 nPropWidth
= rFont
.nPropWidth
;
587 SwFont
& SwFont::operator=( const SwFont
&rFont
)
589 aSub
[SW_LATIN
] = rFont
.aSub
[SW_LATIN
];
590 aSub
[SW_CJK
] = rFont
.aSub
[SW_CJK
];
591 aSub
[SW_CTL
] = rFont
.aSub
[SW_CTL
];
592 nActual
= rFont
.nActual
;
594 pBackColor
= rFont
.pBackColor
? new Color( *rFont
.pBackColor
) : NULL
;
595 aUnderColor
= rFont
.GetUnderColor();
596 aOverColor
= rFont
.GetOverColor();
600 bFntChg
= rFont
.bFntChg
;
601 bOrgChg
= rFont
.bOrgChg
;
602 bPaintBlank
= rFont
.bPaintBlank
;
605 bGreyWave
= rFont
.bGreyWave
;
606 bNoColReplace
= rFont
.bNoColReplace
;
607 bNoHyph
= rFont
.bNoHyph
;
608 bBlink
= rFont
.bBlink
;
612 /*************************************************************************
614 *************************************************************************/
616 void SwFont::GoMagic( ViewShell
*pSh
, BYTE nWhich
)
618 SwFntAccess
aFntAccess( aSub
[nWhich
].pMagic
, aSub
[nWhich
].nFntIndex
,
619 &aSub
[nWhich
], pSh
, TRUE
);
622 /*************************************************************************
623 * SwSubFont::IsSymbol()
624 *************************************************************************/
626 BOOL
SwSubFont::IsSymbol( ViewShell
*pSh
)
628 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
, FALSE
);
629 return aFntAccess
.Get()->IsSymbol();
632 /*************************************************************************
633 * SwSubFont::ChgFnt()
634 *************************************************************************/
636 BOOL
SwSubFont::ChgFnt( ViewShell
*pSh
, OutputDevice
& rOut
)
640 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
, TRUE
);
641 SV_STAT( nChangeFont
);
643 pLastFont
= aFntAccess
.Get();
645 pLastFont
->SetDevFont( pSh
, rOut
);
648 return UNDERLINE_NONE
!= GetUnderline() ||
649 UNDERLINE_NONE
!= GetOverline() ||
650 STRIKEOUT_NONE
!= GetStrikeout();
653 /*************************************************************************
654 * SwFont::ChgPhysFnt()
655 *************************************************************************/
657 void SwFont::ChgPhysFnt( ViewShell
*pSh
, OutputDevice
& rOut
)
659 if( bOrgChg
&& aSub
[nActual
].IsEsc() )
661 const BYTE nOldProp
= aSub
[nActual
].GetPropr();
662 SetProportion( 100 );
664 SwFntAccess
aFntAccess( aSub
[nActual
].pMagic
, aSub
[nActual
].nFntIndex
,
665 &aSub
[nActual
], pSh
);
666 aSub
[nActual
].nOrgHeight
= aFntAccess
.Get()->GetFontHeight( pSh
, rOut
);
667 aSub
[nActual
].nOrgAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
668 SetProportion( nOldProp
);
677 if( rOut
.GetTextLineColor() != aUnderColor
)
678 rOut
.SetTextLineColor( aUnderColor
);
679 if( rOut
.GetOverlineColor() != aOverColor
)
680 rOut
.SetOverlineColor( aOverColor
);
683 /*************************************************************************
684 * SwFont::CalcEscHeight()
685 * Height = MaxAscent + MaxDescent
686 * MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) );
687 * MaxDescent = Max (T1_height-T1_ascent,
688 * T2_height-T2_ascent - (Esc * T1_height)
689 *************************************************************************/
691 USHORT
SwSubFont::CalcEscHeight( const USHORT nOldHeight
,
692 const USHORT nOldAscent
) const
694 if( DFLT_ESC_AUTO_SUPER
!= GetEscapement() &&
695 DFLT_ESC_AUTO_SUB
!= GetEscapement() )
697 long nDescent
= nOldHeight
- nOldAscent
-
698 ( (long) nOrgHeight
* GetEscapement() ) / 100L;
699 const USHORT nDesc
= ( nDescent
>0 ) ? Max ( USHORT(nDescent
),
700 USHORT(nOrgHeight
- nOrgAscent
) ) : nOrgHeight
- nOrgAscent
;
701 return ( nDesc
+ CalcEscAscent( nOldAscent
) );
706 short SwSubFont::_CheckKerning( )
708 short nKernx
= - short( Font::GetSize().Height() / 6 );
710 if ( nKernx
< GetFixKerning() )
711 return GetFixKerning();
715 /*************************************************************************
716 * SwSubFont::GetAscent()
717 *************************************************************************/
719 USHORT
SwSubFont::GetAscent( ViewShell
*pSh
, const OutputDevice
& rOut
)
722 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
);
723 nAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
724 if( GetEscapement() )
725 nAscent
= CalcEscAscent( nAscent
);
729 /*************************************************************************
730 * SwSubFont::GetHeight()
731 *************************************************************************/
733 USHORT
SwSubFont::GetHeight( ViewShell
*pSh
, const OutputDevice
& rOut
)
735 SV_STAT( nGetTextSize
);
736 SwFntAccess
aFntAccess( pMagic
, nFntIndex
, this, pSh
);
737 const USHORT nHeight
= aFntAccess
.Get()->GetFontHeight( pSh
, rOut
);
738 if ( GetEscapement() )
740 const USHORT nAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
741 return CalcEscHeight( nHeight
, nAscent
); // + nLeading;
743 return nHeight
; // + nLeading;
746 /*************************************************************************
747 * SwSubFont::_GetTxtSize()
748 *************************************************************************/
749 Size
SwSubFont::_GetTxtSize( SwDrawTextInfo
& rInf
)
751 // Robust: Eigentlich sollte der Font bereits eingestellt sein, aber
752 // sicher ist sicher ...
753 if ( !pLastFont
|| pLastFont
->GetOwner()!=pMagic
||
754 !IsSameInstance( rInf
.GetpOut()->GetFont() ) )
755 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
757 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
760 xub_StrLen nLn
= ( rInf
.GetLen() == STRING_LEN
? rInf
.GetText().Len()
763 if( IsCapital() && nLn
)
764 aTxtSize
= GetCapitalSize( rInf
);
767 SV_STAT( nGetTextSize
);
768 long nOldKern
= rInf
.GetKern();
769 const XubString
&rOldTxt
= rInf
.GetText();
770 rInf
.SetKern( CheckKerning() );
772 aTxtSize
= pLastFont
->GetTextSize( rInf
);
775 String aTmp
= CalcCaseMap( rInf
.GetText() );
776 const XubString
&rOldStr
= rInf
.GetText();
777 sal_Bool
bCaseMapLengthDiffers(aTmp
.Len() != rOldStr
.Len());
779 if(bCaseMapLengthDiffers
&& rInf
.GetLen())
782 // If the length of the original string and the CaseMapped one
783 // are different, it is necessary to handle the given text part as
784 // a single snippet since it�s size may differ, too.
785 xub_StrLen
nOldIdx(rInf
.GetIdx());
786 xub_StrLen
nOldLen(rInf
.GetLen());
787 const XubString
aSnippet(rOldStr
, nOldIdx
, nOldLen
);
788 XubString
aNewText(CalcCaseMap(aSnippet
));
790 rInf
.SetText( aNewText
);
792 rInf
.SetLen( aNewText
.Len() );
794 aTxtSize
= pLastFont
->GetTextSize( rInf
);
796 rInf
.SetIdx( nOldIdx
);
797 rInf
.SetLen( nOldLen
);
801 rInf
.SetText( aTmp
);
802 aTxtSize
= pLastFont
->GetTextSize( rInf
);
805 rInf
.SetText( rOldStr
);
807 rInf
.SetKern( nOldKern
);
808 rInf
.SetText( rOldTxt
);
809 // 15142: Ein Wort laenger als eine Zeile, beim Zeilenumbruch
810 // hochgestellt, muss seine effektive Hoehe melden.
811 if( GetEscapement() )
813 const USHORT nAscent
= pLastFont
->GetFontAscent( rInf
.GetShell(),
816 (long)CalcEscHeight( (USHORT
)aTxtSize
.Height(), nAscent
);
820 if (1==rInf
.GetLen() && CH_TXT_ATR_FIELDSTART
==rInf
.GetText().GetChar(rInf
.GetIdx()))
822 xub_StrLen
nOldIdx(rInf
.GetIdx());
823 xub_StrLen
nOldLen(rInf
.GetLen());
824 String aNewText
=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDSTART
);
825 rInf
.SetText( aNewText
);
827 rInf
.SetLen( aNewText
.Len() );
828 aTxtSize
= pLastFont
->GetTextSize( rInf
);
829 rInf
.SetIdx( nOldIdx
);
830 rInf
.SetLen( nOldLen
);
832 else if (1==rInf
.GetLen() && CH_TXT_ATR_FIELDEND
==rInf
.GetText().GetChar(rInf
.GetIdx()))
834 xub_StrLen
nOldIdx(rInf
.GetIdx());
835 xub_StrLen
nOldLen(rInf
.GetLen());
836 String aNewText
=String::CreateFromAscii(CH_TXT_ATR_SUBST_FIELDEND
);
837 rInf
.SetText( aNewText
);
839 rInf
.SetLen( aNewText
.Len() );
840 aTxtSize
= pLastFont
->GetTextSize( rInf
);
841 rInf
.SetIdx( nOldIdx
);
842 rInf
.SetLen( nOldLen
);
848 /*************************************************************************
849 * SwSubFont::_DrawText()
850 *************************************************************************/
852 void SwSubFont::_DrawText( SwDrawTextInfo
&rInf
, const BOOL bGrey
)
854 rInf
.SetGreyWave( bGrey
);
855 xub_StrLen nLn
= rInf
.GetText().Len();
856 if( !rInf
.GetLen() || !nLn
)
858 if( STRING_LEN
== rInf
.GetLen() )
861 FontUnderline nOldUnder
= UNDERLINE_NONE
;
862 SwUnderlineFont
* pUnderFnt
= 0;
864 if( rInf
.GetUnderFnt() )
866 nOldUnder
= GetUnderline();
867 SetUnderline( UNDERLINE_NONE
);
868 pUnderFnt
= rInf
.GetUnderFnt();
871 if( !pLastFont
|| pLastFont
->GetOwner()!=pMagic
)
872 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
874 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
876 Point
aPos( rInf
.GetPos() );
877 const Point
&rOld
= rInf
.GetPos();
880 if( GetEscapement() )
881 CalcEsc( rInf
, aPos
);
883 rInf
.SetKern( CheckKerning() + rInf
.GetSperren() / SPACING_PRECISION_FACTOR
);
889 SV_STAT( nDrawText
);
891 pLastFont
->DrawText( rInf
);
894 const XubString
&rOldStr
= rInf
.GetText();
895 XubString
aString( CalcCaseMap( rOldStr
) );
896 sal_Bool
bCaseMapLengthDiffers(aString
.Len() != rOldStr
.Len());
898 if(bCaseMapLengthDiffers
&& rInf
.GetLen())
901 // If the length of the original string and the CaseMapped one
902 // are different, it is necessary to handle the given text part as
903 // a single snippet since it�s size may differ, too.
904 xub_StrLen
nOldIdx(rInf
.GetIdx());
905 xub_StrLen
nOldLen(rInf
.GetLen());
906 const XubString
aSnippet(rOldStr
, nOldIdx
, nOldLen
);
907 XubString aNewText
= CalcCaseMap(aSnippet
);
909 rInf
.SetText( aNewText
);
911 rInf
.SetLen( aNewText
.Len() );
913 pLastFont
->DrawText( rInf
);
915 rInf
.SetIdx( nOldIdx
);
916 rInf
.SetLen( nOldLen
);
920 rInf
.SetText( aString
);
921 pLastFont
->DrawText( rInf
);
924 rInf
.SetText( rOldStr
);
928 if( pUnderFnt
&& nOldUnder
!= UNDERLINE_NONE
)
930 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
931 Size aFontSize
= _GetTxtSize( rInf
);
932 const XubString
&rOldStr
= rInf
.GetText();
933 XubString
aStr( sDoubleSpace
, RTL_TEXTENCODING_MS_1252
);
935 xub_StrLen nOldIdx
= rInf
.GetIdx();
936 xub_StrLen nOldLen
= rInf
.GetLen();
938 if( rInf
.GetSpace() )
940 xub_StrLen nTmpEnd
= nOldIdx
+ nOldLen
;
941 if( nTmpEnd
> rOldStr
.Len() )
942 nTmpEnd
= rOldStr
.Len();
944 const SwScriptInfo
* pSI
= rInf
.GetScriptInfo();
946 const sal_Bool bAsianFont
=
947 ( rInf
.GetFont() && SW_CJK
== rInf
.GetFont()->GetActual() );
948 for( xub_StrLen nTmp
= nOldIdx
; nTmp
< nTmpEnd
; ++nTmp
)
950 if( CH_BLANK
== rOldStr
.GetChar( nTmp
) || bAsianFont
||
951 ( nTmp
+ 1 < rOldStr
.Len() && pSI
&&
952 i18n::ScriptType::ASIAN
== pSI
->ScriptType( nTmp
+ 1 ) ) )
956 // if next portion if a hole portion we do not consider any
957 // extra space added because the last character was ASIAN
958 if ( nSpace
&& rInf
.IsSpaceStop() && bAsianFont
)
961 nSpace
*= rInf
.GetSpace() / SPACING_PRECISION_FACTOR
;
964 rInf
.SetWidth( USHORT(aFontSize
.Width() + nSpace
) );
965 rInf
.SetText( aStr
);
968 SetUnderline( nOldUnder
);
969 rInf
.SetUnderFnt( 0 );
971 // set position for underline font
972 rInf
.SetPos( pUnderFnt
->GetPos() );
974 pUnderFnt
->GetFont()._DrawStretchText( rInf
);
976 rInf
.SetUnderFnt( pUnderFnt
);
977 rInf
.SetText( rOldStr
);
978 rInf
.SetIdx( nOldIdx
);
979 rInf
.SetLen( nOldLen
);
985 void SwSubFont::_DrawStretchText( SwDrawTextInfo
&rInf
)
987 if( !rInf
.GetLen() || !rInf
.GetText().Len() )
990 FontUnderline nOldUnder
= UNDERLINE_NONE
;
991 SwUnderlineFont
* pUnderFnt
= 0;
993 if( rInf
.GetUnderFnt() )
995 nOldUnder
= GetUnderline();
996 SetUnderline( UNDERLINE_NONE
);
997 pUnderFnt
= rInf
.GetUnderFnt();
1000 if ( !pLastFont
|| pLastFont
->GetOwner() != pMagic
)
1001 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
1003 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
1005 rInf
.ApplyAutoColor();
1007 Point
aPos( rInf
.GetPos() );
1009 if( GetEscapement() )
1010 CalcEsc( rInf
, aPos
);
1012 rInf
.SetKern( CheckKerning() + rInf
.GetSperren() / SPACING_PRECISION_FACTOR
);
1013 const Point
&rOld
= rInf
.GetPos();
1014 rInf
.SetPos( aPos
);
1017 DrawStretchCapital( rInf
);
1020 SV_STAT( nDrawStretchText
);
1022 if ( rInf
.GetFrm() )
1024 if ( rInf
.GetFrm()->IsRightToLeft() )
1025 rInf
.GetFrm()->SwitchLTRtoRTL( aPos
);
1027 if ( rInf
.GetFrm()->IsVertical() )
1028 rInf
.GetFrm()->SwitchHorizontalToVertical( aPos
);
1032 rInf
.GetOut().DrawStretchText( aPos
, rInf
.GetWidth(),
1033 rInf
.GetText(), rInf
.GetIdx(), rInf
.GetLen() );
1035 rInf
.GetOut().DrawStretchText( aPos
, rInf
.GetWidth(), CalcCaseMap(
1036 rInf
.GetText() ), rInf
.GetIdx(), rInf
.GetLen() );
1039 if( pUnderFnt
&& nOldUnder
!= UNDERLINE_NONE
)
1041 static sal_Char __READONLY_DATA sDoubleSpace
[] = " ";
1042 const XubString
&rOldStr
= rInf
.GetText();
1043 XubString
aStr( sDoubleSpace
, RTL_TEXTENCODING_MS_1252
);
1044 xub_StrLen nOldIdx
= rInf
.GetIdx();
1045 xub_StrLen nOldLen
= rInf
.GetLen();
1046 rInf
.SetText( aStr
);
1049 SetUnderline( nOldUnder
);
1050 rInf
.SetUnderFnt( 0 );
1052 // set position for underline font
1053 rInf
.SetPos( pUnderFnt
->GetPos() );
1055 pUnderFnt
->GetFont()._DrawStretchText( rInf
);
1057 rInf
.SetUnderFnt( pUnderFnt
);
1058 rInf
.SetText( rOldStr
);
1059 rInf
.SetIdx( nOldIdx
);
1060 rInf
.SetLen( nOldLen
);
1063 rInf
.SetPos( rOld
);
1066 /*************************************************************************
1067 * SwSubFont::_GetCrsrOfst()
1068 *************************************************************************/
1070 xub_StrLen
SwSubFont::_GetCrsrOfst( SwDrawTextInfo
& rInf
)
1072 if ( !pLastFont
|| pLastFont
->GetOwner()!=pMagic
)
1073 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
1075 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
1077 xub_StrLen nLn
= rInf
.GetLen() == STRING_LEN
? rInf
.GetText().Len()
1080 xub_StrLen nCrsr
= 0;
1081 if( IsCapital() && nLn
)
1082 nCrsr
= GetCapitalCrsrOfst( rInf
);
1085 const XubString
&rOldTxt
= rInf
.GetText();
1086 long nOldKern
= rInf
.GetKern();
1087 rInf
.SetKern( CheckKerning() );
1088 SV_STAT( nGetTextSize
);
1090 nCrsr
= pLastFont
->GetCrsrOfst( rInf
);
1093 String aTmp
= CalcCaseMap( rInf
.GetText() );
1094 rInf
.SetText( aTmp
);
1095 nCrsr
= pLastFont
->GetCrsrOfst( rInf
);
1097 rInf
.SetKern( nOldKern
);
1098 rInf
.SetText( rOldTxt
);
1103 /*************************************************************************
1104 * SwSubFont::CalcEsc()
1105 *************************************************************************/
1107 void SwSubFont::CalcEsc( SwDrawTextInfo
& rInf
, Point
& rPos
)
1111 USHORT nDir
= UnMapDirection(
1112 GetOrientation(), rInf
.GetFrm() && rInf
.GetFrm()->IsVertical() );
1114 switch ( GetEscapement() )
1116 case DFLT_ESC_AUTO_SUB
:
1117 nOfst
= nOrgHeight
- nOrgAscent
-
1118 pLastFont
->GetFontHeight( rInf
.GetShell(), rInf
.GetOut() ) +
1119 pLastFont
->GetFontAscent( rInf
.GetShell(), rInf
.GetOut() );
1135 case DFLT_ESC_AUTO_SUPER
:
1136 nOfst
= pLastFont
->GetFontAscent( rInf
.GetShell(), rInf
.GetOut() ) -
1155 nOfst
= ((long)nOrgHeight
* GetEscapement()) / 100L;
1172 // used during painting of small capitals
1173 void SwDrawTextInfo::Shift( USHORT nDir
)
1175 ASSERT( bPos
, "DrawTextInfo: Undefined Position" );
1176 ASSERT( bSize
, "DrawTextInfo: Undefined Width" );
1178 const BOOL bBidiPor
= ( GetFrm() && GetFrm()->IsRightToLeft() ) !=
1179 ( 0 != ( TEXT_LAYOUT_BIDI_RTL
& GetpOut()->GetLayoutMode() ) );
1183 UnMapDirection( nDir
, GetFrm() && GetFrm()->IsVertical() );
1188 ((Point
*)pPos
)->X() += GetSize().Width();
1191 ASSERT( ((Point
*)pPos
)->Y() >= GetSize().Width(), "Going underground" );
1192 ((Point
*)pPos
)->Y() -= GetSize().Width();
1195 ((Point
*)pPos
)->X() -= GetSize().Width();
1198 ((Point
*)pPos
)->Y() += GetSize().Width();
1203 /*************************************************************************
1204 * SwUnderlineFont::~SwUnderlineFont
1206 * Used for the "continuous underline" feature.
1207 *************************************************************************/
1209 SwUnderlineFont::SwUnderlineFont( SwFont
& rFnt
, const Point
& rPoint
)
1210 : aPos( rPoint
), pFnt( &rFnt
)
1214 SwUnderlineFont::~SwUnderlineFont()
1219 //Helper for filters to find true lineheight of a font
1220 long AttrSetToLineHeight( const IDocumentSettingAccess
& rIDocumentSettingAccess
,
1221 const SwAttrSet
&rSet
,
1222 const OutputDevice
&rOut
, sal_Int16 nScript
)
1224 SwFont
aFont(&rSet
, &rIDocumentSettingAccess
);
1229 case i18n::ScriptType::LATIN
:
1232 case i18n::ScriptType::ASIAN
:
1235 case i18n::ScriptType::COMPLEX
:
1239 aFont
.SetActual(nActual
);
1241 OutputDevice
&rMutableOut
= const_cast<OutputDevice
&>(rOut
);
1242 const Font
aOldFont(rMutableOut
.GetFont());
1244 rMutableOut
.SetFont(aFont
.GetActualFont());
1245 long nHeight
= rMutableOut
.GetTextHeight();
1247 rMutableOut
.SetFont(aOldFont
);