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