merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / text / atrstck.cxx
blob641bd51ee389f582fedc21cec89e405b9f2edbd6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: atrstck.cxx,v $
10 * $Revision: 1.30.210.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <errhdl.hxx> // ASSERT
36 #include <atrhndl.hxx>
37 #include <svtools/itemiter.hxx>
38 #include <vcl/outdev.hxx>
39 #include <svx/cmapitem.hxx>
40 #include <svx/colritem.hxx>
41 #include <svx/cntritem.hxx>
42 #include <svx/crsditem.hxx>
43 #include <svx/escpitem.hxx>
44 #include <svx/fontitem.hxx>
45 #include <svx/fhgtitem.hxx>
46 #include <svx/kernitem.hxx>
47 #include <svx/charreliefitem.hxx>
48 #include <svx/langitem.hxx>
49 #include <svx/postitem.hxx>
50 #include <svx/shdditem.hxx>
51 #include <svx/udlnitem.hxx>
52 #include <svx/wghtitem.hxx>
53 #include <svx/wrlmitem.hxx>
54 #include <svx/akrnitem.hxx>
55 #include <svx/blnkitem.hxx>
56 #include <svx/charrotateitem.hxx>
57 #include <svx/emphitem.hxx>
58 #include <svx/charscaleitem.hxx>
59 #include <svx/twolinesitem.hxx>
60 #include <svx/charhiddenitem.hxx>
61 #include <viewopt.hxx>
62 #include <charfmt.hxx>
63 #include <fchrfmt.hxx>
64 #include <fmtautofmt.hxx>
65 #include <svx/brshitem.hxx>
66 #include <fmtinfmt.hxx>
67 #include <txtinet.hxx>
68 #include <IDocumentSettingAccess.hxx>
69 #include <viewsh.hxx> // ViewShell
70 #include <viewopt.hxx> // SwViewOptions
72 #define STACK_INCREMENT 4
74 /*************************************************************************
75 * Attribute to Stack Mapping
77 * Attributes applied to a text are pushed on different stacks. For each
78 * stack, the top most attribute on the stack is valid. Because some
79 * kinds of attributes have to be pushed to the same stacks we map their
80 * ids to stack ids
81 * Attention: The first NUM_DEFAULT_VALUES ( defined in swfntcch.hxx == 35 )
82 * are stored in the defaultitem-cache, if you add one, you have to increase
83 * NUM_DEFAULT_VALUES.
84 * Also adjust NUM_ATTRIBUTE_STACKS in atrhndl.hxx.
85 *************************************************************************/
87 const BYTE StackPos[ static_cast<USHORT>(RES_TXTATR_WITHEND_END) -
88 static_cast<USHORT>(RES_CHRATR_BEGIN) + 1 ] =
90 0, // // 0
91 1, // RES_CHRATR_CASEMAP = RES_CHRATR_BEGIN // 1
92 0, // RES_CHRATR_CHARSETCOLOR, // 2
93 2, // RES_CHRATR_COLOR, // 3
94 3, // RES_CHRATR_CONTOUR, // 4
95 4, // RES_CHRATR_CROSSEDOUT, // 5
96 5, // RES_CHRATR_ESCAPEMENT, // 6
97 6, // RES_CHRATR_FONT, // 7
98 7, // RES_CHRATR_FONTSIZE, // 8
99 8, // RES_CHRATR_KERNING, // 9
100 9, // RES_CHRATR_LANGUAGE, // 10
101 10, // RES_CHRATR_POSTURE, // 11
102 0, // RES_CHRATR_PROPORTIONALFONTSIZE, // 12
103 11, // RES_CHRATR_SHADOWED, // 13
104 12, // RES_CHRATR_UNDERLINE, // 14
105 13, // RES_CHRATR_WEIGHT, // 15
106 14, // RES_CHRATR_WORDLINEMODE, // 16
107 15, // RES_CHRATR_AUTOKERN, // 17
108 16, // RES_CHRATR_BLINK, // 18
109 17, // RES_CHRATR_NOHYPHEN, // 19
110 0, // RES_CHRATR_NOLINEBREAK, // 20
111 18, // RES_CHRATR_BACKGROUND, // 21
112 19, // RES_CHRATR_CJK_FONT, // 22
113 20, // RES_CHRATR_CJK_FONTSIZE, // 23
114 21, // RES_CHRATR_CJK_LANGUAGE, // 24
115 22, // RES_CHRATR_CJK_POSTURE, // 25
116 23, // RES_CHRATR_CJK_WEIGHT, // 26
117 24, // RES_CHRATR_CTL_FONT, // 27
118 25, // RES_CHRATR_CTL_FONTSIZE, // 28
119 26, // RES_CHRATR_CTL_LANGUAGE, // 29
120 27, // RES_CHRATR_CTL_POSTURE, // 30
121 28, // RES_CHRATR_CTL_WEIGHT, // 31
122 29, // RES_CHRATR_ROTATE, // 32
123 30, // RES_CHRATR_EMPHASIS_MARK, // 33
124 31, // RES_CHRATR_TWO_LINES, // 34
125 32, // RES_CHRATR_SCALEW, // 35
126 33, // RES_CHRATR_RELIEF, // 36
127 34, // RES_CHRATR_HIDDEN, // 37
128 35, // RES_CHRATR_OVERLINE, // 38
129 0, // RES_CHRATR_DUMMY1, // 39
130 0, // RES_CHRATR_DUMMY2, // 40
131 0, // RES_TXTATR_AUTOFMT, // 41
132 0, // RES_TXTATR_INETFMT // 42
133 36, // RES_TXTATR_REFMARK, // 43
134 37, // RES_TXTATR_TOXMARK, // 44
135 0, // RES_TXTATR_CHARFMT, // 45
136 0, // RES_TXTATR_DUMMY5 // 46
137 38, // RES_TXTATR_CJK_RUBY, // 47
138 0, // RES_TXTATR_UNKNOWN_CONTAINER, // 48
139 39, // RES_TXTATR_META, // 49
140 39 // RES_TXTATR_METAFIELD, // 50
143 /*************************************************************************
144 * CharFmt::GetItem
145 * returns the item set associated with an character/inet/auto style
146 *************************************************************************/
148 namespace CharFmt
151 const SfxItemSet* GetItemSet( const SfxPoolItem& rAttr )
153 const SfxItemSet* pSet = 0;
155 if ( RES_TXTATR_AUTOFMT == rAttr.Which() )
157 pSet = static_cast<const SwFmtAutoFmt&>(rAttr).GetStyleHandle().get();
159 else
161 // aus der Vorlage die Attribute holen:
162 SwCharFmt* pFmt = RES_TXTATR_INETFMT == rAttr.Which() ?
163 ((SwFmtINetFmt&)rAttr).GetTxtINetFmt()->GetCharFmt() :
164 ((SwFmtCharFmt&)rAttr).GetCharFmt();
165 if( pFmt )
167 pSet = &pFmt->GetAttrSet();
171 return pSet;
174 /*************************************************************************
175 * CharFmt::GetItem
176 * extracts pool item of type nWhich from rAttr
177 *************************************************************************/
179 const SfxPoolItem* GetItem( const SwTxtAttr& rAttr, USHORT nWhich )
181 if ( RES_TXTATR_INETFMT == rAttr.Which() ||
182 RES_TXTATR_CHARFMT == rAttr.Which() ||
183 RES_TXTATR_AUTOFMT == rAttr.Which() )
185 const SfxItemSet* pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
186 if ( !pSet ) return 0;
188 bool bInParent = RES_TXTATR_AUTOFMT != rAttr.Which();
189 const SfxPoolItem* pItem;
190 BOOL bRet = SFX_ITEM_SET == pSet->GetItemState( nWhich, bInParent, &pItem );
192 return bRet ? pItem : 0;
195 return ( nWhich == rAttr.Which() ) ? &rAttr.GetAttr() : 0;
198 /*************************************************************************
199 * CharFmt::IsItemIncluded
200 * checks if item is included in character/inet/auto style
201 *************************************************************************/
203 BOOL IsItemIncluded( const USHORT nWhich, const SwTxtAttr *pAttr )
205 BOOL bRet = FALSE;
207 const SfxItemSet* pItemSet = CharFmt::GetItemSet( pAttr->GetAttr() );
208 if ( pItemSet )
209 bRet = SFX_ITEM_SET == pItemSet->GetItemState( nWhich, TRUE );
211 return bRet;
216 /*************************************************************************
217 * lcl_ChgHyperLinkColor
218 * The color of hyperlinks is taken from the associated character attribute,
219 * depending on its 'visited' state. There are actually two cases, which
220 * should override the colors from the character attribute:
221 * 1. We never take the 'visited' color during printing/pdf export/preview
222 * 2. The user has choosen to override these colors in the view options
223 *************************************************************************/
225 bool lcl_ChgHyperLinkColor( const SwTxtAttr& rAttr,
226 const SfxPoolItem& rItem,
227 const ViewShell* pShell,
228 Color* pColor )
230 if ( !pShell ||
231 RES_TXTATR_INETFMT != rAttr.Which() ||
232 RES_CHRATR_COLOR != rItem.Which() )
233 return false;
235 // --> FME 2004-09-13 #i15455#
236 // 1. case:
237 // We do not want to show visited links:
238 // (printing, pdf export, page preview)
240 if ( pShell->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
241 pShell->GetViewOptions()->IsPDFExport() ||
242 pShell->GetViewOptions()->IsPagePreview() )
244 if ( ((SwTxtINetFmt&)rAttr).IsVisited() )
246 if ( pColor )
248 // take color from character format 'unvisited link'
249 SwTxtINetFmt& rInetAttr( const_cast<SwTxtINetFmt&>(
250 static_cast<const SwTxtINetFmt&>(rAttr)) );
251 rInetAttr.SetVisited( false );
252 const SwCharFmt* pTmpFmt = ((SwTxtINetFmt&)rAttr).GetCharFmt();
253 const SfxPoolItem* pItem;
254 pTmpFmt->GetItemState( RES_CHRATR_COLOR, TRUE, &pItem );
255 *pColor = ((SvxColorItem*)pItem)->GetValue();
256 rInetAttr.SetVisited( true );
258 return true;
261 return false;
263 // <--
266 // 2. case:
267 // We do not want to apply the color set in the hyperlink
268 // attribute, instead we take the colors from the view options:
270 if ( pShell->GetWin() &&
272 (((SwTxtINetFmt&)rAttr).IsVisited() && SwViewOption::IsVisitedLinks()) ||
273 (!((SwTxtINetFmt&)rAttr).IsVisited() && SwViewOption::IsLinks())
277 if ( pColor )
279 if ( ((SwTxtINetFmt&)rAttr).IsVisited() )
281 // take color from view option 'visited link color'
282 *pColor = SwViewOption::GetVisitedLinksColor();
284 else
286 // take color from view option 'unvisited link color'
287 *pColor = SwViewOption::GetLinksColor();
290 return true;
293 return false;
296 /*************************************************************************
297 * SwAttrHandler::SwAttrStack::SwAttrStack()
298 *************************************************************************/
300 inline SwAttrHandler::SwAttrStack::SwAttrStack()
301 : nCount( 0 ), nSize( INITIAL_NUM_ATTR )
303 pArray = pInitialArray;
306 /*************************************************************************
307 * SwAttrHandler::SwAttrStack::Insert()
308 *************************************************************************/
310 void SwAttrHandler::SwAttrStack::Insert( const SwTxtAttr& rAttr, const USHORT nPos )
312 // do we still have enough space?
313 if ( nCount >= nSize )
315 // we are still in our initial array
316 if ( INITIAL_NUM_ATTR == nSize )
318 nSize += STACK_INCREMENT;
319 pArray = new SwTxtAttr*[ nSize ];
320 // copy from pInitArray to new Array
321 memcpy( pArray, pInitialArray,
322 INITIAL_NUM_ATTR * sizeof(SwTxtAttr*)
325 // we are in new memory
326 else
328 nSize += STACK_INCREMENT;
329 SwTxtAttr** pTmpArray = new SwTxtAttr*[ nSize ];
330 // copy from pArray to new Array
331 memcpy( pTmpArray, pArray, nCount * sizeof(SwTxtAttr*) );
332 // free old array
333 delete [] pArray;
334 pArray = pTmpArray;
338 ASSERT( nPos <= nCount, "wrong position for insert operation");
340 if ( nPos < nCount )
341 memmove( pArray + nPos + 1, pArray + nPos,
342 ( nCount - nPos ) * sizeof(SwTxtAttr*)
344 pArray[ nPos ] = (SwTxtAttr*)&rAttr;
346 nCount++;
349 /*************************************************************************
350 * SwAttrHandler::SwAttrStack::Remove()
351 *************************************************************************/
353 void SwAttrHandler::SwAttrStack::Remove( const SwTxtAttr& rAttr )
355 USHORT nPos = Pos( rAttr );
356 if ( nPos < nCount )
358 memmove( pArray + nPos, pArray + nPos + 1,
359 ( nCount - 1 - nPos ) * sizeof(SwTxtAttr*)
361 nCount--;
365 /*************************************************************************
366 * SwAttrHandler::SwAttrStack::Top()
367 *************************************************************************/
369 const SwTxtAttr* SwAttrHandler::SwAttrStack::Top() const
371 return nCount ? pArray[ nCount - 1 ] : 0;
374 /*************************************************************************
375 * SwAttrHandler::SwAttrStack::Pos()
376 *************************************************************************/
378 USHORT SwAttrHandler::SwAttrStack::Pos( const SwTxtAttr& rAttr ) const
380 if ( ! nCount )
381 // empty stack
382 return USHRT_MAX;
384 for ( USHORT nIdx = nCount; nIdx > 0; )
386 if ( &rAttr == pArray[ --nIdx ] )
387 return nIdx;
390 // element not found
391 return USHRT_MAX;
394 /*************************************************************************
395 * SwAttrHandler::SwAttrHandler()
396 *************************************************************************/
398 SwAttrHandler::SwAttrHandler() : mpShell( 0 ), pFnt( 0 ), bVertLayout( sal_False )
401 memset( pDefaultArray, 0, NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) );
404 SwAttrHandler::~SwAttrHandler()
406 delete pFnt;
409 /*************************************************************************
410 * SwAttrHandler::Init()
411 *************************************************************************/
413 void SwAttrHandler::Init( const SwAttrSet& rAttrSet,
414 const IDocumentSettingAccess& rIDocumentSettingAcces,
415 const ViewShell* pSh )
417 mpIDocumentSettingAccess = &rIDocumentSettingAcces;
418 mpShell = pSh;
420 for ( USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++ )
421 pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i, TRUE );
424 void SwAttrHandler::Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAS,
425 const IDocumentSettingAccess& rIDocumentSettingAcces,
426 const ViewShell* pSh,
427 SwFont& rFnt, sal_Bool bVL )
429 // initialize default array
430 memcpy( pDefaultArray, pPoolItem,
431 NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) );
433 mpIDocumentSettingAccess = &rIDocumentSettingAcces;
434 mpShell = pSh;
436 // do we have to apply additional paragraph attributes?
437 bVertLayout = bVL;
439 if ( pAS && pAS->Count() )
441 SfxItemIter aIter( *pAS );
442 USHORT nWhich;
443 const SfxPoolItem* pItem = aIter.GetCurItem();
444 while( TRUE )
446 nWhich = pItem->Which();
447 if (isCHRATR(nWhich))
449 pDefaultArray[ StackPos[ nWhich ] ] = pItem;
450 FontChg( *pItem, rFnt, sal_True );
453 if( aIter.IsAtEnd() )
454 break;
456 pItem = aIter.NextItem();
460 // It is possible, that Init is called more than once, e.g., in a
461 // SwTxtFrm::FormatOnceMore situation.
462 delete pFnt;
463 pFnt = new SwFont( rFnt );
466 void SwAttrHandler::Reset( )
468 for ( USHORT i = 0; i < NUM_ATTRIBUTE_STACKS; i++ )
469 aAttrStack[ i ].Reset();
472 /*************************************************************************
473 * SwAttrHandler::PushAndChg()
474 *************************************************************************/
476 void SwAttrHandler::PushAndChg( const SwTxtAttr& rAttr, SwFont& rFnt )
478 // these special attributes in fact represent a collection of attributes
479 // they have to be pushed to each stack they belong to
480 if ( RES_TXTATR_INETFMT == rAttr.Which() ||
481 RES_TXTATR_CHARFMT == rAttr.Which() ||
482 RES_TXTATR_AUTOFMT == rAttr.Which() )
484 const SfxItemSet* pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
485 if ( !pSet ) return;
487 for ( USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
489 const SfxPoolItem* pItem;
490 BOOL bRet = SFX_ITEM_SET == pSet->GetItemState( i, rAttr.Which() != RES_TXTATR_AUTOFMT, &pItem );
492 if ( bRet )
494 // we push rAttr onto the appropriate stack
495 if ( Push( rAttr, *pItem ) )
497 // we let pItem change rFnt
498 Color aColor;
499 if ( lcl_ChgHyperLinkColor( rAttr, *pItem, mpShell, &aColor ) )
501 SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
502 FontChg( aItemNext, rFnt, sal_True );
504 else
505 FontChg( *pItem, rFnt, sal_True );
510 // this is the usual case, we have a basic attribute, push it onto the
511 // stack and change the font
512 else
514 if ( Push( rAttr, rAttr.GetAttr() ) )
515 // we let pItem change rFnt
516 FontChg( rAttr.GetAttr(), rFnt, sal_True );
520 /*************************************************************************
521 * SwAttrHandler::Push()
522 *************************************************************************/
524 sal_Bool SwAttrHandler::Push( const SwTxtAttr& rAttr, const SfxPoolItem& rItem )
526 ASSERT( rItem.Which() < RES_TXTATR_WITHEND_END ||
527 RES_UNKNOWNATR_CONTAINER == rItem.Which() ,
528 "I do not want this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
530 // robust
531 if ( RES_TXTATR_WITHEND_END <= rItem.Which() ||
532 RES_UNKNOWNATR_CONTAINER == rItem.Which() )
533 return sal_False;
535 USHORT nStack = StackPos[ rItem.Which() ];
537 // attributes originating from redlining have highest priority
538 // second priority are hyperlink attributes, which have a color replacement
539 const SwTxtAttr* pTopAttr = aAttrStack[ nStack ].Top();
540 if ( !pTopAttr || rAttr.IsPriorityAttr() ||
541 ( !pTopAttr->IsPriorityAttr() &&
542 !lcl_ChgHyperLinkColor( *pTopAttr, rItem, mpShell, 0 ) ) )
544 aAttrStack[ nStack ].Push( rAttr );
545 return sal_True;
548 USHORT nPos = aAttrStack[ nStack ].Count();
549 ASSERT( nPos, "empty stack?" );
550 aAttrStack[ nStack ].Insert( rAttr, nPos - 1 );
551 return sal_False;
554 /*************************************************************************
555 * SwAttrHandler::PopAndChg()
556 *************************************************************************/
558 void SwAttrHandler::PopAndChg( const SwTxtAttr& rAttr, SwFont& rFnt )
560 // these special attributes in fact represent a collection of attributes
561 // they have to be removed from each stack they belong to
562 if ( RES_TXTATR_INETFMT == rAttr.Which() ||
563 RES_TXTATR_CHARFMT == rAttr.Which() ||
564 RES_TXTATR_AUTOFMT == rAttr.Which() )
566 const SfxItemSet* pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
567 if ( !pSet ) return;
569 for ( USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
571 const SfxPoolItem* pItem;
572 BOOL bRet = SFX_ITEM_SET == pSet->GetItemState( i, RES_TXTATR_AUTOFMT != rAttr.Which(), &pItem );
573 if ( bRet )
575 // we remove rAttr from the appropriate stack
576 USHORT nStackPos = StackPos[ i ];
577 aAttrStack[ nStackPos ].Remove( rAttr );
578 // reset font according to attribute on top of stack
579 // or default value
580 ActivateTop( rFnt, i );
584 // this is the usual case, we have a basic attribute, remove it from the
585 // stack and reset the font
586 else if ( RES_UNKNOWNATR_CONTAINER != rAttr.Which() )
588 aAttrStack[ StackPos[ rAttr.Which() ] ].Remove( rAttr );
589 // reset font according to attribute on top of stack
590 // or default value
591 ActivateTop( rFnt, rAttr.Which() );
595 /*************************************************************************
596 * SwAttrHandler::Pop()
598 * only used during redlining
599 *************************************************************************/
601 void SwAttrHandler::Pop( const SwTxtAttr& rAttr )
603 ASSERT( rAttr.Which() < RES_TXTATR_WITHEND_END ||
604 RES_UNKNOWNATR_CONTAINER == rAttr.Which() ,
605 "I do not have this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
607 if ( RES_UNKNOWNATR_CONTAINER != rAttr.Which() &&
608 rAttr.Which() < RES_TXTATR_WITHEND_END )
609 aAttrStack[ StackPos[ rAttr.Which() ] ].Remove( rAttr );
612 /*************************************************************************
613 * SwAttrHandler::ActivateTop()
614 *************************************************************************/
615 void SwAttrHandler::ActivateTop( SwFont& rFnt, const USHORT nAttr )
617 ASSERT( nAttr < RES_TXTATR_WITHEND_END,
618 "I cannot activate this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
620 const USHORT nStackPos = StackPos[ nAttr ];
621 const SwTxtAttr* pTopAt = aAttrStack[ nStackPos ].Top();
622 if ( pTopAt )
624 // check if top attribute is collection of attributes
625 if ( RES_TXTATR_INETFMT == pTopAt->Which() ||
626 RES_TXTATR_CHARFMT == pTopAt->Which() ||
627 RES_TXTATR_AUTOFMT == pTopAt->Which() )
629 const SfxItemSet* pSet = CharFmt::GetItemSet( pTopAt->GetAttr() );
630 const SfxPoolItem* pItemNext;
631 pSet->GetItemState( nAttr, RES_TXTATR_AUTOFMT != pTopAt->Which(), &pItemNext );
633 Color aColor;
634 if ( lcl_ChgHyperLinkColor( *pTopAt, *pItemNext, mpShell, &aColor ) )
636 SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
637 FontChg( aItemNext, rFnt, sal_False );
639 else
640 FontChg( *pItemNext, rFnt, sal_False );
642 else
643 FontChg( pTopAt->GetAttr(), rFnt, sal_False );
646 // default value has to be set, we only have default values for char attribs
647 else if ( nStackPos < NUM_DEFAULT_VALUES )
648 FontChg( *pDefaultArray[ nStackPos ], rFnt, sal_False );
649 else if ( RES_TXTATR_REFMARK == nAttr )
650 rFnt.GetRef()--;
651 else if ( RES_TXTATR_TOXMARK == nAttr )
652 rFnt.GetTox()--;
653 else if ( (RES_TXTATR_META == nAttr) || (RES_TXTATR_METAFIELD == nAttr) )
655 rFnt.GetMeta()--;
657 else if ( RES_TXTATR_CJK_RUBY == nAttr )
659 // ruby stack has no more attributes
660 // check, if an rotation attribute has to be applied
661 USHORT nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
662 sal_Bool bTwoLineAct = sal_False;
663 const SfxPoolItem* pTwoLineItem = 0;
664 const SwTxtAttr* pTwoLineAttr = aAttrStack[ nTwoLineStack ].Top();
666 if ( pTwoLineAttr )
668 pTwoLineItem = CharFmt::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
669 bTwoLineAct = ((SvxTwoLinesItem*)pTwoLineItem)->GetValue();
671 else
672 bTwoLineAct =
673 ((SvxTwoLinesItem*)pDefaultArray[ nTwoLineStack ])->GetValue();
675 if ( bTwoLineAct )
676 return;
678 // eventually, an rotate attribute has to be activated
679 USHORT nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
680 const SfxPoolItem* pRotateItem = 0;
681 const SwTxtAttr* pRotateAttr = aAttrStack[ nRotateStack ].Top();
683 if ( pRotateAttr )
685 pRotateItem = CharFmt::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
686 rFnt.SetVertical( ((SvxCharRotateItem*)pRotateItem)->GetValue(),
687 bVertLayout );
689 else
690 rFnt.SetVertical(
691 ((SvxCharRotateItem*)pDefaultArray[ nRotateStack ])->GetValue(),
692 bVertLayout
697 /*************************************************************************
698 * Font Changing Function
700 * When popping an attribute from the stack, the top mose remaining
701 * attribute in the stack becomes valid. The following function change
702 * a font depending on the stack id.
703 *************************************************************************/
705 void SwAttrHandler::FontChg(const SfxPoolItem& rItem, SwFont& rFnt, sal_Bool bPush )
707 switch ( rItem.Which() )
709 case RES_CHRATR_CASEMAP :
710 rFnt.SetCaseMap( ((SvxCaseMapItem&)rItem).GetCaseMap() );
711 break;
712 case RES_CHRATR_COLOR :
713 rFnt.SetColor( ((SvxColorItem&)rItem).GetValue() );
714 break;
715 case RES_CHRATR_CONTOUR :
716 rFnt.SetOutline( ((SvxContourItem&)rItem).GetValue() );
717 break;
718 case RES_CHRATR_CROSSEDOUT :
719 rFnt.SetStrikeout( ((SvxCrossedOutItem&)rItem).GetStrikeout() );
720 break;
721 case RES_CHRATR_ESCAPEMENT :
722 rFnt.SetEscapement( ((SvxEscapementItem&)rItem).GetEsc() );
723 rFnt.SetProportion( ((SvxEscapementItem&)rItem).GetProp() );
724 break;
725 case RES_CHRATR_FONT :
726 rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_LATIN );
727 rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_LATIN );
728 rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_LATIN );
729 rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_LATIN );
730 rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_LATIN );
731 break;
732 case RES_CHRATR_FONTSIZE :
733 rFnt.SetSize(Size(0,((SvxFontHeightItem&)rItem).GetHeight() ), SW_LATIN );
734 break;
735 case RES_CHRATR_KERNING :
736 rFnt.SetFixKerning( ((SvxKerningItem&)rItem).GetValue() );
737 break;
738 case RES_CHRATR_LANGUAGE :
739 rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_LATIN );
740 break;
741 case RES_CHRATR_POSTURE :
742 rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_LATIN );
743 break;
744 case RES_CHRATR_SHADOWED :
745 rFnt.SetShadow( ((SvxShadowedItem&)rItem).GetValue() );
746 break;
747 case RES_CHRATR_UNDERLINE :
749 const USHORT nStackPos = StackPos[ RES_CHRATR_HIDDEN ];
750 const SwTxtAttr* pTopAt = aAttrStack[ nStackPos ].Top();
752 const SfxPoolItem* pTmpItem = pTopAt ?
753 CharFmt::GetItem( *pTopAt, RES_CHRATR_HIDDEN ) :
754 pDefaultArray[ nStackPos ];
756 if( (mpShell && !mpShell->GetWin()) ||
757 (pTmpItem && !static_cast<const SvxCharHiddenItem*>(pTmpItem)->GetValue()) )
759 rFnt.SetUnderline( ((SvxUnderlineItem&)rItem).GetLineStyle() );
760 rFnt.SetUnderColor( ((SvxUnderlineItem&)rItem).GetColor() );
762 break;
764 case RES_CHRATR_OVERLINE :
765 rFnt.SetOverline( ((SvxOverlineItem&)rItem).GetLineStyle() );
766 rFnt.SetOverColor( ((SvxOverlineItem&)rItem).GetColor() );
767 break;
768 case RES_CHRATR_WEIGHT :
769 rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_LATIN );
770 break;
771 case RES_CHRATR_WORDLINEMODE :
772 rFnt.SetWordLineMode( ((SvxWordLineModeItem&)rItem).GetValue() );
773 break;
774 case RES_CHRATR_AUTOKERN :
775 if( ((SvxAutoKernItem&)rItem).GetValue() )
777 rFnt.SetAutoKern( ( !mpIDocumentSettingAccess ||
778 !mpIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION) ) ?
779 KERNING_FONTSPECIFIC :
780 KERNING_ASIAN );
782 else
783 rFnt.SetAutoKern( 0 );
784 break;
785 case RES_CHRATR_BLINK :
786 rFnt.SetBlink( ((SvxBlinkItem&)rItem).GetValue() );
787 break;
788 case RES_CHRATR_BACKGROUND :
789 rFnt.SetBackColor(new Color( ((SvxBrushItem&)rItem).GetColor() ) );
790 break;
791 case RES_CHRATR_CJK_FONT :
792 rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_CJK );
793 rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_CJK );
794 rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_CJK );
795 rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_CJK );
796 rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_CJK );
797 break;
798 case RES_CHRATR_CJK_FONTSIZE :
799 rFnt.SetSize(Size( 0, ((SvxFontHeightItem&)rItem).GetHeight()), SW_CJK);
800 break;
801 case RES_CHRATR_CJK_LANGUAGE :
802 rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_CJK );
803 break;
804 case RES_CHRATR_CJK_POSTURE :
805 rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_CJK );
806 break;
807 case RES_CHRATR_CJK_WEIGHT :
808 rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_CJK );
809 break;
810 case RES_CHRATR_CTL_FONT :
811 rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_CTL );
812 rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_CTL );
813 rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_CTL );
814 rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_CTL );
815 rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_CTL );
816 break;
817 case RES_CHRATR_CTL_FONTSIZE :
818 rFnt.SetSize(Size(0, ((SvxFontHeightItem&)rItem).GetHeight() ), SW_CTL);
819 break;
820 case RES_CHRATR_CTL_LANGUAGE :
821 rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_CTL );
822 break;
823 case RES_CHRATR_CTL_POSTURE :
824 rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_CTL );
825 break;
826 case RES_CHRATR_CTL_WEIGHT :
827 rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_CTL );
828 break;
829 case RES_CHRATR_EMPHASIS_MARK :
830 rFnt.SetEmphasisMark(
831 ((SvxEmphasisMarkItem&)rItem).GetEmphasisMark()
833 break;
834 case RES_CHRATR_SCALEW :
835 rFnt.SetPropWidth( ((SvxCharScaleWidthItem&)rItem).GetValue() );
836 break;
837 case RES_CHRATR_RELIEF :
838 rFnt.SetRelief( (FontRelief)((SvxCharReliefItem&)rItem).GetValue() );
839 break;
840 case RES_CHRATR_HIDDEN :
841 if( mpShell && mpShell->GetWin())
843 if ( ((SvxCharHiddenItem&)rItem).GetValue() )
844 rFnt.SetUnderline( UNDERLINE_DOTTED );
845 else
846 ActivateTop( rFnt, RES_CHRATR_UNDERLINE );
848 break;
849 case RES_CHRATR_ROTATE :
851 // rotate attribute is applied, when:
852 // 1. ruby stack is empty and
853 // 2. top of two line stack ( or default attribute )is an
854 // deactivated two line attribute
855 const bool bRuby =
856 0 != aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].Count();
858 if ( bRuby )
859 break;
861 USHORT nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
862 sal_Bool bTwoLineAct = sal_False;
863 const SfxPoolItem* pTwoLineItem = 0;
864 const SwTxtAttr* pTwoLineAttr = aAttrStack[ nTwoLineStack ].Top();
866 if ( pTwoLineAttr )
868 pTwoLineItem = CharFmt::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
869 bTwoLineAct = ((SvxTwoLinesItem*)pTwoLineItem)->GetValue();
871 else
872 bTwoLineAct =
873 ((SvxTwoLinesItem*)pDefaultArray[ nTwoLineStack ])->GetValue();
875 if ( !bTwoLineAct )
876 rFnt.SetVertical( ((SvxCharRotateItem&)rItem).GetValue(),
877 bVertLayout );
879 break;
881 case RES_CHRATR_TWO_LINES :
883 sal_Bool bRuby = 0 !=
884 aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].Count();
885 sal_Bool bTwoLineAct = sal_False;
887 // two line is activated, if
888 // 1. no ruby attribute is set and
889 // 2. attribute is active
890 bTwoLineAct = ((SvxTwoLinesItem&)rItem).GetValue();
892 if ( !bRuby && bTwoLineAct )
894 rFnt.SetVertical( 0, bVertLayout );
895 break;
898 // a deactivating two line attribute is on top of stack,
899 // check if rotate attribute has to be enabled
900 if ( bRuby )
901 break;
903 USHORT nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
904 const SfxPoolItem* pRotateItem = 0;
905 const SwTxtAttr* pRotateAttr = aAttrStack[ nRotateStack ].Top();
907 if ( pRotateAttr )
909 pRotateItem = CharFmt::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
910 rFnt.SetVertical( ((SvxCharRotateItem*)pRotateItem)->GetValue(),
911 bVertLayout );
913 else
914 rFnt.SetVertical(
915 ((SvxCharRotateItem*)pDefaultArray[ nRotateStack ])->GetValue(),
916 bVertLayout
918 break;
920 case RES_TXTATR_CJK_RUBY :
921 rFnt.SetVertical( 0, bVertLayout );
922 break;
923 case RES_TXTATR_REFMARK :
924 if ( bPush )
925 rFnt.GetRef()++;
926 else
927 rFnt.GetRef()--;
928 break;
929 case RES_TXTATR_TOXMARK :
930 if ( bPush )
931 rFnt.GetTox()++;
932 else
933 rFnt.GetTox()--;
934 break;
935 case RES_TXTATR_META:
936 case RES_TXTATR_METAFIELD:
937 if ( bPush )
938 rFnt.GetMeta()++;
939 else
940 rFnt.GetMeta()--;
941 break;
945 // Takes the default font and calculated the ascent and height
946 void SwAttrHandler::GetDefaultAscentAndHeight( ViewShell* pShell, OutputDevice& rOut,
947 USHORT& nAscent, USHORT& nHeight ) const
949 ASSERT( pFnt, "No font available for GetDefaultAscentAndHeight" )
951 if ( pFnt )
953 SwFont aFont( *pFnt );
954 nHeight = aFont.GetHeight( pShell, rOut );
955 nAscent = aFont.GetAscent( pShell, rOut );