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 "atrhndl.hxx"
21 #include <svl/itemiter.hxx>
22 #include <vcl/outdev.hxx>
23 #include <editeng/cmapitem.hxx>
24 #include <editeng/colritem.hxx>
25 #include <editeng/contouritem.hxx>
26 #include <editeng/crossedoutitem.hxx>
27 #include <editeng/escapementitem.hxx>
28 #include <editeng/fontitem.hxx>
29 #include <editeng/fhgtitem.hxx>
30 #include <editeng/kernitem.hxx>
31 #include <editeng/charreliefitem.hxx>
32 #include <editeng/langitem.hxx>
33 #include <editeng/postitem.hxx>
34 #include <editeng/shdditem.hxx>
35 #include <editeng/udlnitem.hxx>
36 #include <editeng/wghtitem.hxx>
37 #include <editeng/wrlmitem.hxx>
38 #include <editeng/autokernitem.hxx>
39 #include <editeng/charrotateitem.hxx>
40 #include <editeng/emphasismarkitem.hxx>
41 #include <editeng/charscaleitem.hxx>
42 #include <editeng/twolinesitem.hxx>
43 #include <editeng/charhiddenitem.hxx>
44 #include <editeng/boxitem.hxx>
45 #include <editeng/nhypitem.hxx>
46 #include <editeng/shaditem.hxx>
47 #include <viewopt.hxx>
48 #include <charfmt.hxx>
49 #include <fchrfmt.hxx>
50 #include <fmtautofmt.hxx>
51 #include <editeng/brushitem.hxx>
52 #include <fmtinfmt.hxx>
53 #include <txtinet.hxx>
54 #include <IDocumentSettingAccess.hxx>
58 * Attribute to Stack Mapping
60 * Attributes applied to a text are pushed on different stacks. For each
61 * stack, the top most attribute on the stack is valid. Because some
62 * kinds of attributes have to be pushed to the same stacks we map their
64 * Attention: The first NUM_DEFAULT_VALUES ( defined in swfntcch.hxx )
65 * are stored in the defaultitem-cache, if you add one, you have to increase
67 * Also adjust NUM_ATTRIBUTE_STACKS in atrhndl.hxx.
69 const sal_uInt8 StackPos
[ RES_TXTATR_WITHEND_END
- RES_CHRATR_BEGIN
+ 1 ] =
72 1, // RES_CHRATR_CASEMAP = RES_CHRATR_BEGIN // 1
73 0, // RES_CHRATR_CHARSETCOLOR, // 2
74 2, // RES_CHRATR_COLOR, // 3
75 3, // RES_CHRATR_CONTOUR, // 4
76 4, // RES_CHRATR_CROSSEDOUT, // 5
77 5, // RES_CHRATR_ESCAPEMENT, // 6
78 6, // RES_CHRATR_FONT, // 7
79 7, // RES_CHRATR_FONTSIZE, // 8
80 8, // RES_CHRATR_KERNING, // 9
81 9, // RES_CHRATR_LANGUAGE, // 10
82 10, // RES_CHRATR_POSTURE, // 11
83 0, // RES_CHRATR_UNUSED1, // 12
84 11, // RES_CHRATR_SHADOWED, // 13
85 12, // RES_CHRATR_UNDERLINE, // 14
86 13, // RES_CHRATR_WEIGHT, // 15
87 14, // RES_CHRATR_WORDLINEMODE, // 16
88 15, // RES_CHRATR_AUTOKERN, // 17
89 16, // RES_CHRATR_BLINK, // 18
90 17, // RES_CHRATR_NOHYPHEN, // 19
91 0, // RES_CHRATR_UNUSED2, // 20
92 18, // RES_CHRATR_BACKGROUND, // 21
93 19, // RES_CHRATR_CJK_FONT, // 22
94 20, // RES_CHRATR_CJK_FONTSIZE, // 23
95 21, // RES_CHRATR_CJK_LANGUAGE, // 24
96 22, // RES_CHRATR_CJK_POSTURE, // 25
97 23, // RES_CHRATR_CJK_WEIGHT, // 26
98 24, // RES_CHRATR_CTL_FONT, // 27
99 25, // RES_CHRATR_CTL_FONTSIZE, // 28
100 26, // RES_CHRATR_CTL_LANGUAGE, // 29
101 27, // RES_CHRATR_CTL_POSTURE, // 30
102 28, // RES_CHRATR_CTL_WEIGHT, // 31
103 29, // RES_CHRATR_ROTATE, // 32
104 30, // RES_CHRATR_EMPHASIS_MARK, // 33
105 31, // RES_CHRATR_TWO_LINES, // 34
106 32, // RES_CHRATR_SCALEW, // 35
107 33, // RES_CHRATR_RELIEF, // 36
108 34, // RES_CHRATR_HIDDEN, // 37
109 35, // RES_CHRATR_OVERLINE, // 38
110 0, // RES_CHRATR_RSID, // 39
111 36, // RES_CHRATR_BOX, // 40
112 37, // RES_CHRATR_SHADOW, // 41
113 38, // RES_CHRATR_HIGHLIGHT, // 42
114 0, // RES_CHRATR_GRABBAG, // 43
115 0, // RES_CHRATR_BIDIRTL, // 44
116 0, // RES_CHRATR_IDCTHINT, // 45
117 39, // RES_TXTATR_REFMARK, // 46
118 40, // RES_TXTATR_TOXMARK, // 47
119 41, // RES_TXTATR_META, // 48
120 41, // RES_TXTATR_METAFIELD, // 49
121 0, // RES_TXTATR_AUTOFMT, // 50
122 0, // RES_TXTATR_INETFMT // 51
123 0, // RES_TXTATR_CHARFMT, // 52
124 42, // RES_TXTATR_CJK_RUBY, // 53
125 0, // RES_TXTATR_UNKNOWN_CONTAINER, // 54
126 43, // RES_TXTATR_INPUTFIELD // 55
127 44, // RES_TXTATR_CONTENTCONTROL // 56
133 /// Returns the item set associated with a character/inet/auto style
134 const SfxItemSet
* GetItemSet( const SfxPoolItem
& rAttr
)
136 const SfxItemSet
* pSet
= nullptr;
138 if ( RES_TXTATR_AUTOFMT
== rAttr
.Which() )
140 pSet
= rAttr
.StaticWhichCast(RES_TXTATR_AUTOFMT
).GetStyleHandle().get();
144 // Get the attributes from the template
145 const SwCharFormat
* pFormat
= RES_TXTATR_INETFMT
== rAttr
.Which() ?
146 rAttr
.StaticWhichCast(RES_TXTATR_INETFMT
).GetTextINetFormat()->GetCharFormat() :
147 static_cast<const SwFormatCharFormat
&>(rAttr
).GetCharFormat();
150 pSet
= &pFormat
->GetAttrSet();
157 /// Extracts pool item of type nWhich from rAttr
158 const SfxPoolItem
* GetItem( const SwTextAttr
& rAttr
, sal_uInt16 nWhich
)
160 if ( RES_TXTATR_INETFMT
== rAttr
.Which() ||
161 RES_TXTATR_CHARFMT
== rAttr
.Which() ||
162 RES_TXTATR_AUTOFMT
== rAttr
.Which() )
164 const SfxItemSet
* pSet
= CharFormat::GetItemSet( rAttr
.GetAttr() );
165 if ( !pSet
) return nullptr;
167 bool bInParent
= RES_TXTATR_AUTOFMT
!= rAttr
.Which();
168 const SfxPoolItem
* pItem
;
169 bool bRet
= SfxItemState::SET
== pSet
->GetItemState( nWhich
, bInParent
, &pItem
);
171 return bRet
? pItem
: nullptr;
174 return ( nWhich
== rAttr
.Which() ) ? &rAttr
.GetAttr() : nullptr;
177 /// Checks if item is included in character/inet/auto style
178 bool IsItemIncluded( const sal_uInt16 nWhich
, const SwTextAttr
*pAttr
)
182 const SfxItemSet
* pItemSet
= CharFormat::GetItemSet( pAttr
->GetAttr() );
184 bRet
= SfxItemState::SET
== pItemSet
->GetItemState( nWhich
);
191 * The color of hyperlinks is taken from the associated character attribute,
192 * depending on its 'visited' state. There are actually two cases, which
193 * should override the colors from the character attribute:
194 * 1. We never take the 'visited' color during printing/pdf export/preview
195 * 2. The user has chosen to override these colors in the view options
197 static bool lcl_ChgHyperLinkColor( const SwTextAttr
& rAttr
,
198 const SfxPoolItem
& rItem
,
199 const SwViewShell
* pShell
,
203 RES_TXTATR_INETFMT
!= rAttr
.Which() ||
204 RES_CHRATR_COLOR
!= rItem
.Which() )
209 // We do not want to show visited links:
210 // (printing, pdf export, page preview)
212 SwTextINetFormat
& rINetAttr(const_cast<SwTextINetFormat
&>(
213 static_txtattr_cast
<SwTextINetFormat
const&>(rAttr
)));
214 if ( pShell
->GetOut()->GetOutDevType() == OUTDEV_PRINTER
||
215 pShell
->GetViewOptions()->IsPDFExport() ||
216 pShell
->GetViewOptions()->IsPagePreview() )
218 if (rINetAttr
.IsVisited())
222 // take color from character format 'unvisited link'
223 rINetAttr
.SetVisited(false);
224 const SwCharFormat
* pTmpFormat
= rINetAttr
.GetCharFormat();
225 if (const SvxColorItem
* pItem
= pTmpFormat
->GetItemIfSet(RES_CHRATR_COLOR
))
226 *pColor
= pItem
->GetValue();
227 rINetAttr
.SetVisited(true);
236 // We do not want to apply the color set in the hyperlink
237 // attribute, instead we take the colors from the view options:
239 if ( pShell
->GetWin() &&
241 (rINetAttr
.IsVisited() && pShell
->GetViewOptions()->IsVisitedLinks()) ||
242 (!rINetAttr
.IsVisited() && pShell
->GetViewOptions()->IsLinks())
248 if (rINetAttr
.IsVisited())
250 // take color from view option 'visited link color'
251 *pColor
= pShell
->GetViewOptions()->GetVisitedLinksColor();
255 // take color from view option 'unvisited link color'
256 *pColor
= pShell
->GetViewOptions()->GetLinksColor();
265 SwAttrHandler::SwAttrHandler()
266 : m_pIDocumentSettingAccess(nullptr)
268 , m_bVertLayout(false)
269 , m_bVertLayoutLRBT(false)
271 memset( m_pDefaultArray
, 0, NUM_DEFAULT_VALUES
* sizeof(SfxPoolItem
*) );
274 SwAttrHandler::~SwAttrHandler()
278 void SwAttrHandler::Init( const SwAttrSet
& rAttrSet
,
279 const IDocumentSettingAccess
& rIDocumentSettingAcces
)
281 m_pIDocumentSettingAccess
= &rIDocumentSettingAcces
;
284 for ( sal_uInt16 i
= RES_CHRATR_BEGIN
; i
< RES_CHRATR_END
; i
++ )
285 m_pDefaultArray
[ StackPos
[ i
] ] = &rAttrSet
.Get( i
);
288 void SwAttrHandler::Init( const SfxPoolItem
** pPoolItem
, const SwAttrSet
* pAS
,
289 const IDocumentSettingAccess
& rIDocumentSettingAcces
,
290 const SwViewShell
* pSh
,
291 SwFont
& rFnt
, bool bVL
, bool bVertLayoutLRBT
)
293 // initialize default array
294 memcpy( m_pDefaultArray
, pPoolItem
,
295 NUM_DEFAULT_VALUES
* sizeof(SfxPoolItem
*) );
297 m_pIDocumentSettingAccess
= &rIDocumentSettingAcces
;
300 // do we have to apply additional paragraph attributes?
302 m_bVertLayoutLRBT
= bVertLayoutLRBT
;
304 if ( pAS
&& pAS
->Count() )
306 SfxItemIter
aIter( *pAS
);
308 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
311 nWhich
= pItem
->Which();
312 if (isCHRATR(nWhich
))
314 m_pDefaultArray
[ StackPos
[ nWhich
] ] = pItem
;
315 FontChg( *pItem
, rFnt
, true );
318 pItem
= aIter
.NextItem();
322 // It is possible, that Init is called more than once, e.g., in a
323 // SwTextFrame::FormatOnceMore situation or (since sw_redlinehide)
324 // from SwAttrIter::Seek(); in the latter case SwTextSizeInfo::m_pFnt
325 // is an alias of m_pFnt so it must not be deleted!
329 m_oFnt
.emplace(rFnt
);
332 void SwAttrHandler::Reset( )
334 for (auto& i
: m_aAttrStack
)
338 void SwAttrHandler::PushAndChg( const SwTextAttr
& rAttr
, SwFont
& rFnt
)
340 // these special attributes in fact represent a collection of attributes
341 // they have to be pushed to each stack they belong to
342 if ( RES_TXTATR_INETFMT
== rAttr
.Which() ||
343 RES_TXTATR_CHARFMT
== rAttr
.Which() ||
344 RES_PARATR_LIST_AUTOFMT
== rAttr
.Which() ||
345 RES_TXTATR_AUTOFMT
== rAttr
.Which() )
347 const SfxItemSet
* pSet
= rAttr
.Which() == RES_PARATR_LIST_AUTOFMT
348 ? rAttr
.GetAttr().StaticWhichCast(RES_PARATR_LIST_AUTOFMT
).GetStyleHandle().get()
349 : CharFormat::GetItemSet( rAttr
.GetAttr() );
352 bool const inParent
{rAttr
.Which() != RES_TXTATR_AUTOFMT
&& rAttr
.Which() != RES_PARATR_LIST_AUTOFMT
};
353 for ( sal_uInt16 i
= RES_CHRATR_BEGIN
; i
< RES_CHRATR_END
; i
++)
355 const SfxPoolItem
* pItem
;
356 bool bRet
= SfxItemState::SET
== pSet
->GetItemState(i
, inParent
, &pItem
);
360 // we push rAttr onto the appropriate stack
361 if ( Push( rAttr
, *pItem
) )
363 // we let pItem change rFnt
365 if (lcl_ChgHyperLinkColor(rAttr
, *pItem
, m_pShell
, &aColor
))
367 SvxColorItem
aItemNext( aColor
, RES_CHRATR_COLOR
);
368 FontChg( aItemNext
, rFnt
, true );
371 FontChg( *pItem
, rFnt
, true );
376 if (rAttr
.Which() == RES_TXTATR_INETFMT
)
383 // this is the usual case, we have a basic attribute, push it onto the
384 // stack and change the font
387 if ( Push( rAttr
, rAttr
.GetAttr() ) )
388 // we let pItem change rFnt
389 FontChg( rAttr
.GetAttr(), rFnt
, true );
393 const SwTextAttr
* SwAttrHandler::GetTop(sal_uInt16 nStack
)
395 return m_aAttrStack
[nStack
].empty() ? nullptr : m_aAttrStack
[nStack
].back();
398 bool SwAttrHandler::Push( const SwTextAttr
& rAttr
, const SfxPoolItem
& rItem
)
400 OSL_ENSURE( rItem
.Which() < RES_TXTATR_WITHEND_END
,
401 "I do not want this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
404 if ( RES_TXTATR_WITHEND_END
<= rItem
.Which() )
407 const sal_uInt16 nStack
= StackPos
[ rItem
.Which() ];
409 // attributes originating from redlining have highest priority
410 // second priority are hyperlink attributes, which have a color replacement
411 const SwTextAttr
* pTopAttr
= GetTop(nStack
);
413 || rAttr
.IsPriorityAttr()
414 || ( !pTopAttr
->IsPriorityAttr()
415 && !lcl_ChgHyperLinkColor(*pTopAttr
, rItem
, m_pShell
, nullptr)))
417 m_aAttrStack
[nStack
].push_back(&rAttr
);
421 const auto it
= m_aAttrStack
[nStack
].end() - 1;
422 m_aAttrStack
[nStack
].insert(it
, &rAttr
);
426 void SwAttrHandler::RemoveFromStack(sal_uInt16 nWhich
, const SwTextAttr
& rAttr
)
428 auto& rStack
= m_aAttrStack
[StackPos
[nWhich
]];
429 const auto it
= std::find(rStack
.begin(), rStack
.end(), &rAttr
);
430 if (it
!= rStack
.end())
434 void SwAttrHandler::PopAndChg( const SwTextAttr
& rAttr
, SwFont
& rFnt
)
436 if ( RES_TXTATR_WITHEND_END
<= rAttr
.Which() )
439 // these special attributes in fact represent a collection of attributes
440 // they have to be removed from each stack they belong to
441 if ( RES_TXTATR_INETFMT
== rAttr
.Which() ||
442 RES_TXTATR_CHARFMT
== rAttr
.Which() ||
443 RES_TXTATR_AUTOFMT
== rAttr
.Which() )
445 const SfxItemSet
* pSet
= CharFormat::GetItemSet( rAttr
.GetAttr() );
448 if (rAttr
.Which() == RES_TXTATR_INETFMT
)
450 assert(m_nINETFMT
> 0);
456 for ( sal_uInt16 i
= RES_CHRATR_BEGIN
; i
< RES_CHRATR_END
; i
++)
458 const SfxPoolItem
* pItem
;
459 bool bRet
= SfxItemState::SET
== pSet
->GetItemState( i
, RES_TXTATR_AUTOFMT
!= rAttr
.Which(), &pItem
);
462 // we remove rAttr from the appropriate stack
463 RemoveFromStack(i
, rAttr
);
464 // reset font according to attribute on top of stack
466 ActivateTop( rFnt
, i
);
470 // this is the usual case, we have a basic attribute, remove it from the
471 // stack and reset the font
474 RemoveFromStack(rAttr
.Which(), rAttr
);
475 // reset font according to attribute on top of stack
477 ActivateTop( rFnt
, rAttr
.Which() );
481 /// Only used during redlining
482 void SwAttrHandler::Pop( const SwTextAttr
& rAttr
)
484 OSL_ENSURE( rAttr
.Which() < RES_TXTATR_WITHEND_END
,
485 "I do not have this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
487 if ( rAttr
.Which() < RES_TXTATR_WITHEND_END
)
489 RemoveFromStack(rAttr
.Which(), rAttr
);
493 void SwAttrHandler::ActivateTop( SwFont
& rFnt
, const sal_uInt16 nAttr
)
495 assert(nAttr
< RES_TXTATR_WITHEND_END
);
497 const sal_uInt16 nStackPos
= StackPos
[ nAttr
];
498 const SwTextAttr
* pTopAt
= GetTop(nStackPos
);
501 const SfxPoolItem
* pItemNext(nullptr);
503 // check if top attribute is collection of attributes
504 if ( RES_TXTATR_INETFMT
== pTopAt
->Which() ||
505 RES_TXTATR_CHARFMT
== pTopAt
->Which() ||
506 RES_TXTATR_AUTOFMT
== pTopAt
->Which() )
508 const SfxItemSet
* pSet
= CharFormat::GetItemSet( pTopAt
->GetAttr() );
510 pSet
->GetItemState( nAttr
, RES_TXTATR_AUTOFMT
!= pTopAt
->Which(), &pItemNext
);
516 if (lcl_ChgHyperLinkColor(*pTopAt
, *pItemNext
, m_pShell
, &aColor
))
518 SvxColorItem
aItemNext( aColor
, RES_CHRATR_COLOR
);
519 FontChg( aItemNext
, rFnt
, false );
522 FontChg( *pItemNext
, rFnt
, false );
525 FontChg( pTopAt
->GetAttr(), rFnt
, false );
528 // default value has to be set, we only have default values for char attribs
529 else if ( nStackPos
< NUM_DEFAULT_VALUES
)
530 FontChg( *m_pDefaultArray
[ nStackPos
], rFnt
, false );
531 else if ( RES_TXTATR_REFMARK
== nAttr
)
533 else if ( RES_TXTATR_TOXMARK
== nAttr
)
535 else if ( (RES_TXTATR_META
== nAttr
) || (RES_TXTATR_METAFIELD
== nAttr
) )
539 else if (nAttr
== RES_TXTATR_CONTENTCONTROL
)
541 rFnt
.GetContentControl()--;
543 else if ( RES_TXTATR_CJK_RUBY
== nAttr
)
545 // ruby stack has no more attributes
546 // check, if a rotation attribute has to be applied
547 const sal_uInt16 nTwoLineStack
= StackPos
[ RES_CHRATR_TWO_LINES
];
548 bool bTwoLineAct
= false;
549 const SwTextAttr
* pTwoLineAttr
= GetTop(nTwoLineStack
);
553 const auto& rTwoLineItem
= *CharFormat::GetItem( *pTwoLineAttr
, RES_CHRATR_TWO_LINES
);
554 bTwoLineAct
= rTwoLineItem
.GetValue();
557 bTwoLineAct
= m_pDefaultArray
[ nTwoLineStack
]->StaticWhichCast(RES_CHRATR_TWO_LINES
).GetValue();
562 // eventually, a rotate attribute has to be activated
563 const sal_uInt16 nRotateStack
= StackPos
[ RES_CHRATR_ROTATE
];
564 const SwTextAttr
* pRotateAttr
= GetTop(nRotateStack
);
568 const auto& rRotateItem
= *CharFormat::GetItem( *pRotateAttr
, RES_CHRATR_ROTATE
);
569 rFnt
.SetVertical( rRotateItem
.GetValue(), m_bVertLayout
);
572 rFnt
.SetVertical( m_pDefaultArray
[ nRotateStack
]->StaticWhichCast(RES_CHRATR_ROTATE
).GetValue(), m_bVertLayout
);
574 else if ( RES_TXTATR_INPUTFIELD
== nAttr
)
575 rFnt
.GetInputField()--;
579 * When popping an attribute from the stack, the top more remaining
580 * attribute in the stack becomes valid. The following function change
581 * a font depending on the stack id.
583 void SwAttrHandler::FontChg(const SfxPoolItem
& rItem
, SwFont
& rFnt
, bool bPush
)
585 switch ( rItem
.Which() )
587 case RES_CHRATR_CASEMAP
:
588 rFnt
.SetCaseMap( rItem
.StaticWhichCast(RES_CHRATR_CASEMAP
).GetCaseMap() );
590 case RES_CHRATR_COLOR
:
591 rFnt
.SetColor( rItem
.StaticWhichCast(RES_CHRATR_COLOR
).GetValue() );
593 case RES_CHRATR_CONTOUR
:
594 rFnt
.SetOutline( rItem
.StaticWhichCast(RES_CHRATR_CONTOUR
).GetValue() );
596 case RES_CHRATR_CROSSEDOUT
:
597 rFnt
.SetStrikeout( rItem
.StaticWhichCast(RES_CHRATR_CROSSEDOUT
).GetStrikeout() );
599 case RES_CHRATR_ESCAPEMENT
:
600 rFnt
.SetEscapement( rItem
.StaticWhichCast(RES_CHRATR_ESCAPEMENT
).GetEsc() );
601 rFnt
.SetProportion( rItem
.StaticWhichCast(RES_CHRATR_ESCAPEMENT
).GetProportionalHeight() );
603 case RES_CHRATR_FONT
:
605 auto& rFontItem
= rItem
.StaticWhichCast(RES_CHRATR_FONT
);
606 rFnt
.SetName( rFontItem
.GetFamilyName(), SwFontScript::Latin
);
607 rFnt
.SetStyleName( rFontItem
.GetStyleName(), SwFontScript::Latin
);
608 rFnt
.SetFamily( rFontItem
.GetFamily(), SwFontScript::Latin
);
609 rFnt
.SetPitch( rFontItem
.GetPitch(), SwFontScript::Latin
);
610 rFnt
.SetCharSet( rFontItem
.GetCharSet(), SwFontScript::Latin
);
613 case RES_CHRATR_FONTSIZE
:
614 rFnt
.SetSize(Size(0, rItem
.StaticWhichCast(RES_CHRATR_FONTSIZE
).GetHeight() ), SwFontScript::Latin
);
616 case RES_CHRATR_KERNING
:
617 rFnt
.SetFixKerning( rItem
.StaticWhichCast(RES_CHRATR_KERNING
).GetValue() );
619 case RES_CHRATR_LANGUAGE
:
620 rFnt
.SetLanguage( rItem
.StaticWhichCast(RES_CHRATR_LANGUAGE
).GetLanguage(), SwFontScript::Latin
);
622 case RES_CHRATR_POSTURE
:
623 rFnt
.SetItalic( rItem
.StaticWhichCast(RES_CHRATR_POSTURE
).GetPosture(), SwFontScript::Latin
);
625 case RES_CHRATR_SHADOWED
:
626 rFnt
.SetShadow( rItem
.StaticWhichCast(RES_CHRATR_SHADOWED
).GetValue() );
628 case RES_CHRATR_UNDERLINE
:
630 const sal_uInt16 nStackPos
= StackPos
[ RES_CHRATR_HIDDEN
];
631 const SwTextAttr
* pTopAt
= GetTop(nStackPos
);
633 const SfxPoolItem
* pTmpItem
= pTopAt
?
634 CharFormat::GetItem( *pTopAt
, RES_CHRATR_HIDDEN
) :
635 m_pDefaultArray
[ nStackPos
];
637 const sal_uInt16 nStackPos2
= StackPos
[ RES_CHRATR_NOHYPHEN
];
638 const SwTextAttr
* pTopAt2
= GetTop(nStackPos2
);
640 const SfxPoolItem
* pTmpItem2
= pTopAt2
?
641 CharFormat::GetItem( *pTopAt2
, RES_CHRATR_NOHYPHEN
) :
642 m_pDefaultArray
[ nStackPos2
];
644 if ((m_pShell
&& !m_pShell
->GetWin()) ||
645 (pTmpItem
&& !pTmpItem
->StaticWhichCast(RES_CHRATR_HIDDEN
).GetValue()) ||
646 (pTmpItem2
&& !pTmpItem2
->StaticWhichCast(RES_CHRATR_NOHYPHEN
).GetValue()) )
648 rFnt
.SetUnderline( rItem
.StaticWhichCast(RES_CHRATR_UNDERLINE
).GetLineStyle() );
649 rFnt
.SetUnderColor( rItem
.StaticWhichCast(RES_CHRATR_UNDERLINE
).GetColor() );
655 const SvxBoxItem
& aBoxItem
= rItem
.StaticWhichCast(RES_CHRATR_BOX
);
656 rFnt
.SetTopBorder( aBoxItem
.GetTop() );
657 rFnt
.SetBottomBorder( aBoxItem
.GetBottom() );
658 rFnt
.SetRightBorder( aBoxItem
.GetRight() );
659 rFnt
.SetLeftBorder( aBoxItem
.GetLeft() );
660 rFnt
.SetTopBorderDist( aBoxItem
.GetDistance(SvxBoxItemLine::TOP
) );
661 rFnt
.SetBottomBorderDist( aBoxItem
.GetDistance(SvxBoxItemLine::BOTTOM
) );
662 rFnt
.SetRightBorderDist( aBoxItem
.GetDistance(SvxBoxItemLine::RIGHT
) );
663 rFnt
.SetLeftBorderDist( aBoxItem
.GetDistance(SvxBoxItemLine::LEFT
) );
666 case RES_CHRATR_SHADOW
:
668 const SvxShadowItem
& aShadowItem
= rItem
.StaticWhichCast(RES_CHRATR_SHADOW
);
669 rFnt
.SetShadowColor( aShadowItem
.GetColor() );
670 rFnt
.SetShadowWidth( aShadowItem
.GetWidth() );
671 rFnt
.SetShadowLocation( aShadowItem
.GetLocation() );
674 case RES_CHRATR_OVERLINE
:
675 rFnt
.SetOverline( rItem
.StaticWhichCast(RES_CHRATR_OVERLINE
).GetLineStyle() );
676 rFnt
.SetOverColor( rItem
.StaticWhichCast(RES_CHRATR_OVERLINE
).GetColor() );
678 case RES_CHRATR_WEIGHT
:
679 rFnt
.SetWeight( rItem
.StaticWhichCast(RES_CHRATR_WEIGHT
).GetWeight(), SwFontScript::Latin
);
681 case RES_CHRATR_WORDLINEMODE
:
682 rFnt
.SetWordLineMode( rItem
.StaticWhichCast(RES_CHRATR_WORDLINEMODE
).GetValue() );
684 case RES_CHRATR_AUTOKERN
:
685 if( rItem
.StaticWhichCast(RES_CHRATR_AUTOKERN
).GetValue() )
687 rFnt
.SetAutoKern( (!m_pIDocumentSettingAccess
||
688 !m_pIDocumentSettingAccess
->get(DocumentSettingId::KERN_ASIAN_PUNCTUATION
)) ?
689 FontKerning::FontSpecific
:
690 FontKerning::Asian
);
693 rFnt
.SetAutoKern( FontKerning::NONE
);
695 case RES_CHRATR_BACKGROUND
:
696 rFnt
.SetBackColor(rItem
.StaticWhichCast(RES_CHRATR_BACKGROUND
).GetColor());
698 case RES_CHRATR_HIGHLIGHT
:
699 rFnt
.SetHighlightColor( rItem
.StaticWhichCast(RES_CHRATR_HIGHLIGHT
).GetColor() );
701 case RES_CHRATR_NOHYPHEN
:
702 if ( m_pShell
&& m_pShell
->GetWin() &&
703 m_pShell
->GetViewOptions()->IsViewMetaChars() )
705 if ( rItem
.StaticWhichCast(RES_CHRATR_NOHYPHEN
).GetValue() )
707 rFnt
.SetUnderline( LINESTYLE_DOTTED
);
708 rFnt
.SetUnderColor( COL_LIGHTGRAY
);
711 ActivateTop( rFnt
, RES_CHRATR_UNDERLINE
);
714 case RES_CHRATR_CJK_FONT
:
716 auto& rFontItem
= rItem
.StaticWhichCast(RES_CHRATR_CJK_FONT
);
717 rFnt
.SetName( rFontItem
.GetFamilyName(), SwFontScript::CJK
);
718 rFnt
.SetStyleName( rFontItem
.GetStyleName(), SwFontScript::CJK
);
719 rFnt
.SetFamily( rFontItem
.GetFamily(), SwFontScript::CJK
);
720 rFnt
.SetPitch( rFontItem
.GetPitch(), SwFontScript::CJK
);
721 rFnt
.SetCharSet( rFontItem
.GetCharSet(), SwFontScript::CJK
);
724 case RES_CHRATR_CJK_FONTSIZE
:
725 rFnt
.SetSize(Size( 0, rItem
.StaticWhichCast(RES_CHRATR_CJK_FONTSIZE
).GetHeight()), SwFontScript::CJK
);
727 case RES_CHRATR_CJK_LANGUAGE
:
728 rFnt
.SetLanguage( rItem
.StaticWhichCast(RES_CHRATR_CJK_LANGUAGE
).GetLanguage(), SwFontScript::CJK
);
730 case RES_CHRATR_CJK_POSTURE
:
731 rFnt
.SetItalic( rItem
.StaticWhichCast(RES_CHRATR_CJK_POSTURE
).GetPosture(), SwFontScript::CJK
);
733 case RES_CHRATR_CJK_WEIGHT
:
734 rFnt
.SetWeight( rItem
.StaticWhichCast(RES_CHRATR_CJK_WEIGHT
).GetWeight(), SwFontScript::CJK
);
736 case RES_CHRATR_CTL_FONT
:
738 auto& rFontItem
= rItem
.StaticWhichCast(RES_CHRATR_CTL_FONT
);
739 rFnt
.SetName( rFontItem
.GetFamilyName(), SwFontScript::CTL
);
740 rFnt
.SetStyleName( rFontItem
.GetStyleName(), SwFontScript::CTL
);
741 rFnt
.SetFamily( rFontItem
.GetFamily(), SwFontScript::CTL
);
742 rFnt
.SetPitch( rFontItem
.GetPitch(), SwFontScript::CTL
);
743 rFnt
.SetCharSet( rFontItem
.GetCharSet(), SwFontScript::CTL
);
746 case RES_CHRATR_CTL_FONTSIZE
:
747 rFnt
.SetSize(Size(0, rItem
.StaticWhichCast(RES_CHRATR_CTL_FONTSIZE
).GetHeight() ), SwFontScript::CTL
);
749 case RES_CHRATR_CTL_LANGUAGE
:
750 rFnt
.SetLanguage( rItem
.StaticWhichCast(RES_CHRATR_CTL_LANGUAGE
).GetLanguage(), SwFontScript::CTL
);
752 case RES_CHRATR_CTL_POSTURE
:
753 rFnt
.SetItalic( rItem
.StaticWhichCast(RES_CHRATR_CTL_POSTURE
).GetPosture(), SwFontScript::CTL
);
755 case RES_CHRATR_CTL_WEIGHT
:
756 rFnt
.SetWeight( rItem
.StaticWhichCast(RES_CHRATR_CTL_WEIGHT
).GetWeight(), SwFontScript::CTL
);
758 case RES_CHRATR_EMPHASIS_MARK
:
759 rFnt
.SetEmphasisMark( rItem
.StaticWhichCast(RES_CHRATR_EMPHASIS_MARK
).GetEmphasisMark() );
761 case RES_CHRATR_SCALEW
:
762 rFnt
.SetPropWidth( rItem
.StaticWhichCast(RES_CHRATR_SCALEW
).GetValue() );
764 case RES_CHRATR_RELIEF
:
765 rFnt
.SetRelief( rItem
.StaticWhichCast(RES_CHRATR_RELIEF
).GetValue() );
767 case RES_CHRATR_HIDDEN
:
768 if (m_pShell
&& m_pShell
->GetWin())
770 if ( rItem
.StaticWhichCast(RES_CHRATR_HIDDEN
).GetValue() )
771 rFnt
.SetUnderline( LINESTYLE_DOTTED
);
773 ActivateTop( rFnt
, RES_CHRATR_UNDERLINE
);
776 case RES_CHRATR_ROTATE
:
778 // rotate attribute is applied, when:
779 // 1. ruby stack is empty and
780 // 2. top of two line stack ( or default attribute )is an
781 // deactivated two line attribute
783 0 != m_aAttrStack
[ StackPos
[ RES_TXTATR_CJK_RUBY
] ].size();
788 const sal_uInt16 nTwoLineStack
= StackPos
[ RES_CHRATR_TWO_LINES
];
789 bool bTwoLineAct
= false;
790 const SwTextAttr
* pTwoLineAttr
= GetTop(nTwoLineStack
);
794 const auto& rTwoLineItem
= *CharFormat::GetItem( *pTwoLineAttr
, RES_CHRATR_TWO_LINES
);
795 bTwoLineAct
= rTwoLineItem
.GetValue();
798 bTwoLineAct
= m_pDefaultArray
[ nTwoLineStack
]->StaticWhichCast(RES_CHRATR_TWO_LINES
).GetValue();
801 rFnt
.SetVertical( rItem
.StaticWhichCast(RES_CHRATR_ROTATE
).GetValue(), m_bVertLayout
, m_bVertLayoutLRBT
);
805 case RES_CHRATR_TWO_LINES
:
808 m_aAttrStack
[ StackPos
[ RES_TXTATR_CJK_RUBY
] ].size();
810 // two line is activated, if
811 // 1. no ruby attribute is set and
812 // 2. attribute is active
813 if ( !bRuby
&& rItem
.StaticWhichCast(RES_CHRATR_TWO_LINES
).GetValue() )
815 rFnt
.SetVertical( 0_deg10
, m_bVertLayout
);
819 // a deactivating two line attribute is on top of stack,
820 // check if rotate attribute has to be enabled
824 const sal_uInt16 nRotateStack
= StackPos
[ RES_CHRATR_ROTATE
];
825 const SwTextAttr
* pRotateAttr
= GetTop(nRotateStack
);
829 const auto& rRotateItem
= *CharFormat::GetItem( *pRotateAttr
, RES_CHRATR_ROTATE
);
830 rFnt
.SetVertical( rRotateItem
.GetValue(), m_bVertLayout
);
833 rFnt
.SetVertical(m_pDefaultArray
[ nRotateStack
]->StaticWhichCast(RES_CHRATR_ROTATE
).GetValue(), m_bVertLayout
);
836 case RES_TXTATR_CJK_RUBY
:
837 rFnt
.SetVertical( 0_deg10
, m_bVertLayout
);
839 case RES_TXTATR_REFMARK
:
845 case RES_TXTATR_TOXMARK
:
851 case RES_TXTATR_META
:
852 case RES_TXTATR_METAFIELD
:
858 case RES_TXTATR_CONTENTCONTROL
:
861 rFnt
.GetContentControl()++;
865 rFnt
.GetContentControl()--;
868 case RES_TXTATR_INPUTFIELD
:
870 rFnt
.GetInputField()++;
872 rFnt
.GetInputField()--;
877 /// Takes the default font and calculated the ascent and height
878 void SwAttrHandler::GetDefaultAscentAndHeight( SwViewShell
const * pShell
, OutputDevice
const & rOut
,
879 sal_uInt16
& nAscent
, sal_uInt16
& nHeight
) const
881 OSL_ENSURE(m_oFnt
, "No font available for GetDefaultAscentAndHeight");
885 SwFont
aFont( *m_oFnt
);
886 nHeight
= aFont
.GetHeight( pShell
, rOut
);
887 nAscent
= aFont
.GetAscent( pShell
, rOut
);
891 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */