Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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/blinkitem.hxx>
40 : #include <editeng/charrotateitem.hxx>
41 : #include <editeng/emphasismarkitem.hxx>
42 : #include <editeng/charscaleitem.hxx>
43 : #include <editeng/twolinesitem.hxx>
44 : #include <editeng/charhiddenitem.hxx>
45 : #include <editeng/boxitem.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>
56 :
57 : #define STACK_INCREMENT 4
58 :
59 : /**
60 : * Attribute to Stack Mapping
61 : *
62 : * Attributes applied to a text are pushed on different stacks. For each
63 : * stack, the top most attribute on the stack is valid. Because some
64 : * kinds of attributes have to be pushed to the same stacks we map their
65 : * ids to stack ids
66 : * Attention: The first NUM_DEFAULT_VALUES ( defined in swfntcch.hxx )
67 : * are stored in the defaultitem-cache, if you add one, you have to increase
68 : * NUM_DEFAULT_VALUES.
69 : * Also adjust NUM_ATTRIBUTE_STACKS in atrhndl.hxx.
70 : */
71 : const sal_uInt8 StackPos[ RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN + 1 ] =
72 : {
73 : 0, // // 0
74 : 1, // RES_CHRATR_CASEMAP = RES_CHRATR_BEGIN // 1
75 : 0, // RES_CHRATR_CHARSETCOLOR, // 2
76 : 2, // RES_CHRATR_COLOR, // 3
77 : 3, // RES_CHRATR_CONTOUR, // 4
78 : 4, // RES_CHRATR_CROSSEDOUT, // 5
79 : 5, // RES_CHRATR_ESCAPEMENT, // 6
80 : 6, // RES_CHRATR_FONT, // 7
81 : 7, // RES_CHRATR_FONTSIZE, // 8
82 : 8, // RES_CHRATR_KERNING, // 9
83 : 9, // RES_CHRATR_LANGUAGE, // 10
84 : 10, // RES_CHRATR_POSTURE, // 11
85 : 0, // RES_CHRATR_PROPORTIONALFONTSIZE, // 12
86 : 11, // RES_CHRATR_SHADOWED, // 13
87 : 12, // RES_CHRATR_UNDERLINE, // 14
88 : 13, // RES_CHRATR_WEIGHT, // 15
89 : 14, // RES_CHRATR_WORDLINEMODE, // 16
90 : 15, // RES_CHRATR_AUTOKERN, // 17
91 : 16, // RES_CHRATR_BLINK, // 18
92 : 17, // RES_CHRATR_NOHYPHEN, // 19
93 : 0, // RES_CHRATR_NOLINEBREAK, // 20
94 : 18, // RES_CHRATR_BACKGROUND, // 21
95 : 19, // RES_CHRATR_CJK_FONT, // 22
96 : 20, // RES_CHRATR_CJK_FONTSIZE, // 23
97 : 21, // RES_CHRATR_CJK_LANGUAGE, // 24
98 : 22, // RES_CHRATR_CJK_POSTURE, // 25
99 : 23, // RES_CHRATR_CJK_WEIGHT, // 26
100 : 24, // RES_CHRATR_CTL_FONT, // 27
101 : 25, // RES_CHRATR_CTL_FONTSIZE, // 28
102 : 26, // RES_CHRATR_CTL_LANGUAGE, // 29
103 : 27, // RES_CHRATR_CTL_POSTURE, // 30
104 : 28, // RES_CHRATR_CTL_WEIGHT, // 31
105 : 29, // RES_CHRATR_ROTATE, // 32
106 : 30, // RES_CHRATR_EMPHASIS_MARK, // 33
107 : 31, // RES_CHRATR_TWO_LINES, // 34
108 : 32, // RES_CHRATR_SCALEW, // 35
109 : 33, // RES_CHRATR_RELIEF, // 36
110 : 34, // RES_CHRATR_HIDDEN, // 37
111 : 35, // RES_CHRATR_OVERLINE, // 38
112 : 0, // RES_CHRATR_RSID, // 39
113 : 36, // RES_CHRATR_BOX, // 40
114 : 37, // RES_CHRATR_SHADOW, // 41
115 : 38, // RES_CHRATR_HIGHLIGHT, // 42
116 : 0, // RES_CHRATR_GRABBAG, // 43
117 : 0, // RES_CHRATR_BIDIRTL, // 44
118 : 0, // RES_CHRATR_IDCTHINT, // 45
119 : 39, // RES_TXTATR_REFMARK, // 46
120 : 40, // RES_TXTATR_TOXMARK, // 47
121 : 41, // RES_TXTATR_META, // 48
122 : 41, // RES_TXTATR_METAFIELD, // 49
123 : 0, // RES_TXTATR_AUTOFMT, // 50
124 : 0, // RES_TXTATR_INETFMT // 51
125 : 0, // RES_TXTATR_CHARFMT, // 52
126 : 42, // RES_TXTATR_CJK_RUBY, // 53
127 : 0, // RES_TXTATR_UNKNOWN_CONTAINER, // 54
128 : 43, // RES_TXTATR_INPUTFIELD // 55
129 : };
130 :
131 : namespace CharFmt
132 : {
133 :
134 : /// Returns the item set associated with an character/inet/auto style
135 820976 : const SfxItemSet* GetItemSet( const SfxPoolItem& rAttr )
136 : {
137 820976 : const SfxItemSet* pSet = 0;
138 :
139 820976 : if ( RES_TXTATR_AUTOFMT == rAttr.Which() )
140 : {
141 676754 : pSet = static_cast<const SwFmtAutoFmt&>(rAttr).GetStyleHandle().get();
142 : }
143 : else
144 : {
145 : // Get the attributes from the template
146 144222 : SwCharFmt* pFmt = RES_TXTATR_INETFMT == rAttr.Which() ?
147 26781 : ((SwFmtINetFmt&)rAttr).GetTxtINetFmt()->GetCharFmt() :
148 171003 : ((SwFmtCharFmt&)rAttr).GetCharFmt();
149 144222 : if( pFmt )
150 : {
151 143760 : pSet = &pFmt->GetAttrSet();
152 : }
153 : }
154 :
155 820976 : return pSet;
156 : }
157 :
158 : /// Extracts pool item of type nWhich from rAttr
159 505678 : const SfxPoolItem* GetItem( const SwTxtAttr& rAttr, sal_uInt16 nWhich )
160 : {
161 1501850 : if ( RES_TXTATR_INETFMT == rAttr.Which() ||
162 931240 : RES_TXTATR_CHARFMT == rAttr.Which() ||
163 425562 : RES_TXTATR_AUTOFMT == rAttr.Which() )
164 : {
165 487779 : const SfxItemSet* pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
166 487779 : if ( !pSet ) return 0;
167 :
168 487671 : bool bInParent = RES_TXTATR_AUTOFMT != rAttr.Which();
169 : const SfxPoolItem* pItem;
170 487671 : bool bRet = SfxItemState::SET == pSet->GetItemState( nWhich, bInParent, &pItem );
171 :
172 487671 : return bRet ? pItem : 0;
173 : }
174 :
175 17899 : return ( nWhich == rAttr.Which() ) ? &rAttr.GetAttr() : 0;
176 : }
177 :
178 : /// Checks if item is included in character/inet/auto style
179 81774 : bool IsItemIncluded( const sal_uInt16 nWhich, const SwTxtAttr *pAttr )
180 : {
181 81774 : bool bRet = false;
182 :
183 81774 : const SfxItemSet* pItemSet = CharFmt::GetItemSet( pAttr->GetAttr() );
184 81774 : if ( pItemSet )
185 81774 : bRet = SfxItemState::SET == pItemSet->GetItemState( nWhich, true );
186 :
187 81774 : return bRet;
188 : }
189 : }
190 :
191 : /**
192 : * The color of hyperlinks is taken from the associated character attribute,
193 : * depending on its 'visited' state. There are actually two cases, which
194 : * should override the colors from the character attribute:
195 : * 1. We never take the 'visited' color during printing/pdf export/preview
196 : * 2. The user has chosen to override these colors in the view options
197 : */
198 452864 : static bool lcl_ChgHyperLinkColor( const SwTxtAttr& rAttr,
199 : const SfxPoolItem& rItem,
200 : const SwViewShell* pShell,
201 : Color* pColor )
202 : {
203 905728 : if ( !pShell ||
204 465922 : RES_TXTATR_INETFMT != rAttr.Which() ||
205 13058 : RES_CHRATR_COLOR != rItem.Which() )
206 449118 : return false;
207 :
208 : // #i15455#
209 : // 1. case:
210 : // We do not want to show visited links:
211 : // (printing, pdf export, page preview)
212 :
213 : SwTxtINetFmt & rINetAttr(const_cast<SwTxtINetFmt&>(
214 3746 : static_txtattr_cast<SwTxtINetFmt const&>(rAttr)));
215 11238 : if ( pShell->GetOut()->GetOutDevType() == OUTDEV_PRINTER ||
216 7492 : pShell->GetViewOptions()->IsPDFExport() ||
217 3746 : pShell->GetViewOptions()->IsPagePreview() )
218 : {
219 0 : if (rINetAttr.IsVisited())
220 : {
221 0 : if ( pColor )
222 : {
223 : // take color from character format 'unvisited link'
224 0 : rINetAttr.SetVisited(false);
225 0 : const SwCharFmt* pTmpFmt = rINetAttr.GetCharFmt();
226 : const SfxPoolItem* pItem;
227 0 : pTmpFmt->GetItemState( RES_CHRATR_COLOR, true, &pItem );
228 0 : *pColor = ((SvxColorItem*)pItem)->GetValue();
229 0 : rINetAttr.SetVisited(true);
230 : }
231 0 : return true;
232 : }
233 :
234 0 : return false;
235 : }
236 :
237 : // 2. case:
238 : // We do not want to apply the color set in the hyperlink
239 : // attribute, instead we take the colors from the view options:
240 :
241 7492 : if ( pShell->GetWin() &&
242 : (
243 7492 : (rINetAttr.IsVisited() && SwViewOption::IsVisitedLinks()) ||
244 7492 : (!rINetAttr.IsVisited() && SwViewOption::IsLinks())
245 : )
246 : )
247 : {
248 0 : if ( pColor )
249 : {
250 0 : if (rINetAttr.IsVisited())
251 : {
252 : // take color from view option 'visited link color'
253 0 : *pColor = SwViewOption::GetVisitedLinksColor();
254 : }
255 : else
256 : {
257 : // take color from view option 'unvisited link color'
258 0 : *pColor = SwViewOption::GetLinksColor();
259 : }
260 : }
261 0 : return true;
262 : }
263 :
264 3746 : return false;
265 : }
266 :
267 14059848 : inline SwAttrHandler::SwAttrStack::SwAttrStack()
268 14059848 : : nCount( 0 ), nSize( INITIAL_NUM_ATTR )
269 : {
270 14059848 : pArray = pInitialArray;
271 14059848 : }
272 :
273 460826 : void SwAttrHandler::SwAttrStack::Insert( const SwTxtAttr& rAttr, const sal_uInt16 nPos )
274 : {
275 : // do we still have enough space?
276 460826 : if ( nCount >= nSize )
277 : {
278 : // we are still in our initial array
279 40 : if ( INITIAL_NUM_ATTR == nSize )
280 : {
281 40 : nSize += STACK_INCREMENT;
282 40 : pArray = new SwTxtAttr*[ nSize ];
283 : // copy from pInitArray to new Array
284 : memcpy( pArray, pInitialArray,
285 : INITIAL_NUM_ATTR * sizeof(SwTxtAttr*)
286 40 : );
287 : }
288 : // we are in new memory
289 : else
290 : {
291 0 : nSize += STACK_INCREMENT;
292 0 : SwTxtAttr** pTmpArray = new SwTxtAttr*[ nSize ];
293 : // copy from pArray to new Array
294 0 : memcpy( pTmpArray, pArray, nCount * sizeof(SwTxtAttr*) );
295 : // free old array
296 0 : delete [] pArray;
297 0 : pArray = pTmpArray;
298 : }
299 : }
300 :
301 : OSL_ENSURE( nPos <= nCount, "wrong position for insert operation");
302 :
303 460826 : if ( nPos < nCount )
304 36 : memmove( pArray + nPos + 1, pArray + nPos,
305 18 : ( nCount - nPos ) * sizeof(SwTxtAttr*)
306 54 : );
307 460826 : pArray[ nPos ] = (SwTxtAttr*)&rAttr;
308 :
309 460826 : nCount++;
310 460826 : }
311 :
312 132342 : void SwAttrHandler::SwAttrStack::Remove( const SwTxtAttr& rAttr )
313 : {
314 132342 : sal_uInt16 nPos = Pos( rAttr );
315 132342 : if ( nPos < nCount )
316 : {
317 397026 : memmove( pArray + nPos, pArray + nPos + 1,
318 132342 : ( nCount - 1 - nPos ) * sizeof(SwTxtAttr*)
319 529368 : );
320 132342 : nCount--;
321 : }
322 132342 : }
323 :
324 614580 : const SwTxtAttr* SwAttrHandler::SwAttrStack::Top() const
325 : {
326 614580 : return nCount ? pArray[ nCount - 1 ] : 0;
327 : }
328 :
329 132342 : sal_uInt16 SwAttrHandler::SwAttrStack::Pos( const SwTxtAttr& rAttr ) const
330 : {
331 132342 : if ( ! nCount )
332 : // empty stack
333 0 : return USHRT_MAX;
334 :
335 265054 : for ( sal_uInt16 nIdx = nCount; nIdx > 0; )
336 : {
337 132712 : if ( &rAttr == pArray[ --nIdx ] )
338 132342 : return nIdx;
339 : }
340 :
341 : // element not found
342 0 : return USHRT_MAX;
343 : }
344 :
345 319542 : SwAttrHandler::SwAttrHandler()
346 : : mpIDocumentSettingAccess(NULL)
347 : , mpShell(NULL)
348 : , pFnt(NULL)
349 319542 : , bVertLayout(false)
350 : {
351 319542 : memset( pDefaultArray, 0, NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) );
352 319542 : }
353 :
354 639084 : SwAttrHandler::~SwAttrHandler()
355 : {
356 319542 : delete pFnt;
357 319542 : }
358 :
359 562 : void SwAttrHandler::Init( const SwAttrSet& rAttrSet,
360 : const IDocumentSettingAccess& rIDocumentSettingAcces,
361 : const SwViewShell* pSh )
362 : {
363 562 : mpIDocumentSettingAccess = &rIDocumentSettingAcces;
364 562 : mpShell = pSh;
365 :
366 25852 : for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++ )
367 25290 : pDefaultArray[ StackPos[ i ] ] = &rAttrSet.Get( i, true );
368 562 : }
369 :
370 318980 : void SwAttrHandler::Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAS,
371 : const IDocumentSettingAccess& rIDocumentSettingAcces,
372 : const SwViewShell* pSh,
373 : SwFont& rFnt, bool bVL )
374 : {
375 : // initialize default array
376 : memcpy( pDefaultArray, pPoolItem,
377 318980 : NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) );
378 :
379 318980 : mpIDocumentSettingAccess = &rIDocumentSettingAcces;
380 318980 : mpShell = pSh;
381 :
382 : // do we have to apply additional paragraph attributes?
383 318980 : bVertLayout = bVL;
384 :
385 318980 : if ( pAS && pAS->Count() )
386 : {
387 204150 : SfxItemIter aIter( *pAS );
388 : sal_uInt16 nWhich;
389 204150 : const SfxPoolItem* pItem = aIter.GetCurItem();
390 : while( true )
391 : {
392 1008674 : nWhich = pItem->Which();
393 1008674 : if (isCHRATR(nWhich))
394 : {
395 192984 : pDefaultArray[ StackPos[ nWhich ] ] = pItem;
396 192984 : FontChg( *pItem, rFnt, true );
397 : }
398 :
399 1008674 : if( aIter.IsAtEnd() )
400 204150 : break;
401 :
402 804524 : pItem = aIter.NextItem();
403 204150 : }
404 : }
405 :
406 : // It is possible, that Init is called more than once, e.g., in a
407 : // SwTxtFrm::FormatOnceMore situation.
408 318980 : delete pFnt;
409 318980 : pFnt = new SwFont( rFnt );
410 318980 : }
411 :
412 116153 : void SwAttrHandler::Reset( )
413 : {
414 5226885 : for ( sal_uInt16 i = 0; i < NUM_ATTRIBUTE_STACKS; i++ )
415 5110732 : aAttrStack[ i ].Reset();
416 116153 : }
417 :
418 114560 : void SwAttrHandler::PushAndChg( const SwTxtAttr& rAttr, SwFont& rFnt )
419 : {
420 : // these special attributes in fact represent a collection of attributes
421 : // they have to be pushed to each stack they belong to
422 339334 : if ( RES_TXTATR_INETFMT == rAttr.Which() ||
423 202684 : RES_TXTATR_CHARFMT == rAttr.Which() ||
424 88124 : RES_TXTATR_AUTOFMT == rAttr.Which() )
425 : {
426 101276 : const SfxItemSet* pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
427 215836 : if ( !pSet ) return;
428 :
429 4653176 : for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
430 : {
431 : const SfxPoolItem* pItem;
432 4552020 : bool bRet = SfxItemState::SET == pSet->GetItemState( i, rAttr.Which() != RES_TXTATR_AUTOFMT, &pItem );
433 :
434 4552020 : if ( bRet )
435 : {
436 : // we push rAttr onto the appropriate stack
437 447542 : if ( Push( rAttr, *pItem ) )
438 : {
439 : // we let pItem change rFnt
440 447524 : Color aColor;
441 447524 : if ( lcl_ChgHyperLinkColor( rAttr, *pItem, mpShell, &aColor ) )
442 : {
443 0 : SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
444 0 : FontChg( aItemNext, rFnt, true );
445 : }
446 : else
447 447524 : FontChg( *pItem, rFnt, true );
448 : }
449 : }
450 : }
451 : }
452 : // this is the usual case, we have a basic attribute, push it onto the
453 : // stack and change the font
454 : else
455 : {
456 13284 : if ( Push( rAttr, rAttr.GetAttr() ) )
457 : // we let pItem change rFnt
458 13284 : FontChg( rAttr.GetAttr(), rFnt, true );
459 : }
460 : }
461 :
462 460826 : bool SwAttrHandler::Push( const SwTxtAttr& rAttr, const SfxPoolItem& rItem )
463 : {
464 : OSL_ENSURE( rItem.Which() < RES_TXTATR_WITHEND_END,
465 : "I do not want this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
466 :
467 : // robust
468 460826 : if ( RES_TXTATR_WITHEND_END <= rItem.Which() )
469 0 : return false;
470 :
471 460826 : const sal_uInt16 nStack = StackPos[ rItem.Which() ];
472 :
473 : // attributes originating from redlining have highest priority
474 : // second priority are hyperlink attributes, which have a color replacement
475 460826 : const SwTxtAttr* pTopAttr = aAttrStack[ nStack ].Top();
476 460826 : if ( !pTopAttr
477 4274 : || rAttr.IsPriorityAttr()
478 925116 : || ( !pTopAttr->IsPriorityAttr()
479 3464 : && !lcl_ChgHyperLinkColor( *pTopAttr, rItem, mpShell, 0 ) ) )
480 : {
481 460808 : aAttrStack[ nStack ].Push( rAttr );
482 460808 : return true;
483 : }
484 :
485 18 : const sal_uInt16 nPos = aAttrStack[ nStack ].Count();
486 : OSL_ENSURE( nPos, "empty stack?" );
487 18 : aAttrStack[ nStack ].Insert( rAttr, nPos - 1 );
488 18 : return false;
489 : }
490 :
491 30212 : void SwAttrHandler::PopAndChg( const SwTxtAttr& rAttr, SwFont& rFnt )
492 : {
493 30212 : if ( RES_TXTATR_WITHEND_END <= rAttr.Which() )
494 0 : return; // robust
495 :
496 : // these special attributes in fact represent a collection of attributes
497 : // they have to be removed from each stack they belong to
498 88522 : if ( RES_TXTATR_INETFMT == rAttr.Which() ||
499 50290 : RES_TXTATR_CHARFMT == rAttr.Which() ||
500 20078 : RES_TXTATR_AUTOFMT == rAttr.Which() )
501 : {
502 25386 : const SfxItemSet* pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
503 25386 : if ( !pSet ) return;
504 :
505 1166652 : for ( sal_uInt16 i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++)
506 : {
507 : const SfxPoolItem* pItem;
508 1141290 : bool bRet = SfxItemState::SET == pSet->GetItemState( i, RES_TXTATR_AUTOFMT != rAttr.Which(), &pItem );
509 1141290 : if ( bRet )
510 : {
511 : // we remove rAttr from the appropriate stack
512 120724 : const sal_uInt16 nStackPos = StackPos[ i ];
513 120724 : aAttrStack[ nStackPos ].Remove( rAttr );
514 : // reset font according to attribute on top of stack
515 : // or default value
516 120724 : ActivateTop( rFnt, i );
517 : }
518 : }
519 : }
520 : // this is the usual case, we have a basic attribute, remove it from the
521 : // stack and reset the font
522 : else
523 : {
524 4826 : aAttrStack[ StackPos[ rAttr.Which() ] ].Remove( rAttr );
525 : // reset font according to attribute on top of stack
526 : // or default value
527 4826 : ActivateTop( rFnt, rAttr.Which() );
528 : }
529 : }
530 :
531 : /// Only used during redlining
532 6792 : void SwAttrHandler::Pop( const SwTxtAttr& rAttr )
533 : {
534 : OSL_ENSURE( rAttr.Which() < RES_TXTATR_WITHEND_END,
535 : "I do not have this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
536 :
537 6792 : if ( rAttr.Which() < RES_TXTATR_WITHEND_END )
538 : {
539 6792 : aAttrStack[ StackPos[ rAttr.Which() ] ].Remove( rAttr );
540 : }
541 6792 : }
542 :
543 126548 : void SwAttrHandler::ActivateTop( SwFont& rFnt, const sal_uInt16 nAttr )
544 : {
545 : OSL_ENSURE( nAttr < RES_TXTATR_WITHEND_END,
546 : "I cannot activate this attribute, nWhich >= RES_TXTATR_WITHEND_END" );
547 :
548 126548 : const sal_uInt16 nStackPos = StackPos[ nAttr ];
549 126548 : const SwTxtAttr* pTopAt = aAttrStack[ nStackPos ].Top();
550 126548 : if ( pTopAt )
551 : {
552 2492 : const SfxPoolItem* pItemNext(NULL);
553 :
554 : // check if top attribute is collection of attributes
555 6772 : if ( RES_TXTATR_INETFMT == pTopAt->Which() ||
556 3272 : RES_TXTATR_CHARFMT == pTopAt->Which() ||
557 780 : RES_TXTATR_AUTOFMT == pTopAt->Which() )
558 : {
559 1876 : const SfxItemSet* pSet = CharFmt::GetItemSet( pTopAt->GetAttr() );
560 1876 : if (pSet)
561 1876 : pSet->GetItemState( nAttr, RES_TXTATR_AUTOFMT != pTopAt->Which(), &pItemNext );
562 : }
563 :
564 2492 : if (pItemNext)
565 : {
566 1876 : Color aColor;
567 1876 : if ( lcl_ChgHyperLinkColor( *pTopAt, *pItemNext, mpShell, &aColor ) )
568 : {
569 0 : SvxColorItem aItemNext( aColor, RES_CHRATR_COLOR );
570 0 : FontChg( aItemNext, rFnt, false );
571 : }
572 : else
573 1876 : FontChg( *pItemNext, rFnt, false );
574 : }
575 : else
576 616 : FontChg( pTopAt->GetAttr(), rFnt, false );
577 : }
578 :
579 : // default value has to be set, we only have default values for char attribs
580 124056 : else if ( nStackPos < NUM_DEFAULT_VALUES )
581 122534 : FontChg( *pDefaultArray[ nStackPos ], rFnt, false );
582 1522 : else if ( RES_TXTATR_REFMARK == nAttr )
583 20 : rFnt.GetRef()--;
584 1502 : else if ( RES_TXTATR_TOXMARK == nAttr )
585 20 : rFnt.GetTox()--;
586 1482 : else if ( (RES_TXTATR_META == nAttr) || (RES_TXTATR_METAFIELD == nAttr) )
587 : {
588 930 : rFnt.GetMeta()--;
589 : }
590 552 : else if ( RES_TXTATR_CJK_RUBY == nAttr )
591 : {
592 : // ruby stack has no more attributes
593 : // check, if an rotation attribute has to be applied
594 506 : const sal_uInt16 nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
595 506 : bool bTwoLineAct = false;
596 506 : const SwTxtAttr* pTwoLineAttr = aAttrStack[ nTwoLineStack ].Top();
597 :
598 506 : if ( pTwoLineAttr )
599 : {
600 0 : const SfxPoolItem* pTwoLineItem = CharFmt::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
601 0 : bTwoLineAct = ((SvxTwoLinesItem*)pTwoLineItem)->GetValue();
602 : }
603 : else
604 : bTwoLineAct =
605 506 : ((SvxTwoLinesItem*)pDefaultArray[ nTwoLineStack ])->GetValue();
606 :
607 506 : if ( bTwoLineAct )
608 126548 : return;
609 :
610 : // eventually, an rotate attribute has to be activated
611 506 : const sal_uInt16 nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
612 506 : const SwTxtAttr* pRotateAttr = aAttrStack[ nRotateStack ].Top();
613 :
614 506 : if ( pRotateAttr )
615 : {
616 0 : const SfxPoolItem* pRotateItem = CharFmt::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
617 0 : rFnt.SetVertical( ((SvxCharRotateItem*)pRotateItem)->GetValue(),
618 0 : bVertLayout );
619 : }
620 : else
621 : rFnt.SetVertical(
622 506 : ((SvxCharRotateItem*)pDefaultArray[ nRotateStack ])->GetValue(),
623 : bVertLayout
624 1012 : );
625 : }
626 46 : else if ( RES_TXTATR_INPUTFIELD == nAttr )
627 46 : rFnt.GetInputField()--;
628 : }
629 :
630 : /**
631 : * When popping an attribute from the stack, the top mose remaining
632 : * attribute in the stack becomes valid. The following function change
633 : * a font depending on the stack id.
634 : */
635 778818 : void SwAttrHandler::FontChg(const SfxPoolItem& rItem, SwFont& rFnt, bool bPush )
636 : {
637 778818 : switch ( rItem.Which() )
638 : {
639 : case RES_CHRATR_CASEMAP :
640 4236 : rFnt.SetCaseMap( ((SvxCaseMapItem&)rItem).GetCaseMap() );
641 4236 : break;
642 : case RES_CHRATR_COLOR :
643 70040 : rFnt.SetColor( ((SvxColorItem&)rItem).GetValue() );
644 70040 : break;
645 : case RES_CHRATR_CONTOUR :
646 1994 : rFnt.SetOutline( ((SvxContourItem&)rItem).GetValue() );
647 1994 : break;
648 : case RES_CHRATR_CROSSEDOUT :
649 5460 : rFnt.SetStrikeout( ((SvxCrossedOutItem&)rItem).GetStrikeout() );
650 5460 : break;
651 : case RES_CHRATR_ESCAPEMENT :
652 5990 : rFnt.SetEscapement( ((SvxEscapementItem&)rItem).GetEsc() );
653 5990 : rFnt.SetProportion( ((SvxEscapementItem&)rItem).GetProp() );
654 5990 : break;
655 : case RES_CHRATR_FONT :
656 73560 : rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_LATIN );
657 73560 : rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_LATIN );
658 73560 : rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_LATIN );
659 73560 : rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_LATIN );
660 73560 : rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_LATIN );
661 73560 : break;
662 : case RES_CHRATR_FONTSIZE :
663 92990 : rFnt.SetSize(Size(0,((SvxFontHeightItem&)rItem).GetHeight() ), SW_LATIN );
664 92990 : break;
665 : case RES_CHRATR_KERNING :
666 4466 : rFnt.SetFixKerning( ((SvxKerningItem&)rItem).GetValue() );
667 4466 : break;
668 : case RES_CHRATR_LANGUAGE :
669 22692 : rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_LATIN );
670 22692 : break;
671 : case RES_CHRATR_POSTURE :
672 23748 : rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_LATIN );
673 23748 : break;
674 : case RES_CHRATR_SHADOWED :
675 2304 : rFnt.SetShadow( ((SvxShadowedItem&)rItem).GetValue() );
676 2304 : break;
677 : case RES_CHRATR_UNDERLINE :
678 : {
679 25122 : const sal_uInt16 nStackPos = StackPos[ RES_CHRATR_HIDDEN ];
680 25122 : const SwTxtAttr* pTopAt = aAttrStack[ nStackPos ].Top();
681 :
682 : const SfxPoolItem* pTmpItem = pTopAt ?
683 : CharFmt::GetItem( *pTopAt, RES_CHRATR_HIDDEN ) :
684 25122 : pDefaultArray[ nStackPos ];
685 :
686 50232 : if( (mpShell && !mpShell->GetWin()) ||
687 25122 : (pTmpItem && !static_cast<const SvxCharHiddenItem*>(pTmpItem)->GetValue()) )
688 : {
689 25110 : rFnt.SetUnderline( ((SvxUnderlineItem&)rItem).GetLineStyle() );
690 25110 : rFnt.SetUnderColor( ((SvxUnderlineItem&)rItem).GetColor() );
691 : }
692 25122 : break;
693 : }
694 : case RES_CHRATR_BOX:
695 : {
696 784 : const SvxBoxItem& aBoxItem = static_cast<const SvxBoxItem&>(rItem);
697 784 : rFnt.SetTopBorder( aBoxItem.GetTop() );
698 784 : rFnt.SetBottomBorder( aBoxItem.GetBottom() );
699 784 : rFnt.SetRightBorder( aBoxItem.GetRight() );
700 784 : rFnt.SetLeftBorder( aBoxItem.GetLeft() );
701 784 : rFnt.SetTopBorderDist( aBoxItem.GetDistance(BOX_LINE_TOP) );
702 784 : rFnt.SetBottomBorderDist( aBoxItem.GetDistance(BOX_LINE_BOTTOM) );
703 784 : rFnt.SetRightBorderDist( aBoxItem.GetDistance(BOX_LINE_RIGHT) );
704 784 : rFnt.SetLeftBorderDist( aBoxItem.GetDistance(BOX_LINE_LEFT) );
705 784 : break;
706 : }
707 : case RES_CHRATR_SHADOW:
708 : {
709 582 : const SvxShadowItem& aShadowItem = static_cast<const SvxShadowItem&>(rItem);
710 582 : rFnt.SetShadowColor( aShadowItem.GetColor() );
711 582 : rFnt.SetShadowWidth( aShadowItem.GetWidth() );
712 582 : rFnt.SetShadowLocation( aShadowItem.GetLocation() );
713 582 : break;
714 : }
715 : case RES_CHRATR_OVERLINE :
716 200 : rFnt.SetOverline( ((SvxOverlineItem&)rItem).GetLineStyle() );
717 200 : rFnt.SetOverColor( ((SvxOverlineItem&)rItem).GetColor() );
718 200 : break;
719 : case RES_CHRATR_WEIGHT :
720 48546 : rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_LATIN );
721 48546 : break;
722 : case RES_CHRATR_WORDLINEMODE :
723 2376 : rFnt.SetWordLineMode( ((SvxWordLineModeItem&)rItem).GetValue() );
724 2376 : break;
725 : case RES_CHRATR_AUTOKERN :
726 5536 : if( ((SvxAutoKernItem&)rItem).GetValue() )
727 : {
728 3760 : rFnt.SetAutoKern( ( !mpIDocumentSettingAccess ||
729 1880 : !mpIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION) ) ?
730 : KERNING_FONTSPECIFIC :
731 3760 : KERNING_ASIAN );
732 : }
733 : else
734 3656 : rFnt.SetAutoKern( 0 );
735 5536 : break;
736 : case RES_CHRATR_BLINK :
737 2496 : rFnt.SetBlink( ((SvxBlinkItem&)rItem).GetValue() );
738 2496 : break;
739 : case RES_CHRATR_BACKGROUND :
740 3848 : rFnt.SetBackColor(new Color( ((SvxBrushItem&)rItem).GetColor() ) );
741 3848 : break;
742 : case RES_CHRATR_HIGHLIGHT :
743 88 : rFnt.SetHighlightColor( ((SvxBrushItem&)rItem).GetColor() );
744 88 : break;
745 : case RES_CHRATR_CJK_FONT :
746 25500 : rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_CJK );
747 25500 : rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_CJK );
748 25500 : rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_CJK );
749 25500 : rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_CJK );
750 25500 : rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_CJK );
751 25500 : break;
752 : case RES_CHRATR_CJK_FONTSIZE :
753 90700 : rFnt.SetSize(Size( 0, ((SvxFontHeightItem&)rItem).GetHeight()), SW_CJK);
754 90700 : break;
755 : case RES_CHRATR_CJK_LANGUAGE :
756 5948 : rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_CJK );
757 5948 : break;
758 : case RES_CHRATR_CJK_POSTURE :
759 21130 : rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_CJK );
760 21130 : break;
761 : case RES_CHRATR_CJK_WEIGHT :
762 46750 : rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_CJK );
763 46750 : break;
764 : case RES_CHRATR_CTL_FONT :
765 45630 : rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_CTL );
766 45630 : rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_CTL );
767 45630 : rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_CTL );
768 45630 : rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_CTL );
769 45630 : rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_CTL );
770 45630 : break;
771 : case RES_CHRATR_CTL_FONTSIZE :
772 62996 : rFnt.SetSize(Size(0, ((SvxFontHeightItem&)rItem).GetHeight() ), SW_CTL);
773 62996 : break;
774 : case RES_CHRATR_CTL_LANGUAGE :
775 3894 : rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_CTL );
776 3894 : break;
777 : case RES_CHRATR_CTL_POSTURE :
778 2402 : rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_CTL );
779 2402 : break;
780 : case RES_CHRATR_CTL_WEIGHT :
781 12750 : rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_CTL );
782 12750 : break;
783 : case RES_CHRATR_EMPHASIS_MARK :
784 : rFnt.SetEmphasisMark(
785 1728 : ((SvxEmphasisMarkItem&)rItem).GetEmphasisMark()
786 1728 : );
787 1728 : break;
788 : case RES_CHRATR_SCALEW :
789 872 : rFnt.SetPropWidth( ((SvxCharScaleWidthItem&)rItem).GetValue() );
790 872 : break;
791 : case RES_CHRATR_RELIEF :
792 1590 : rFnt.SetRelief( (FontRelief)((SvxCharReliefItem&)rItem).GetValue() );
793 1590 : break;
794 : case RES_CHRATR_HIDDEN :
795 1100 : if( mpShell && mpShell->GetWin())
796 : {
797 1100 : if ( ((SvxCharHiddenItem&)rItem).GetValue() )
798 102 : rFnt.SetUnderline( UNDERLINE_DOTTED );
799 : else
800 998 : ActivateTop( rFnt, RES_CHRATR_UNDERLINE );
801 : }
802 1100 : break;
803 : case RES_CHRATR_ROTATE :
804 : {
805 : // rotate attribute is applied, when:
806 : // 1. ruby stack is empty and
807 : // 2. top of two line stack ( or default attribute )is an
808 : // deactivated two line attribute
809 : const bool bRuby =
810 1260 : 0 != aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].Count();
811 :
812 1260 : if ( bRuby )
813 312 : break;
814 :
815 948 : const sal_uInt16 nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ];
816 948 : bool bTwoLineAct = false;
817 948 : const SwTxtAttr* pTwoLineAttr = aAttrStack[ nTwoLineStack ].Top();
818 :
819 948 : if ( pTwoLineAttr )
820 : {
821 0 : const SfxPoolItem* pTwoLineItem = CharFmt::GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES );
822 0 : bTwoLineAct = ((SvxTwoLinesItem*)pTwoLineItem)->GetValue();
823 : }
824 : else
825 : bTwoLineAct =
826 948 : ((SvxTwoLinesItem*)pDefaultArray[ nTwoLineStack ])->GetValue();
827 :
828 948 : if ( !bTwoLineAct )
829 948 : rFnt.SetVertical( ((SvxCharRotateItem&)rItem).GetValue(),
830 1896 : bVertLayout );
831 :
832 948 : break;
833 : }
834 : case RES_CHRATR_TWO_LINES :
835 : {
836 : bool bRuby = 0 !=
837 1872 : aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].Count();
838 :
839 : // two line is activated, if
840 : // 1. no ruby attribute is set and
841 : // 2. attribute is active
842 1872 : if ( !bRuby && ((SvxTwoLinesItem&)rItem).GetValue() )
843 : {
844 1364 : rFnt.SetVertical( 0, bVertLayout );
845 1364 : break;
846 : }
847 :
848 : // a deactivating two line attribute is on top of stack,
849 : // check if rotate attribute has to be enabled
850 508 : if ( bRuby )
851 384 : break;
852 :
853 124 : const sal_uInt16 nRotateStack = StackPos[ RES_CHRATR_ROTATE ];
854 124 : const SwTxtAttr* pRotateAttr = aAttrStack[ nRotateStack ].Top();
855 :
856 124 : if ( pRotateAttr )
857 : {
858 76 : const SfxPoolItem* pRotateItem = CharFmt::GetItem( *pRotateAttr, RES_CHRATR_ROTATE );
859 76 : rFnt.SetVertical( ((SvxCharRotateItem*)pRotateItem)->GetValue(),
860 152 : bVertLayout );
861 : }
862 : else
863 : rFnt.SetVertical(
864 48 : ((SvxCharRotateItem*)pDefaultArray[ nRotateStack ])->GetValue(),
865 : bVertLayout
866 96 : );
867 124 : break;
868 : }
869 : case RES_TXTATR_CJK_RUBY :
870 1608 : rFnt.SetVertical( 0, bVertLayout );
871 1608 : break;
872 : case RES_TXTATR_REFMARK :
873 290 : if ( bPush )
874 266 : rFnt.GetRef()++;
875 : else
876 24 : rFnt.GetRef()--;
877 290 : break;
878 : case RES_TXTATR_TOXMARK :
879 300 : if ( bPush )
880 276 : rFnt.GetTox()++;
881 : else
882 24 : rFnt.GetTox()--;
883 300 : break;
884 : case RES_TXTATR_META:
885 : case RES_TXTATR_METAFIELD:
886 1394 : if ( bPush )
887 1196 : rFnt.GetMeta()++;
888 : else
889 198 : rFnt.GetMeta()--;
890 1394 : break;
891 : case RES_TXTATR_INPUTFIELD :
892 88 : if ( bPush )
893 88 : rFnt.GetInputField()++;
894 : else
895 0 : rFnt.GetInputField()--;
896 88 : break;
897 : }
898 778818 : }
899 :
900 : /// Takes the default font and calculated the ascent and height
901 19468 : void SwAttrHandler::GetDefaultAscentAndHeight( SwViewShell* pShell, OutputDevice& rOut,
902 : sal_uInt16& nAscent, sal_uInt16& nHeight ) const
903 : {
904 : OSL_ENSURE( pFnt, "No font available for GetDefaultAscentAndHeight" );
905 :
906 19468 : if ( pFnt )
907 : {
908 19468 : SwFont aFont( *pFnt );
909 19468 : nHeight = aFont.GetHeight( pShell, rOut );
910 19468 : nAscent = aFont.GetAscent( pShell, rOut );
911 : }
912 19738 : }
913 :
914 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|