ITEM: Refactor ItemType
[LibreOffice.git] / sw / source / core / text / atrstck.cxx
blob7d2b6afddc7f512d52d3829ce708b4026dcee28a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
55 #include <viewsh.hxx>
57 /**
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
63 * ids to stack ids
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
66 * NUM_DEFAULT_VALUES.
67 * Also adjust NUM_ATTRIBUTE_STACKS in atrhndl.hxx.
69 const sal_uInt8 StackPos[ RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN + 1 ] =
71 0, // // 0
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
130 namespace CharFormat
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();
142 else
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();
148 if( pFormat )
150 pSet = &pFormat->GetAttrSet();
154 return pSet;
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 )
180 bool bRet = false;
182 const SfxItemSet* pItemSet = CharFormat::GetItemSet( pAttr->GetAttr() );
183 if ( pItemSet )
184 bRet = SfxItemState::SET == pItemSet->GetItemState( nWhich );
186 return bRet;
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,
200 Color* pColor )
202 if ( !pShell ||
203 RES_TXTATR_INETFMT != rAttr.Which() ||
204 RES_CHRATR_COLOR != rItem.Which() )
205 return false;
207 // #i15455#
208 // 1. case:
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())
220 if ( pColor )
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);
229 return true;
232 return false;
235 // 2. case:
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())
246 if ( pColor )
248 if (rINetAttr.IsVisited())
250 // take color from view option 'visited link color'
251 *pColor = pShell->GetViewOptions()->GetVisitedLinksColor();
253 else
255 // take color from view option 'unvisited link color'
256 *pColor = pShell->GetViewOptions()->GetLinksColor();
259 return true;
262 return false;
265 SwAttrHandler::SwAttrHandler()
266 : m_pIDocumentSettingAccess(nullptr)
267 , m_pShell(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;
282 m_pShell = nullptr;
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;
298 m_pShell = pSh;
300 // do we have to apply additional paragraph attributes?
301 m_bVertLayout = bVL;
302 m_bVertLayoutLRBT = bVertLayoutLRBT;
304 if ( pAS && pAS->Count() )
306 SfxItemIter aIter( *pAS );
307 sal_uInt16 nWhich;
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();
319 } while (pItem);
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!
326 if (m_oFnt)
327 *m_oFnt = rFnt;
328 else
329 m_oFnt.emplace(rFnt);
332 void SwAttrHandler::Reset( )
334 for (auto& i : m_aAttrStack)
335 i.clear();
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() );
350 if ( !pSet ) return;
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);
358 if ( bRet )
360 // we push rAttr onto the appropriate stack
361 if ( Push( rAttr, *pItem ) )
363 // we let pItem change rFnt
364 Color aColor;
365 if (lcl_ChgHyperLinkColor(rAttr, *pItem, m_pShell, &aColor))
367 SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
368 FontChg( aItemNext, rFnt, true );
370 else
371 FontChg( *pItem, rFnt, true );
376 if (rAttr.Which() == RES_TXTATR_INETFMT)
378 if (m_nINETFMT == 0)
379 rFnt.SetURL(true);
380 ++m_nINETFMT;
383 // this is the usual case, we have a basic attribute, push it onto the
384 // stack and change the font
385 else
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" );
403 // robust
404 if ( RES_TXTATR_WITHEND_END <= rItem.Which() )
405 return false;
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);
412 if ( !pTopAttr
413 || rAttr.IsPriorityAttr()
414 || ( !pTopAttr->IsPriorityAttr()
415 && !lcl_ChgHyperLinkColor(*pTopAttr, rItem, m_pShell, nullptr)))
417 m_aAttrStack[nStack].push_back(&rAttr);
418 return true;
421 const auto it = m_aAttrStack[nStack].end() - 1;
422 m_aAttrStack[nStack].insert(it, &rAttr);
423 return false;
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())
431 rStack.erase(it);
434 void SwAttrHandler::PopAndChg( const SwTextAttr& rAttr, SwFont& rFnt )
436 if ( RES_TXTATR_WITHEND_END <= rAttr.Which() )
437 return; // robust
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() );
446 if ( !pSet ) return;
448 if (rAttr.Which() == RES_TXTATR_INETFMT)
450 assert(m_nINETFMT > 0);
451 --m_nINETFMT;
452 if (m_nINETFMT == 0)
453 rFnt.SetURL(false);
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 );
460 if ( bRet )
462 // we remove rAttr from the appropriate stack
463 RemoveFromStack(i, rAttr);
464 // reset font according to attribute on top of stack
465 // or default value
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
472 else
474 RemoveFromStack(rAttr.Which(), rAttr);
475 // reset font according to attribute on top of stack
476 // or default value
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);
499 if ( pTopAt )
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() );
509 if (pSet)
510 pSet->GetItemState( nAttr, RES_TXTATR_AUTOFMT != pTopAt->Which(), &pItemNext );
513 if (pItemNext)
515 Color aColor;
516 if (lcl_ChgHyperLinkColor(*pTopAt, *pItemNext, m_pShell, &aColor))
518 SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
519 FontChg( aItemNext, rFnt, false );
521 else
522 FontChg( *pItemNext, rFnt, false );
524 else
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 )
532 rFnt.GetRef()--;
533 else if ( RES_TXTATR_TOXMARK == nAttr )
534 rFnt.GetTox()--;
535 else if ( (RES_TXTATR_META == nAttr) || (RES_TXTATR_METAFIELD == nAttr) )
537 rFnt.GetMeta()--;
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);
551 if ( pTwoLineAttr )
553 const auto& rTwoLineItem = *CharFormat::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
554 bTwoLineAct = rTwoLineItem.GetValue();
556 else
557 bTwoLineAct = m_pDefaultArray[ nTwoLineStack ]->StaticWhichCast(RES_CHRATR_TWO_LINES).GetValue();
559 if ( bTwoLineAct )
560 return;
562 // eventually, a rotate attribute has to be activated
563 const sal_uInt16 nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
564 const SwTextAttr* pRotateAttr = GetTop(nRotateStack);
566 if ( pRotateAttr )
568 const auto& rRotateItem = *CharFormat::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
569 rFnt.SetVertical( rRotateItem.GetValue(), m_bVertLayout );
571 else
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() );
589 break;
590 case RES_CHRATR_COLOR :
591 rFnt.SetColor( rItem.StaticWhichCast(RES_CHRATR_COLOR).GetValue() );
592 break;
593 case RES_CHRATR_CONTOUR :
594 rFnt.SetOutline( rItem.StaticWhichCast(RES_CHRATR_CONTOUR).GetValue() );
595 break;
596 case RES_CHRATR_CROSSEDOUT :
597 rFnt.SetStrikeout( rItem.StaticWhichCast(RES_CHRATR_CROSSEDOUT).GetStrikeout() );
598 break;
599 case RES_CHRATR_ESCAPEMENT :
600 rFnt.SetEscapement( rItem.StaticWhichCast(RES_CHRATR_ESCAPEMENT).GetEsc() );
601 rFnt.SetProportion( rItem.StaticWhichCast(RES_CHRATR_ESCAPEMENT).GetProportionalHeight() );
602 break;
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 );
611 break;
613 case RES_CHRATR_FONTSIZE :
614 rFnt.SetSize(Size(0, rItem.StaticWhichCast(RES_CHRATR_FONTSIZE).GetHeight() ), SwFontScript::Latin );
615 break;
616 case RES_CHRATR_KERNING :
617 rFnt.SetFixKerning( rItem.StaticWhichCast(RES_CHRATR_KERNING).GetValue() );
618 break;
619 case RES_CHRATR_LANGUAGE :
620 rFnt.SetLanguage( rItem.StaticWhichCast(RES_CHRATR_LANGUAGE).GetLanguage(), SwFontScript::Latin );
621 break;
622 case RES_CHRATR_POSTURE :
623 rFnt.SetItalic( rItem.StaticWhichCast(RES_CHRATR_POSTURE).GetPosture(), SwFontScript::Latin );
624 break;
625 case RES_CHRATR_SHADOWED :
626 rFnt.SetShadow( rItem.StaticWhichCast(RES_CHRATR_SHADOWED).GetValue() );
627 break;
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() );
651 break;
653 case RES_CHRATR_BOX:
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) );
664 break;
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() );
672 break;
674 case RES_CHRATR_OVERLINE :
675 rFnt.SetOverline( rItem.StaticWhichCast(RES_CHRATR_OVERLINE).GetLineStyle() );
676 rFnt.SetOverColor( rItem.StaticWhichCast(RES_CHRATR_OVERLINE).GetColor() );
677 break;
678 case RES_CHRATR_WEIGHT :
679 rFnt.SetWeight( rItem.StaticWhichCast(RES_CHRATR_WEIGHT).GetWeight(), SwFontScript::Latin );
680 break;
681 case RES_CHRATR_WORDLINEMODE :
682 rFnt.SetWordLineMode( rItem.StaticWhichCast(RES_CHRATR_WORDLINEMODE).GetValue() );
683 break;
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 );
692 else
693 rFnt.SetAutoKern( FontKerning::NONE );
694 break;
695 case RES_CHRATR_BACKGROUND :
696 rFnt.SetBackColor(rItem.StaticWhichCast(RES_CHRATR_BACKGROUND).GetColor());
697 break;
698 case RES_CHRATR_HIGHLIGHT :
699 rFnt.SetHighlightColor( rItem.StaticWhichCast(RES_CHRATR_HIGHLIGHT).GetColor() );
700 break;
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 );
710 else
711 ActivateTop( rFnt, RES_CHRATR_UNDERLINE );
713 break;
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 );
722 break;
724 case RES_CHRATR_CJK_FONTSIZE :
725 rFnt.SetSize(Size( 0, rItem.StaticWhichCast(RES_CHRATR_CJK_FONTSIZE).GetHeight()), SwFontScript::CJK);
726 break;
727 case RES_CHRATR_CJK_LANGUAGE :
728 rFnt.SetLanguage( rItem.StaticWhichCast(RES_CHRATR_CJK_LANGUAGE).GetLanguage(), SwFontScript::CJK );
729 break;
730 case RES_CHRATR_CJK_POSTURE :
731 rFnt.SetItalic( rItem.StaticWhichCast(RES_CHRATR_CJK_POSTURE).GetPosture(), SwFontScript::CJK );
732 break;
733 case RES_CHRATR_CJK_WEIGHT :
734 rFnt.SetWeight( rItem.StaticWhichCast(RES_CHRATR_CJK_WEIGHT).GetWeight(), SwFontScript::CJK );
735 break;
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 );
744 break;
746 case RES_CHRATR_CTL_FONTSIZE :
747 rFnt.SetSize(Size(0, rItem.StaticWhichCast(RES_CHRATR_CTL_FONTSIZE).GetHeight() ), SwFontScript::CTL);
748 break;
749 case RES_CHRATR_CTL_LANGUAGE :
750 rFnt.SetLanguage( rItem.StaticWhichCast(RES_CHRATR_CTL_LANGUAGE).GetLanguage(), SwFontScript::CTL );
751 break;
752 case RES_CHRATR_CTL_POSTURE :
753 rFnt.SetItalic( rItem.StaticWhichCast(RES_CHRATR_CTL_POSTURE).GetPosture(), SwFontScript::CTL );
754 break;
755 case RES_CHRATR_CTL_WEIGHT :
756 rFnt.SetWeight( rItem.StaticWhichCast(RES_CHRATR_CTL_WEIGHT).GetWeight(), SwFontScript::CTL );
757 break;
758 case RES_CHRATR_EMPHASIS_MARK :
759 rFnt.SetEmphasisMark( rItem.StaticWhichCast(RES_CHRATR_EMPHASIS_MARK).GetEmphasisMark() );
760 break;
761 case RES_CHRATR_SCALEW :
762 rFnt.SetPropWidth( rItem.StaticWhichCast(RES_CHRATR_SCALEW).GetValue() );
763 break;
764 case RES_CHRATR_RELIEF :
765 rFnt.SetRelief( rItem.StaticWhichCast(RES_CHRATR_RELIEF).GetValue() );
766 break;
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 );
772 else
773 ActivateTop( rFnt, RES_CHRATR_UNDERLINE );
775 break;
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
782 const bool bRuby =
783 0 != m_aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].size();
785 if ( bRuby )
786 break;
788 const sal_uInt16 nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
789 bool bTwoLineAct = false;
790 const SwTextAttr* pTwoLineAttr = GetTop(nTwoLineStack);
792 if ( pTwoLineAttr )
794 const auto& rTwoLineItem = *CharFormat::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
795 bTwoLineAct = rTwoLineItem.GetValue();
797 else
798 bTwoLineAct = m_pDefaultArray[ nTwoLineStack ]->StaticWhichCast(RES_CHRATR_TWO_LINES).GetValue();
800 if ( !bTwoLineAct )
801 rFnt.SetVertical( rItem.StaticWhichCast(RES_CHRATR_ROTATE).GetValue(), m_bVertLayout, m_bVertLayoutLRBT );
803 break;
805 case RES_CHRATR_TWO_LINES :
807 bool bRuby = 0 !=
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 );
816 break;
819 // a deactivating two line attribute is on top of stack,
820 // check if rotate attribute has to be enabled
821 if ( bRuby )
822 break;
824 const sal_uInt16 nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
825 const SwTextAttr* pRotateAttr = GetTop(nRotateStack);
827 if ( pRotateAttr )
829 const auto& rRotateItem = *CharFormat::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
830 rFnt.SetVertical( rRotateItem.GetValue(), m_bVertLayout );
832 else
833 rFnt.SetVertical(m_pDefaultArray[ nRotateStack ]->StaticWhichCast(RES_CHRATR_ROTATE).GetValue(), m_bVertLayout);
834 break;
836 case RES_TXTATR_CJK_RUBY :
837 rFnt.SetVertical( 0_deg10, m_bVertLayout );
838 break;
839 case RES_TXTATR_REFMARK :
840 if ( bPush )
841 rFnt.GetRef()++;
842 else
843 rFnt.GetRef()--;
844 break;
845 case RES_TXTATR_TOXMARK :
846 if ( bPush )
847 rFnt.GetTox()++;
848 else
849 rFnt.GetTox()--;
850 break;
851 case RES_TXTATR_META:
852 case RES_TXTATR_METAFIELD:
853 if ( bPush )
854 rFnt.GetMeta()++;
855 else
856 rFnt.GetMeta()--;
857 break;
858 case RES_TXTATR_CONTENTCONTROL:
859 if (bPush)
861 rFnt.GetContentControl()++;
863 else
865 rFnt.GetContentControl()--;
867 break;
868 case RES_TXTATR_INPUTFIELD :
869 if ( bPush )
870 rFnt.GetInputField()++;
871 else
872 rFnt.GetInputField()--;
873 break;
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");
883 if (m_oFnt)
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: */