1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
22 #include <com/sun/star/i18n/ScriptType.hpp>
23 #include <vcl/outdev.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <editeng/wrlmitem.hxx>
26 #include <editeng/kernitem.hxx>
27 #include <editeng/cmapitem.hxx>
28 #include <editeng/langitem.hxx>
29 #include <editeng/escapementitem.hxx>
30 #include <editeng/autokernitem.hxx>
31 #include <editeng/shdditem.hxx>
32 #include <editeng/charreliefitem.hxx>
33 #include <editeng/contouritem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/crossedoutitem.hxx>
36 #include <editeng/udlnitem.hxx>
37 #include <editeng/wghtitem.hxx>
38 #include <editeng/postitem.hxx>
39 #include <editeng/fhgtitem.hxx>
40 #include <editeng/fontitem.hxx>
41 #include <editeng/emphasismarkitem.hxx>
42 #include <editeng/charscaleitem.hxx>
43 #include <editeng/charrotateitem.hxx>
44 #include <editeng/twolinesitem.hxx>
45 #include <editeng/charhiddenitem.hxx>
46 #include <editeng/boxitem.hxx>
47 #include <editeng/shaditem.hxx>
48 #include <IDocumentSettingAccess.hxx>
49 #include <charatr.hxx>
52 #include <fntcache.hxx>
54 #include <scriptinfo.hxx>
58 SvStatistics g_SvStat
;
61 using namespace ::com::sun::star
;
63 // set background brush, depending on character formatting
64 void SwFont::SetBackColor( std::optional
<Color
> xNewColor
)
66 mxBackColor
= xNewColor
;
68 m_aSub
[SwFontScript::Latin
].m_nFontCacheId
= m_aSub
[SwFontScript::CJK
].m_nFontCacheId
= m_aSub
[SwFontScript::CTL
].m_nFontCacheId
= nullptr;
71 void SwFont::SetTopBorder( const editeng::SvxBorderLine
* pTopBorder
)
74 m_aTopBorder
= *pTopBorder
;
81 m_aSub
[SwFontScript::Latin
].m_nFontCacheId
= m_aSub
[SwFontScript::CJK
].m_nFontCacheId
= m_aSub
[SwFontScript::CTL
].m_nFontCacheId
= nullptr;
84 void SwFont::SetBottomBorder( const editeng::SvxBorderLine
* pBottomBorder
)
87 m_aBottomBorder
= *pBottomBorder
;
90 m_aBottomBorder
.reset();
91 m_nBottomBorderDist
= 0;
94 m_aSub
[SwFontScript::Latin
].m_nFontCacheId
= m_aSub
[SwFontScript::CJK
].m_nFontCacheId
= m_aSub
[SwFontScript::CTL
].m_nFontCacheId
= nullptr;
97 void SwFont::SetRightBorder( const editeng::SvxBorderLine
* pRightBorder
)
100 m_aRightBorder
= *pRightBorder
;
103 m_aRightBorder
.reset();
104 m_nRightBorderDist
= 0;
107 m_aSub
[SwFontScript::Latin
].m_nFontCacheId
= m_aSub
[SwFontScript::CJK
].m_nFontCacheId
= m_aSub
[SwFontScript::CTL
].m_nFontCacheId
= nullptr;
110 void SwFont::SetLeftBorder( const editeng::SvxBorderLine
* pLeftBorder
)
113 m_aLeftBorder
= *pLeftBorder
;
116 m_aLeftBorder
.reset();
117 m_nLeftBorderDist
= 0;
120 m_aSub
[SwFontScript::Latin
].m_nFontCacheId
= m_aSub
[SwFontScript::CJK
].m_nFontCacheId
= m_aSub
[SwFontScript::CTL
].m_nFontCacheId
= nullptr;
123 const std::optional
<editeng::SvxBorderLine
>&
124 SwFont::GetAbsTopBorder(const bool bVertLayout
, const bool bVertLayoutLRBT
) const
126 switch (GetOrientation(bVertLayout
, bVertLayoutLRBT
).get())
131 return m_aRightBorder
;
133 return m_aBottomBorder
;
135 return m_aLeftBorder
;
142 const std::optional
<editeng::SvxBorderLine
>&
143 SwFont::GetAbsBottomBorder(const bool bVertLayout
, const bool bVertLayoutLRBT
) const
145 switch (GetOrientation(bVertLayout
, bVertLayoutLRBT
).get())
148 return m_aBottomBorder
;
150 return m_aLeftBorder
;
154 return m_aRightBorder
;
157 return m_aBottomBorder
;
161 const std::optional
<editeng::SvxBorderLine
>&
162 SwFont::GetAbsLeftBorder(const bool bVertLayout
, const bool bVertLayoutLRBT
) const
164 switch (GetOrientation(bVertLayout
, bVertLayoutLRBT
).get())
167 return m_aLeftBorder
;
171 return m_aRightBorder
;
173 return m_aBottomBorder
;
176 return m_aLeftBorder
;
180 const std::optional
<editeng::SvxBorderLine
>&
181 SwFont::GetAbsRightBorder(const bool bVertLayout
, const bool bVertLayoutLRBT
) const
183 switch (GetOrientation(bVertLayout
, bVertLayoutLRBT
).get())
186 return m_aRightBorder
;
188 return m_aBottomBorder
;
190 return m_aLeftBorder
;
195 return m_aRightBorder
;
199 SvxShadowLocation
SwFont::GetAbsShadowLocation(const bool bVertLayout
,
200 const bool bVertLayoutLRBT
) const
202 SvxShadowLocation aLocation
= SvxShadowLocation::NONE
;
203 switch (GetOrientation(bVertLayout
, bVertLayoutLRBT
).get())
206 aLocation
= m_aShadowLocation
;
210 switch ( m_aShadowLocation
)
212 case SvxShadowLocation::TopLeft
:
213 aLocation
= SvxShadowLocation::BottomLeft
;
215 case SvxShadowLocation::TopRight
:
216 aLocation
= SvxShadowLocation::TopLeft
;
218 case SvxShadowLocation::BottomLeft
:
219 aLocation
= SvxShadowLocation::BottomRight
;
221 case SvxShadowLocation::BottomRight
:
222 aLocation
= SvxShadowLocation::TopRight
;
224 case SvxShadowLocation::NONE
:
225 case SvxShadowLocation::End
:
226 aLocation
= m_aShadowLocation
;
232 switch ( m_aShadowLocation
)
234 case SvxShadowLocation::TopLeft
:
235 aLocation
= SvxShadowLocation::BottomRight
;
237 case SvxShadowLocation::TopRight
:
238 aLocation
= SvxShadowLocation::BottomLeft
;
240 case SvxShadowLocation::BottomLeft
:
241 aLocation
= SvxShadowLocation::TopRight
;
243 case SvxShadowLocation::BottomRight
:
244 aLocation
= SvxShadowLocation::TopLeft
;
246 case SvxShadowLocation::NONE
:
247 case SvxShadowLocation::End
:
248 aLocation
= m_aShadowLocation
;
254 switch ( m_aShadowLocation
)
256 case SvxShadowLocation::TopLeft
:
257 aLocation
= SvxShadowLocation::TopRight
;
259 case SvxShadowLocation::TopRight
:
260 aLocation
= SvxShadowLocation::BottomRight
;
262 case SvxShadowLocation::BottomLeft
:
263 aLocation
= SvxShadowLocation::TopLeft
;
265 case SvxShadowLocation::BottomRight
:
266 aLocation
= SvxShadowLocation::BottomLeft
;
268 case SvxShadowLocation::NONE
:
269 case SvxShadowLocation::End
:
270 aLocation
= m_aShadowLocation
;
282 sal_uInt16
SwFont::CalcShadowSpace(const SvxShadowItemSide nShadow
, const bool bVertLayout
,
283 const bool bVertLayoutLRBT
, const bool bSkipLeft
,
284 const bool bSkipRight
) const
286 sal_uInt16 nSpace
= 0;
287 const Degree10 nOrient
= GetOrientation(bVertLayout
, bVertLayoutLRBT
);
288 const SvxShadowLocation aLoc
= GetAbsShadowLocation(bVertLayout
, bVertLayoutLRBT
);
291 case SvxShadowItemSide::TOP
:
292 if(( aLoc
== SvxShadowLocation::TopLeft
||
293 aLoc
== SvxShadowLocation::TopRight
) &&
294 ( nOrient
== 0_deg10
|| nOrient
== 1800_deg10
||
295 ( nOrient
== 900_deg10
&& !bSkipRight
) ||
296 ( nOrient
== 2700_deg10
&& !bSkipLeft
)))
298 nSpace
= m_nShadowWidth
;
302 case SvxShadowItemSide::BOTTOM
:
303 if(( aLoc
== SvxShadowLocation::BottomLeft
||
304 aLoc
== SvxShadowLocation::BottomRight
) &&
305 ( nOrient
== 0_deg10
|| nOrient
== 1800_deg10
||
306 ( nOrient
== 900_deg10
&& !bSkipLeft
) ||
307 ( nOrient
== 2700_deg10
&& !bSkipRight
)))
309 nSpace
= m_nShadowWidth
;
313 case SvxShadowItemSide::LEFT
:
314 if(( aLoc
== SvxShadowLocation::TopLeft
||
315 aLoc
== SvxShadowLocation::BottomLeft
) &&
316 ( nOrient
== 900_deg10
|| nOrient
== 2700_deg10
||
317 ( nOrient
== 0_deg10
&& !bSkipLeft
) ||
318 ( nOrient
== 1800_deg10
&& !bSkipRight
)))
320 nSpace
= m_nShadowWidth
;
324 case SvxShadowItemSide::RIGHT
:
325 if(( aLoc
== SvxShadowLocation::TopRight
||
326 aLoc
== SvxShadowLocation::BottomRight
) &&
327 ( nOrient
== 900_deg10
|| nOrient
== 2700_deg10
||
328 ( nOrient
== 0_deg10
&& !bSkipRight
) ||
329 ( nOrient
== 1800_deg10
&& !bSkipLeft
)))
331 nSpace
= m_nShadowWidth
;
342 // maps directions for vertical layout
343 static Degree10
MapDirection(Degree10 nDir
, const bool bVertFormat
, const bool bVertFormatLRBT
)
347 switch ( nDir
.get() )
361 #if OSL_DEBUG_LEVEL > 0
363 OSL_FAIL( "Unsupported direction" );
371 // maps the absolute direction set at the font to its logical counterpart
372 // in the rotated environment
373 Degree10
UnMapDirection(Degree10 nDir
, const bool bVertFormat
, const bool bVertFormatLRBT
)
383 SAL_WARN("sw.core", "unsupported direction for VertLRBT");
391 switch ( nDir
.get() )
402 #if OSL_DEBUG_LEVEL > 0
404 OSL_FAIL( "Unsupported direction" );
412 Degree10
SwFont::GetOrientation(const bool bVertFormat
, const bool bVertFormatLRBT
) const
414 return UnMapDirection(m_aSub
[m_nActual
].GetOrientation(), bVertFormat
, bVertFormatLRBT
);
417 void SwFont::SetVertical(Degree10 nDir
, const bool bVertFormat
, const bool bVertLayoutLRBT
)
419 // map direction if frame has vertical layout
420 nDir
= MapDirection(nDir
, bVertFormat
, bVertLayoutLRBT
);
422 if( nDir
!= m_aSub
[SwFontScript::Latin
].GetOrientation() )
425 bool bVertical
= bVertFormat
&& !bVertLayoutLRBT
;
426 m_aSub
[SwFontScript::Latin
].SetVertical(nDir
, bVertical
);
427 m_aSub
[SwFontScript::CJK
].SetVertical(nDir
, bVertical
);
428 m_aSub
[SwFontScript::CTL
].SetVertical(nDir
, bVertical
);
434 frEsc: Fraction, ratio of Escapements
435 Esc = resulting Escapement
436 A1 = original Ascent (nOrgAscent)
437 A2 = shrunk Ascent (nEscAscent)
438 Ax = resulting Ascent (GetAscent())
439 H1 = original Height (nOrgHeight)
440 H2 = shrunk Height (nEscHeight)
441 Hx = resulting Height (GetHeight())
442 Bx = resulting Baseline for Text (CalcPos())
455 Hx = A1 + Esc + (H2 - A2);
459 // nEsc is the percentage
460 sal_uInt16
SwSubFont::CalcEscAscent( const sal_uInt16 nOldAscent
) const
462 if( DFLT_ESC_AUTO_SUPER
!= GetEscapement() &&
463 DFLT_ESC_AUTO_SUB
!= GetEscapement() )
465 const tools::Long nAscent
= nOldAscent
+
466 ( static_cast<tools::Long
>(m_nOrgHeight
) * GetEscapement() ) / 100;
468 return std::max
<sal_uInt16
>( nAscent
, m_nOrgAscent
);
473 void SwFont::SetDiffFnt( const SfxItemSet
*pAttrSet
,
474 const IDocumentSettingAccess
*pIDocumentSettingAccess
)
481 if( const SvxFontItem
* pFont
= pAttrSet
->GetItemIfSet( RES_CHRATR_FONT
) )
483 m_aSub
[SwFontScript::Latin
].SetFamily( pFont
->GetFamily() );
484 m_aSub
[SwFontScript::Latin
].Font::SetFamilyName( pFont
->GetFamilyName() );
485 m_aSub
[SwFontScript::Latin
].Font::SetStyleName( pFont
->GetStyleName() );
486 m_aSub
[SwFontScript::Latin
].Font::SetPitch( pFont
->GetPitch() );
487 m_aSub
[SwFontScript::Latin
].Font::SetCharSet( pFont
->GetCharSet() );
489 if( const SvxFontHeightItem
*pHeight
= pAttrSet
->GetItemIfSet( RES_CHRATR_FONTSIZE
) )
491 m_aSub
[SwFontScript::Latin
].SvxFont::SetPropr( 100 );
492 m_aSub
[SwFontScript::Latin
].m_aSize
= m_aSub
[SwFontScript::Latin
].Font::GetFontSize();
493 Size aTmpSize
= m_aSub
[SwFontScript::Latin
].m_aSize
;
494 aTmpSize
.setHeight( pHeight
->GetHeight() );
495 m_aSub
[SwFontScript::Latin
].SetSize( aTmpSize
);
497 if( const SvxPostureItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_POSTURE
) )
498 m_aSub
[SwFontScript::Latin
].Font::SetItalic( pItem
->GetPosture() );
499 if( const SvxWeightItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_WEIGHT
) )
500 m_aSub
[SwFontScript::Latin
].Font::SetWeight( pItem
->GetWeight() );
501 if( const SvxLanguageItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_LANGUAGE
) )
502 m_aSub
[SwFontScript::Latin
].SetLanguage( pItem
->GetLanguage() );
504 if( const SvxFontItem
* pFont
= pAttrSet
->GetItemIfSet( RES_CHRATR_CJK_FONT
) )
506 m_aSub
[SwFontScript::CJK
].SetFamily( pFont
->GetFamily() );
507 m_aSub
[SwFontScript::CJK
].Font::SetFamilyName( pFont
->GetFamilyName() );
508 m_aSub
[SwFontScript::CJK
].Font::SetStyleName( pFont
->GetStyleName() );
509 m_aSub
[SwFontScript::CJK
].Font::SetPitch( pFont
->GetPitch() );
510 m_aSub
[SwFontScript::CJK
].Font::SetCharSet( pFont
->GetCharSet() );
512 if( const SvxFontHeightItem
* pHeight
= pAttrSet
->GetItemIfSet( RES_CHRATR_CJK_FONTSIZE
) )
514 m_aSub
[SwFontScript::CJK
].SvxFont::SetPropr( 100 );
515 m_aSub
[SwFontScript::CJK
].m_aSize
= m_aSub
[SwFontScript::CJK
].Font::GetFontSize();
516 Size aTmpSize
= m_aSub
[SwFontScript::CJK
].m_aSize
;
517 aTmpSize
.setHeight( pHeight
->GetHeight() );
518 m_aSub
[SwFontScript::CJK
].SetSize( aTmpSize
);
520 if( const SvxPostureItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CJK_POSTURE
) )
521 m_aSub
[SwFontScript::CJK
].Font::SetItalic( pItem
->GetPosture() );
522 if( const SvxWeightItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CJK_WEIGHT
) )
523 m_aSub
[SwFontScript::CJK
].Font::SetWeight( pItem
->GetWeight() );
524 if( const SvxLanguageItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CJK_LANGUAGE
) )
526 LanguageType eNewLang
= pItem
->GetLanguage();
527 m_aSub
[SwFontScript::CJK
].SetLanguage( eNewLang
);
528 m_aSub
[SwFontScript::Latin
].SetCJKContextLanguage( eNewLang
);
529 m_aSub
[SwFontScript::CJK
].SetCJKContextLanguage( eNewLang
);
530 m_aSub
[SwFontScript::CTL
].SetCJKContextLanguage( eNewLang
);
533 if( const SvxFontItem
* pFont
= pAttrSet
->GetItemIfSet( RES_CHRATR_CTL_FONT
) )
535 m_aSub
[SwFontScript::CTL
].SetFamily( pFont
->GetFamily() );
536 m_aSub
[SwFontScript::CTL
].Font::SetFamilyName( pFont
->GetFamilyName() );
537 m_aSub
[SwFontScript::CTL
].Font::SetStyleName( pFont
->GetStyleName() );
538 m_aSub
[SwFontScript::CTL
].Font::SetPitch( pFont
->GetPitch() );
539 m_aSub
[SwFontScript::CTL
].Font::SetCharSet( pFont
->GetCharSet() );
541 if( const SvxFontHeightItem
* pHeight
= pAttrSet
->GetItemIfSet( RES_CHRATR_CTL_FONTSIZE
) )
543 m_aSub
[SwFontScript::CTL
].SvxFont::SetPropr( 100 );
544 m_aSub
[SwFontScript::CTL
].m_aSize
= m_aSub
[SwFontScript::CTL
].Font::GetFontSize();
545 Size aTmpSize
= m_aSub
[SwFontScript::CTL
].m_aSize
;
546 aTmpSize
.setHeight( pHeight
->GetHeight() );
547 m_aSub
[SwFontScript::CTL
].SetSize( aTmpSize
);
549 if( const SvxPostureItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CTL_POSTURE
) )
550 m_aSub
[SwFontScript::CTL
].Font::SetItalic(pItem
->GetPosture() );
551 if( const SvxWeightItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CTL_WEIGHT
) )
552 m_aSub
[SwFontScript::CTL
].Font::SetWeight( pItem
->GetWeight() );
553 if( const SvxLanguageItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CTL_LANGUAGE
) )
554 m_aSub
[SwFontScript::CTL
].SetLanguage( pItem
->GetLanguage() );
556 if( const SvxUnderlineItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_UNDERLINE
) )
558 SetUnderline( pItem
->GetLineStyle() );
559 SetUnderColor( pItem
->GetColor() );
561 if( const SvxOverlineItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_OVERLINE
) )
563 SetOverline( pItem
->GetLineStyle() );
564 SetOverColor( pItem
->GetColor() );
566 if( const SvxCrossedOutItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CROSSEDOUT
) )
567 SetStrikeout( pItem
->GetStrikeout() );
568 if( const SvxColorItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_COLOR
) )
569 SetColor( pItem
->GetValue() );
570 if( const SvxEmphasisMarkItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_EMPHASIS_MARK
))
571 SetEmphasisMark( pItem
->GetEmphasisMark() );
573 SetTransparent( true );
574 SetAlign( ALIGN_BASELINE
);
575 if( const SvxContourItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CONTOUR
) )
576 SetOutline( pItem
->GetValue() );
577 if( const SvxShadowedItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_SHADOWED
) )
578 SetShadow( pItem
->GetValue() );
579 if( const SvxCharReliefItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_RELIEF
) )
580 SetRelief( pItem
->GetValue() );
581 if( const SvxShadowedItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_SHADOWED
))
582 SetPropWidth( pItem
->GetValue() ? 50 : 100 );
583 if( const SvxAutoKernItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_AUTOKERN
) )
585 if( pItem
->GetValue() )
587 SetAutoKern( ( !pIDocumentSettingAccess
||
588 !pIDocumentSettingAccess
->get(DocumentSettingId::KERN_ASIAN_PUNCTUATION
) ) ?
589 FontKerning::FontSpecific
:
590 FontKerning::Asian
);
593 SetAutoKern( FontKerning::NONE
);
595 if( const SvxWordLineModeItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_WORDLINEMODE
) )
596 SetWordLineMode( pItem
->GetValue() );
598 if( const SvxEscapementItem
* pEsc
= pAttrSet
->GetItemIfSet( RES_CHRATR_ESCAPEMENT
) )
600 SetEscapement( pEsc
->GetEsc() );
601 if( m_aSub
[SwFontScript::Latin
].IsEsc() )
602 SetProportion( pEsc
->GetProportionalHeight() );
604 if( const SvxCaseMapItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_CASEMAP
) )
605 SetCaseMap( pItem
->GetCaseMap() );
606 if( const SvxKerningItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_KERNING
) )
607 SetFixKerning( pItem
->GetValue() );
608 if( const SvxCharRotateItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_ROTATE
) )
609 SetVertical( pItem
->GetValue() );
610 if( const SvxBrushItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_BACKGROUND
) )
611 mxBackColor
= pItem
->GetColor();
612 if( const SvxBrushItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_HIGHLIGHT
) )
613 SetHighlightColor(pItem
->GetColor());
614 if( const SvxBoxItem
* pBoxItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_BOX
) )
616 SetTopBorder(pBoxItem
->GetTop());
617 SetBottomBorder(pBoxItem
->GetBottom());
618 SetRightBorder(pBoxItem
->GetRight());
619 SetLeftBorder(pBoxItem
->GetLeft());
620 SetTopBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::TOP
));
621 SetBottomBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::BOTTOM
));
622 SetRightBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::RIGHT
));
623 SetLeftBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::LEFT
));
625 if( const SvxShadowItem
* pShadowItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_SHADOW
) )
627 SetShadowColor(pShadowItem
->GetColor());
628 SetShadowWidth(pShadowItem
->GetWidth());
629 SetShadowLocation(pShadowItem
->GetLocation());
631 const SvxTwoLinesItem
* pTwoLinesItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_TWO_LINES
);
632 if( pTwoLinesItem
&& pTwoLinesItem
->GetValue() )
633 SetVertical( 0_deg10
);
639 m_bPaintBlank
= false;
640 OSL_ENSURE( m_aSub
[SwFontScript::Latin
].IsTransparent(), "SwFont: Transparent revolution" );
643 SwFont::SwFont( const SwFont
&rFont
)
644 : m_aSub(rFont
.m_aSub
)
646 m_nActual
= rFont
.m_nActual
;
647 mxBackColor
= rFont
.mxBackColor
;
648 m_aHighlightColor
= rFont
.m_aHighlightColor
;
649 m_aTopBorder
= rFont
.m_aTopBorder
;
650 m_aBottomBorder
= rFont
.m_aBottomBorder
;
651 m_aRightBorder
= rFont
.m_aRightBorder
;
652 m_aLeftBorder
= rFont
.m_aLeftBorder
;
653 m_nTopBorderDist
= rFont
.m_nTopBorderDist
;
654 m_nBottomBorderDist
= rFont
.m_nBottomBorderDist
;
655 m_nRightBorderDist
= rFont
.m_nRightBorderDist
;
656 m_nLeftBorderDist
= rFont
.m_nLeftBorderDist
;
657 m_aShadowColor
= rFont
.m_aShadowColor
;
658 m_nShadowWidth
= rFont
.m_nShadowWidth
;
659 m_aShadowLocation
= rFont
.m_aShadowLocation
;
660 m_aUnderColor
= rFont
.GetUnderColor();
661 m_aOverColor
= rFont
.GetOverColor();
665 m_nContentControlCount
= 0;
666 m_nInputFieldCount
= 0;
667 m_bFontChg
= rFont
.m_bFontChg
;
668 m_bOrgChg
= rFont
.m_bOrgChg
;
669 m_bPaintBlank
= rFont
.m_bPaintBlank
;
670 m_bGreyWave
= rFont
.m_bGreyWave
;
673 SwFont::SwFont( const SwAttrSet
* pAttrSet
,
674 const IDocumentSettingAccess
* pIDocumentSettingAccess
)
677 m_nActual
= SwFontScript::Latin
;
681 m_nContentControlCount
= 0;
682 m_nInputFieldCount
= 0;
683 m_bPaintBlank
= false;
687 const SvxFontItem
& rFont
= pAttrSet
->GetFont();
688 m_aSub
[SwFontScript::Latin
].SetFamily( rFont
.GetFamily() );
689 m_aSub
[SwFontScript::Latin
].SetFamilyName( rFont
.GetFamilyName() );
690 m_aSub
[SwFontScript::Latin
].SetStyleName( rFont
.GetStyleName() );
691 m_aSub
[SwFontScript::Latin
].SetPitch( rFont
.GetPitch() );
692 m_aSub
[SwFontScript::Latin
].SetCharSet( rFont
.GetCharSet() );
693 m_aSub
[SwFontScript::Latin
].SvxFont::SetPropr( 100 ); // 100% of FontSize
694 Size aTmpSize
= m_aSub
[SwFontScript::Latin
].m_aSize
;
695 aTmpSize
.setHeight( pAttrSet
->GetSize().GetHeight() );
696 m_aSub
[SwFontScript::Latin
].SetSize( aTmpSize
);
697 m_aSub
[SwFontScript::Latin
].SetItalic( pAttrSet
->GetPosture().GetPosture() );
698 m_aSub
[SwFontScript::Latin
].SetWeight( pAttrSet
->GetWeight().GetWeight() );
699 m_aSub
[SwFontScript::Latin
].SetLanguage( pAttrSet
->GetLanguage().GetLanguage() );
703 const SvxFontItem
& rFont
= pAttrSet
->GetCJKFont();
704 m_aSub
[SwFontScript::CJK
].SetFamily( rFont
.GetFamily() );
705 m_aSub
[SwFontScript::CJK
].SetFamilyName( rFont
.GetFamilyName() );
706 m_aSub
[SwFontScript::CJK
].SetStyleName( rFont
.GetStyleName() );
707 m_aSub
[SwFontScript::CJK
].SetPitch( rFont
.GetPitch() );
708 m_aSub
[SwFontScript::CJK
].SetCharSet( rFont
.GetCharSet() );
709 m_aSub
[SwFontScript::CJK
].SvxFont::SetPropr( 100 ); // 100% of FontSize
710 Size aTmpSize
= m_aSub
[SwFontScript::CJK
].m_aSize
;
711 aTmpSize
.setHeight( pAttrSet
->GetCJKSize().GetHeight() );
712 m_aSub
[SwFontScript::CJK
].SetSize( aTmpSize
);
713 m_aSub
[SwFontScript::CJK
].SetItalic( pAttrSet
->GetCJKPosture().GetPosture() );
714 m_aSub
[SwFontScript::CJK
].SetWeight( pAttrSet
->GetCJKWeight().GetWeight() );
715 LanguageType eNewLang
= pAttrSet
->GetCJKLanguage().GetLanguage();
716 m_aSub
[SwFontScript::CJK
].SetLanguage( eNewLang
);
717 m_aSub
[SwFontScript::Latin
].SetCJKContextLanguage( eNewLang
);
718 m_aSub
[SwFontScript::CJK
].SetCJKContextLanguage( eNewLang
);
719 m_aSub
[SwFontScript::CTL
].SetCJKContextLanguage( eNewLang
);
723 const SvxFontItem
& rFont
= pAttrSet
->GetCTLFont();
724 m_aSub
[SwFontScript::CTL
].SetFamily( rFont
.GetFamily() );
725 m_aSub
[SwFontScript::CTL
].SetFamilyName( rFont
.GetFamilyName() );
726 m_aSub
[SwFontScript::CTL
].SetStyleName( rFont
.GetStyleName() );
727 m_aSub
[SwFontScript::CTL
].SetPitch( rFont
.GetPitch() );
728 m_aSub
[SwFontScript::CTL
].SetCharSet( rFont
.GetCharSet() );
729 m_aSub
[SwFontScript::CTL
].SvxFont::SetPropr( 100 ); // 100% of FontSize
730 Size aTmpSize
= m_aSub
[SwFontScript::CTL
].m_aSize
;
731 aTmpSize
.setHeight( pAttrSet
->GetCTLSize().GetHeight() );
732 m_aSub
[SwFontScript::CTL
].SetSize( aTmpSize
);
733 m_aSub
[SwFontScript::CTL
].SetItalic( pAttrSet
->GetCTLPosture().GetPosture() );
734 m_aSub
[SwFontScript::CTL
].SetWeight( pAttrSet
->GetCTLWeight().GetWeight() );
735 m_aSub
[SwFontScript::CTL
].SetLanguage( pAttrSet
->GetCTLLanguage().GetLanguage() );
737 if ( pAttrSet
->GetCharHidden().GetValue() )
738 SetUnderline( LINESTYLE_DOTTED
);
740 SetUnderline( pAttrSet
->GetUnderline().GetLineStyle() );
741 SetUnderColor( pAttrSet
->GetUnderline().GetColor() );
742 SetOverline( pAttrSet
->GetOverline().GetLineStyle() );
743 SetOverColor( pAttrSet
->GetOverline().GetColor() );
744 SetEmphasisMark( pAttrSet
->GetEmphasisMark().GetEmphasisMark() );
745 SetStrikeout( pAttrSet
->GetCrossedOut().GetStrikeout() );
746 SetColor( pAttrSet
->GetColor().GetValue() );
747 SetTransparent( true );
748 SetAlign( ALIGN_BASELINE
);
749 SetOutline( pAttrSet
->GetContour().GetValue() );
750 SetShadow( pAttrSet
->GetShadowed().GetValue() );
751 SetPropWidth( pAttrSet
->GetCharScaleW().GetValue() );
752 SetRelief( pAttrSet
->GetCharRelief().GetValue() );
753 if( pAttrSet
->GetAutoKern().GetValue() )
755 SetAutoKern( ( !pIDocumentSettingAccess
||
756 !pIDocumentSettingAccess
->get(DocumentSettingId::KERN_ASIAN_PUNCTUATION
) ) ?
757 FontKerning::FontSpecific
:
758 FontKerning::Asian
);
761 SetAutoKern( FontKerning::NONE
);
762 SetWordLineMode( pAttrSet
->GetWordLineMode().GetValue() );
763 const SvxEscapementItem
&rEsc
= pAttrSet
->GetEscapement();
764 SetEscapement( rEsc
.GetEsc() );
765 if( m_aSub
[SwFontScript::Latin
].IsEsc() )
766 SetProportion( rEsc
.GetProportionalHeight() );
767 SetCaseMap( pAttrSet
->GetCaseMap().GetCaseMap() );
768 SetFixKerning( pAttrSet
->GetKerning().GetValue() );
769 if( const SvxBrushItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_BACKGROUND
) )
770 mxBackColor
= pItem
->GetColor();
771 if( const SvxBrushItem
* pItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_HIGHLIGHT
) )
772 SetHighlightColor(pItem
->GetColor());
774 SetHighlightColor(COL_TRANSPARENT
);
775 if( const SvxBoxItem
* pBoxItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_BOX
) )
777 SetTopBorder(pBoxItem
->GetTop());
778 SetBottomBorder(pBoxItem
->GetBottom());
779 SetRightBorder(pBoxItem
->GetRight());
780 SetLeftBorder(pBoxItem
->GetLeft());
781 SetTopBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::TOP
));
782 SetBottomBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::BOTTOM
));
783 SetRightBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::RIGHT
));
784 SetLeftBorderDist(pBoxItem
->GetDistance(SvxBoxItemLine::LEFT
));
788 SetTopBorder(nullptr);
789 SetBottomBorder(nullptr);
790 SetRightBorder(nullptr);
791 SetLeftBorder(nullptr);
793 SetBottomBorderDist(0);
794 SetRightBorderDist(0);
795 SetLeftBorderDist(0);
798 if( const SvxShadowItem
* pShadowItem
= pAttrSet
->GetItemIfSet( RES_CHRATR_SHADOW
) )
800 SetShadowColor(pShadowItem
->GetColor());
801 SetShadowWidth(pShadowItem
->GetWidth());
802 SetShadowLocation(pShadowItem
->GetLocation());
806 SetShadowColor(COL_TRANSPARENT
);
808 SetShadowLocation(SvxShadowLocation::NONE
);
811 const SvxTwoLinesItem
& rTwoLinesItem
= pAttrSet
->Get2Lines();
812 if ( ! rTwoLinesItem
.GetValue() )
813 SetVertical( pAttrSet
->GetCharRotate().GetValue() );
815 SetVertical( 0_deg10
);
816 if( pIDocumentSettingAccess
&& pIDocumentSettingAccess
->get( DocumentSettingId::SMALL_CAPS_PERCENTAGE_66
))
818 m_aSub
[ SwFontScript::Latin
].m_bSmallCapsPercentage66
= true;
819 m_aSub
[ SwFontScript::CJK
].m_bSmallCapsPercentage66
= true;
820 m_aSub
[ SwFontScript::CTL
].m_bSmallCapsPercentage66
= true;
828 SwFont
& SwFont::operator=( const SwFont
&rFont
)
832 m_aSub
[SwFontScript::Latin
] = rFont
.m_aSub
[SwFontScript::Latin
];
833 m_aSub
[SwFontScript::CJK
] = rFont
.m_aSub
[SwFontScript::CJK
];
834 m_aSub
[SwFontScript::CTL
] = rFont
.m_aSub
[SwFontScript::CTL
];
835 m_nActual
= rFont
.m_nActual
;
836 mxBackColor
= rFont
.mxBackColor
;
837 m_aHighlightColor
= rFont
.m_aHighlightColor
;
838 m_aTopBorder
= rFont
.m_aTopBorder
;
839 m_aBottomBorder
= rFont
.m_aBottomBorder
;
840 m_aRightBorder
= rFont
.m_aRightBorder
;
841 m_aLeftBorder
= rFont
.m_aLeftBorder
;
842 m_nTopBorderDist
= rFont
.m_nTopBorderDist
;
843 m_nBottomBorderDist
= rFont
.m_nBottomBorderDist
;
844 m_nRightBorderDist
= rFont
.m_nRightBorderDist
;
845 m_nLeftBorderDist
= rFont
.m_nLeftBorderDist
;
846 m_aShadowColor
= rFont
.m_aShadowColor
;
847 m_nShadowWidth
= rFont
.m_nShadowWidth
;
848 m_aShadowLocation
= rFont
.m_aShadowLocation
;
849 m_aUnderColor
= rFont
.GetUnderColor();
850 m_aOverColor
= rFont
.GetOverColor();
854 m_nContentControlCount
= 0;
855 m_nInputFieldCount
= 0;
856 m_bFontChg
= rFont
.m_bFontChg
;
857 m_bOrgChg
= rFont
.m_bOrgChg
;
858 m_bPaintBlank
= rFont
.m_bPaintBlank
;
859 m_bGreyWave
= rFont
.m_bGreyWave
;
864 void SwFont::AllocFontCacheId( SwViewShell
const *pSh
, SwFontScript nWhich
)
866 SwFntAccess
aFntAccess( m_aSub
[nWhich
].m_nFontCacheId
, m_aSub
[nWhich
].m_nFontIndex
,
867 &m_aSub
[nWhich
], pSh
, true );
870 bool SwSubFont::IsSymbol( SwViewShell
const *pSh
)
872 SwFntAccess
aFntAccess( m_nFontCacheId
, m_nFontIndex
, this, pSh
, false );
873 return aFntAccess
.Get()->IsSymbol();
876 bool SwSubFont::ChgFnt( SwViewShell
const *pSh
, OutputDevice
& rOut
)
880 SwFntAccess
aFntAccess( m_nFontCacheId
, m_nFontIndex
, this, pSh
, true );
881 SV_STAT( nChangeFont
);
883 pLastFont
= aFntAccess
.Get();
885 pLastFont
->SetDevFont( pSh
, rOut
);
888 return LINESTYLE_NONE
!= GetUnderline() ||
889 LINESTYLE_NONE
!= GetOverline() ||
890 STRIKEOUT_NONE
!= GetStrikeout();
893 void SwFont::ChgPhysFnt( SwViewShell
const *pSh
, OutputDevice
& rOut
)
895 if( m_bOrgChg
&& m_aSub
[m_nActual
].IsEsc() )
897 const sal_uInt8 nOldProp
= m_aSub
[m_nActual
].GetPropr();
898 SetProportion( 100 );
900 SwFntAccess
aFntAccess( m_aSub
[m_nActual
].m_nFontCacheId
, m_aSub
[m_nActual
].m_nFontIndex
,
901 &m_aSub
[m_nActual
], pSh
);
902 m_aSub
[m_nActual
].m_nOrgHeight
= aFntAccess
.Get()->GetFontHeight( pSh
, rOut
);
903 m_aSub
[m_nActual
].m_nOrgAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
904 SetProportion( nOldProp
);
911 m_bFontChg
= m_bOrgChg
;
913 if( rOut
.GetTextLineColor() != m_aUnderColor
)
914 rOut
.SetTextLineColor( m_aUnderColor
);
915 if( rOut
.GetOverlineColor() != m_aOverColor
)
916 rOut
.SetOverlineColor( m_aOverColor
);
919 // Height = MaxAscent + MaxDescent
920 // MaxAscent = Max (T1_ascent, T2_ascent + (Esc * T1_height) );
921 // MaxDescent = Max (T1_height-T1_ascent,
922 // T2_height-T2_ascent - (Esc * T1_height)
923 sal_uInt16
SwSubFont::CalcEscHeight( const sal_uInt16 nOldHeight
,
924 const sal_uInt16 nOldAscent
) const
926 if( DFLT_ESC_AUTO_SUPER
!= GetEscapement() &&
927 DFLT_ESC_AUTO_SUB
!= GetEscapement() )
929 tools::Long nDescent
= nOldHeight
- nOldAscent
-
930 ( static_cast<tools::Long
>(m_nOrgHeight
) * GetEscapement() ) / 100;
931 const sal_uInt16 nDesc
= nDescent
>0
932 ? std::max
<sal_uInt16
>( nDescent
, m_nOrgHeight
- m_nOrgAscent
)
933 : m_nOrgHeight
- m_nOrgAscent
;
934 return ( nDesc
+ CalcEscAscent( nOldAscent
) );
939 short SwSubFont::CheckKerning_( )
941 short nKernx
= - short( Font::GetFontSize().Height() / 6 );
943 if ( nKernx
< GetFixKerning() )
944 return GetFixKerning();
948 sal_uInt16
SwSubFont::GetAscent( SwViewShell
const *pSh
, const OutputDevice
& rOut
)
950 SwFntAccess
aFntAccess( m_nFontCacheId
, m_nFontIndex
, this, pSh
);
951 const sal_uInt16 nAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
952 return GetEscapement() ? CalcEscAscent( nAscent
) : nAscent
;
955 sal_uInt16
SwSubFont::GetHeight( SwViewShell
const *pSh
, const OutputDevice
& rOut
)
957 SV_STAT( nGetTextSize
);
958 SwFntAccess
aFntAccess( m_nFontCacheId
, m_nFontIndex
, this, pSh
);
959 const sal_uInt16 nHeight
= aFntAccess
.Get()->GetFontHeight( pSh
, rOut
);
960 if ( GetEscapement() )
962 const sal_uInt16 nAscent
= aFntAccess
.Get()->GetFontAscent( pSh
, rOut
);
963 return CalcEscHeight( nHeight
, nAscent
); // + nLeading;
965 return nHeight
; // + nLeading;
968 sal_uInt16
SwSubFont::GetHangingBaseline( SwViewShell
const *pSh
, const OutputDevice
& rOut
)
970 SwFntAccess
aFntAccess( m_nFontCacheId
, m_nFontIndex
, this, pSh
);
971 return aFntAccess
.Get()->GetFontHangingBaseline( pSh
, rOut
);
974 Size
SwSubFont::GetTextSize_( SwDrawTextInfo
& rInf
)
976 // Robust: the font is supposed to be set already, but better safe than
978 if ( !pLastFont
|| pLastFont
->GetOwner() != m_nFontCacheId
||
979 !IsSameInstance( rInf
.GetpOut()->GetFont() ) )
980 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
982 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
985 TextFrameIndex
const nLn
= rInf
.GetLen() == TextFrameIndex(COMPLETE_STRING
)
986 ? TextFrameIndex(rInf
.GetText().getLength())
990 if( IsCapital() && nLn
)
992 if (rInf
.GetMeasureLen() != TextFrameIndex(COMPLETE_STRING
))
994 rInf
.SetLen(rInf
.GetMeasureLen());
995 rInf
.SetMeasureLen(TextFrameIndex(COMPLETE_STRING
));
997 aTextSize
= GetCapitalSize( rInf
);
1001 SV_STAT( nGetTextSize
);
1002 tools::Long nOldKern
= rInf
.GetKern();
1003 const OUString oldText
= rInf
.GetText();
1004 rInf
.SetKern( CheckKerning() );
1006 aTextSize
= pLastFont
->GetTextSize( rInf
);
1009 const OUString aTmp
= CalcCaseMap( rInf
.GetText() );
1010 const OUString oldStr
= rInf
.GetText();
1011 bool bCaseMapLengthDiffers(aTmp
.getLength() != oldStr
.getLength());
1013 if(bCaseMapLengthDiffers
&& rInf
.GetLen())
1015 // If the length of the original string and the CaseMapped one
1016 // are different, it is necessary to handle the given text part as
1017 // a single snippet since its size may differ, too.
1018 TextFrameIndex
const nOldIdx(rInf
.GetIdx());
1019 TextFrameIndex
const nOldLen(rInf
.GetLen());
1020 TextFrameIndex
const nOldMeasureLen(rInf
.GetMeasureLen());
1021 const OUString
aSnippet(oldStr
.copy(sal_Int32(nOldIdx
), sal_Int32(nOldLen
)));
1022 const OUString
aNewText(CalcCaseMap(aSnippet
));
1024 rInf
.SetText( aNewText
);
1025 rInf
.SetIdx( TextFrameIndex(0) );
1026 rInf
.SetLen( TextFrameIndex(aNewText
.getLength()) );
1027 if (nOldMeasureLen
!= TextFrameIndex(COMPLETE_STRING
))
1029 const OUString
aMeasureSnippet(oldStr
.copy(sal_Int32(nOldIdx
), sal_Int32(nOldMeasureLen
)));
1030 const OUString
aNewMeasureText(CalcCaseMap(aMeasureSnippet
));
1031 rInf
.SetMeasureLen(TextFrameIndex(aNewMeasureText
.getLength()));
1034 aTextSize
= pLastFont
->GetTextSize( rInf
);
1036 rInf
.SetIdx( nOldIdx
);
1037 rInf
.SetLen( nOldLen
);
1038 rInf
.SetMeasureLen(nOldMeasureLen
);
1042 rInf
.SetText( aTmp
);
1043 aTextSize
= pLastFont
->GetTextSize( rInf
);
1046 rInf
.SetText(oldStr
);
1048 rInf
.SetKern( nOldKern
);
1049 rInf
.SetText(oldText
);
1050 // A word that's longer than one line, with escapement at the line
1051 // break, must report its effective height.
1052 if( GetEscapement() )
1054 const sal_uInt16 nAscent
= pLastFont
->GetFontAscent( rInf
.GetShell(),
1056 aTextSize
.setHeight(
1057 static_cast<tools::Long
>(CalcEscHeight( o3tl::narrowing
<sal_uInt16
>(aTextSize
.Height()), nAscent
)) );
1061 if (TextFrameIndex(1) == rInf
.GetLen()
1062 && CH_TXT_ATR_FIELDSTART
== rInf
.GetText()[sal_Int32(rInf
.GetIdx())])
1064 SAL_WARN("sw", "this is meant to be dead code");
1065 TextFrameIndex
const nOldIdx(rInf
.GetIdx());
1066 TextFrameIndex
const nOldLen(rInf
.GetLen());
1067 OUString
aOldText(rInf
.GetText());
1068 const OUString
aNewText(CH_TXT_ATR_SUBST_FIELDSTART
);
1069 rInf
.SetTextIdxLen(aNewText
, TextFrameIndex(0), TextFrameIndex(aNewText
.getLength()));
1070 aTextSize
= pLastFont
->GetTextSize( rInf
);
1071 rInf
.SetTextIdxLen(aOldText
, nOldIdx
, nOldLen
);
1073 else if (TextFrameIndex(1) == rInf
.GetLen()
1074 && CH_TXT_ATR_FIELDEND
== rInf
.GetText()[sal_Int32(rInf
.GetIdx())])
1076 SAL_WARN("sw", "this is meant to be dead code");
1077 TextFrameIndex
const nOldIdx(rInf
.GetIdx());
1078 TextFrameIndex
const nOldLen(rInf
.GetLen());
1079 OUString
aOldText(rInf
.GetText());
1080 const OUString
aNewText(CH_TXT_ATR_SUBST_FIELDEND
);
1081 rInf
.SetTextIdxLen(aNewText
, TextFrameIndex(0), TextFrameIndex(aNewText
.getLength()));
1082 aTextSize
= pLastFont
->GetTextSize( rInf
);
1083 rInf
.SetTextIdxLen(aOldText
, nOldIdx
, nOldLen
);
1089 void SwSubFont::DrawText_( SwDrawTextInfo
&rInf
, const bool bGrey
)
1091 rInf
.SetGreyWave( bGrey
);
1092 TextFrameIndex
const nLn(rInf
.GetText().getLength());
1093 if( !rInf
.GetLen() || !nLn
)
1095 if (TextFrameIndex(COMPLETE_STRING
) == rInf
.GetLen())
1098 FontLineStyle nOldUnder
= LINESTYLE_NONE
;
1099 SwUnderlineFont
* pUnderFnt
= nullptr;
1101 if( rInf
.GetUnderFnt() )
1103 nOldUnder
= GetUnderline();
1104 SetUnderline( LINESTYLE_NONE
);
1105 pUnderFnt
= rInf
.GetUnderFnt();
1108 if( !pLastFont
|| pLastFont
->GetOwner() != m_nFontCacheId
)
1109 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
1111 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
1113 const Point
aOldPos(rInf
.GetPos());
1114 Point
aPos( rInf
.GetPos() );
1116 if( GetEscapement() )
1117 CalcEsc( rInf
, aPos
);
1119 rInf
.SetPos( aPos
);
1120 rInf
.SetKern( CheckKerning() + rInf
.GetCharacterSpacing() / SPACING_PRECISION_FACTOR
);
1123 DrawCapital( rInf
);
1126 SV_STAT( nDrawText
);
1128 pLastFont
->DrawText( rInf
);
1131 const OUString oldStr
= rInf
.GetText();
1132 const OUString
aString( CalcCaseMap(oldStr
) );
1133 bool bCaseMapLengthDiffers(aString
.getLength() != oldStr
.getLength());
1135 if(bCaseMapLengthDiffers
&& rInf
.GetLen())
1137 // If the length of the original string and the CaseMapped one
1138 // are different, it is necessary to handle the given text part as
1139 // a single snippet since its size may differ, too.
1140 TextFrameIndex
const nOldIdx(rInf
.GetIdx());
1141 TextFrameIndex
const nOldLen(rInf
.GetLen());
1142 const OUString
aSnippet(oldStr
.copy(sal_Int32(nOldIdx
), sal_Int32(nOldLen
)));
1143 const OUString aNewText
= CalcCaseMap(aSnippet
);
1145 rInf
.SetText( aNewText
);
1146 rInf
.SetIdx( TextFrameIndex(0) );
1147 rInf
.SetLen( TextFrameIndex(aNewText
.getLength()) );
1149 pLastFont
->DrawText( rInf
);
1151 rInf
.SetIdx( nOldIdx
);
1152 rInf
.SetLen( nOldLen
);
1156 rInf
.SetText( aString
);
1157 pLastFont
->DrawText( rInf
);
1160 rInf
.SetText(oldStr
);
1164 if( pUnderFnt
&& nOldUnder
!= LINESTYLE_NONE
)
1166 Size aFontSize
= GetTextSize_( rInf
);
1167 const OUString oldStr
= rInf
.GetText();
1169 TextFrameIndex
const nOldIdx
= rInf
.GetIdx();
1170 TextFrameIndex
const nOldLen
= rInf
.GetLen();
1171 tools::Long nSpace
= 0;
1172 if( rInf
.GetSpace() )
1174 TextFrameIndex nTmpEnd
= nOldIdx
+ nOldLen
;
1175 if (nTmpEnd
> TextFrameIndex(oldStr
.getLength()))
1176 nTmpEnd
= TextFrameIndex(oldStr
.getLength());
1178 const SwScriptInfo
* pSI
= rInf
.GetScriptInfo();
1180 const bool bAsianFont
=
1181 ( rInf
.GetFont() && SwFontScript::CJK
== rInf
.GetFont()->GetActual() );
1182 for (TextFrameIndex nTmp
= nOldIdx
; nTmp
< nTmpEnd
; ++nTmp
)
1184 if (CH_BLANK
== oldStr
[sal_Int32(nTmp
)] || bAsianFont
||
1185 (nTmp
+ TextFrameIndex(1) < TextFrameIndex(oldStr
.getLength())
1187 && i18n::ScriptType::ASIAN
== pSI
->ScriptType(nTmp
+ TextFrameIndex(1))))
1193 // if next portion if a hole portion we do not consider any
1194 // extra space added because the last character was ASIAN
1195 if ( nSpace
&& rInf
.IsSpaceStop() && bAsianFont
)
1198 nSpace
*= rInf
.GetSpace() / SPACING_PRECISION_FACTOR
;
1201 rInf
.SetWidth( sal_uInt16(aFontSize
.Width() + nSpace
) );
1202 rInf
.SetTextIdxLen( " ", TextFrameIndex(0), TextFrameIndex(2) );
1203 SetUnderline( nOldUnder
);
1204 rInf
.SetUnderFnt( nullptr );
1206 // set position for underline font
1207 rInf
.SetPos( pUnderFnt
->GetPos() );
1209 pUnderFnt
->GetFont().DrawStretchText_( rInf
);
1211 rInf
.SetUnderFnt( pUnderFnt
);
1212 rInf
.SetTextIdxLen(oldStr
, nOldIdx
, nOldLen
);
1215 rInf
.SetPos(aOldPos
);
1218 void SwSubFont::DrawStretchText_( SwDrawTextInfo
&rInf
)
1220 if( !rInf
.GetLen() || !rInf
.GetText().getLength() )
1223 FontLineStyle nOldUnder
= LINESTYLE_NONE
;
1224 SwUnderlineFont
* pUnderFnt
= nullptr;
1226 if( rInf
.GetUnderFnt() )
1228 nOldUnder
= GetUnderline();
1229 SetUnderline( LINESTYLE_NONE
);
1230 pUnderFnt
= rInf
.GetUnderFnt();
1233 if ( !pLastFont
|| pLastFont
->GetOwner() != m_nFontCacheId
)
1234 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
1236 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
1238 rInf
.ApplyAutoColor();
1240 const Point
aOldPos(rInf
.GetPos());
1241 Point
aPos( rInf
.GetPos() );
1243 if( GetEscapement() )
1244 CalcEsc( rInf
, aPos
);
1246 rInf
.SetKern( CheckKerning() + rInf
.GetCharacterSpacing() / SPACING_PRECISION_FACTOR
);
1247 rInf
.SetPos( aPos
);
1250 DrawStretchCapital( rInf
);
1253 SV_STAT( nDrawStretchText
);
1255 if ( rInf
.GetFrame() )
1257 if ( rInf
.GetFrame()->IsRightToLeft() )
1258 rInf
.GetFrame()->SwitchLTRtoRTL( aPos
);
1260 if ( rInf
.GetFrame()->IsVertical() )
1261 rInf
.GetFrame()->SwitchHorizontalToVertical( aPos
);
1263 rInf
.SetPos( aPos
);
1267 rInf
.GetOut().DrawStretchText( aPos
, rInf
.GetWidth(),
1268 rInf
.GetText(), sal_Int32(rInf
.GetIdx()), sal_Int32(rInf
.GetLen()));
1270 rInf
.GetOut().DrawStretchText( aPos
, rInf
.GetWidth(),
1271 CalcCaseMap(rInf
.GetText()),
1272 sal_Int32(rInf
.GetIdx()), sal_Int32(rInf
.GetLen()));
1275 if( pUnderFnt
&& nOldUnder
!= LINESTYLE_NONE
)
1277 const OUString oldStr
= rInf
.GetText();
1278 TextFrameIndex
const nOldIdx
= rInf
.GetIdx();
1279 TextFrameIndex
const nOldLen
= rInf
.GetLen();
1280 rInf
.SetTextIdxLen( " ", TextFrameIndex(0), TextFrameIndex(2) );
1281 SetUnderline( nOldUnder
);
1282 rInf
.SetUnderFnt( nullptr );
1284 // set position for underline font
1285 rInf
.SetPos( pUnderFnt
->GetPos() );
1287 pUnderFnt
->GetFont().DrawStretchText_( rInf
);
1289 rInf
.SetUnderFnt( pUnderFnt
);
1290 rInf
.SetTextIdxLen(oldStr
, nOldIdx
, nOldLen
);
1293 rInf
.SetPos(aOldPos
);
1296 TextFrameIndex
SwSubFont::GetModelPositionForViewPoint_( SwDrawTextInfo
& rInf
)
1298 if ( !pLastFont
|| pLastFont
->GetOwner() != m_nFontCacheId
)
1299 ChgFnt( rInf
.GetShell(), rInf
.GetOut() );
1301 SwDigitModeModifier
aDigitModeModifier( rInf
.GetOut(), rInf
.GetFont()->GetLanguage() );
1303 TextFrameIndex
const nLn
= rInf
.GetLen() == TextFrameIndex(COMPLETE_STRING
)
1304 ? TextFrameIndex(rInf
.GetText().getLength())
1307 TextFrameIndex
nCursor(0);
1308 if( IsCapital() && nLn
)
1309 nCursor
= GetCapitalCursorOfst( rInf
);
1312 const OUString oldText
= rInf
.GetText();
1313 tools::Long nOldKern
= rInf
.GetKern();
1314 rInf
.SetKern( CheckKerning() );
1315 SV_STAT( nGetTextSize
);
1317 nCursor
= pLastFont
->GetModelPositionForViewPoint( rInf
);
1320 rInf
.SetText( CalcCaseMap( rInf
.GetText() ) );
1321 nCursor
= pLastFont
->GetModelPositionForViewPoint( rInf
);
1323 rInf
.SetKern( nOldKern
);
1324 rInf
.SetText(oldText
);
1329 void SwSubFont::CalcEsc( SwDrawTextInfo
const & rInf
, Point
& rPos
)
1334 bool bVertLRBT
= false;
1335 if (rInf
.GetFrame())
1337 bVert
= rInf
.GetFrame()->IsVertical();
1338 bVertLRBT
= rInf
.GetFrame()->IsVertLRBT();
1340 const Degree10 nDir
= UnMapDirection(GetOrientation(), bVert
, bVertLRBT
);
1342 switch ( GetEscapement() )
1344 case DFLT_ESC_AUTO_SUB
:
1345 nOfst
= m_nOrgHeight
- m_nOrgAscent
-
1346 pLastFont
->GetFontHeight( rInf
.GetShell(), rInf
.GetOut() ) +
1347 pLastFont
->GetFontAscent( rInf
.GetShell(), rInf
.GetOut() );
1349 switch ( nDir
.get() )
1352 rPos
.AdjustY(nOfst
);
1355 rPos
.AdjustX(nOfst
);
1358 rPos
.AdjustX( -nOfst
);
1363 case DFLT_ESC_AUTO_SUPER
:
1364 nOfst
= pLastFont
->GetFontAscent( rInf
.GetShell(), rInf
.GetOut() ) -
1367 switch ( nDir
.get() )
1370 rPos
.AdjustY(nOfst
);
1373 rPos
.AdjustX(nOfst
);
1376 rPos
.AdjustX( -nOfst
);
1382 nOfst
= (static_cast<tools::Long
>(m_nOrgHeight
) * GetEscapement()) / 100;
1384 switch ( nDir
.get() )
1387 rPos
.AdjustY( -nOfst
);
1390 rPos
.AdjustX( -nOfst
);
1393 rPos
.AdjustX(nOfst
);
1399 // used during painting of small capitals
1400 void SwDrawTextInfo::Shift( Degree10 nDir
)
1403 OSL_ENSURE( m_bPos
, "DrawTextInfo: Undefined Position" );
1404 OSL_ENSURE( m_bSize
, "DrawTextInfo: Undefined Width" );
1407 const bool bBidiPor
= ( GetFrame() && GetFrame()->IsRightToLeft() ) !=
1408 ( vcl::text::ComplexTextLayoutFlags::Default
!= ( vcl::text::ComplexTextLayoutFlags::BiDiRtl
& GetpOut()->GetLayoutMode() ) );
1411 bool bVertLRBT
= false;
1414 bVert
= GetFrame()->IsVertical();
1415 bVertLRBT
= GetFrame()->IsVertLRBT();
1417 nDir
= bBidiPor
? 1800_deg10
: UnMapDirection(nDir
, bVert
, bVertLRBT
);
1419 switch ( nDir
.get() )
1422 m_aPos
.AdjustX(GetSize().Width() );
1425 OSL_ENSURE( m_aPos
.Y() >= GetSize().Width(), "Going underground" );
1426 m_aPos
.AdjustY( -(GetSize().Width()) );
1429 m_aPos
.AdjustX( -(GetSize().Width()) );
1432 m_aPos
.AdjustY(GetSize().Width() );
1438 * @note Used for the "continuous underline" feature.
1440 SwUnderlineFont::SwUnderlineFont(SwFont
& rFnt
, TextFrameIndex
const nEnd
, const Point
& rPoint
)
1441 : m_aPos( rPoint
), m_nEnd( nEnd
), m_pFont( &rFnt
)
1445 SwUnderlineFont::~SwUnderlineFont()
1449 /// Helper for filters to find true lineheight of a font
1450 tools::Long
AttrSetToLineHeight( const IDocumentSettingAccess
& rIDocumentSettingAccess
,
1451 const SwAttrSet
&rSet
,
1452 const vcl::RenderContext
&rOut
, sal_Int16 nScript
)
1454 SwFont
aFont(&rSet
, &rIDocumentSettingAccess
);
1455 SwFontScript nActual
;
1459 case i18n::ScriptType::LATIN
:
1460 nActual
= SwFontScript::Latin
;
1462 case i18n::ScriptType::ASIAN
:
1463 nActual
= SwFontScript::CJK
;
1465 case i18n::ScriptType::COMPLEX
:
1466 nActual
= SwFontScript::CTL
;
1469 aFont
.SetActual(nActual
);
1471 vcl::RenderContext
&rMutableOut
= const_cast<vcl::RenderContext
&>(rOut
);
1472 const vcl::Font
aOldFont(rMutableOut
.GetFont());
1474 rMutableOut
.SetFont(aFont
.GetActualFont());
1475 tools::Long nHeight
= rMutableOut
.GetTextHeight();
1477 rMutableOut
.SetFont(aOldFont
);
1481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */