Bump version to 4.1-6
[LibreOffice.git] / editeng / source / rtf / rtfitem.cxx
blobd397c767a128b7793f5d7ac69af0d091c03d94b8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <editeng/flstitem.hxx>
22 #include <editeng/fontitem.hxx>
23 #include <editeng/postitem.hxx>
24 #include <editeng/wghtitem.hxx>
25 #include <editeng/fhgtitem.hxx>
26 #include <editeng/fwdtitem.hxx>
27 #include <editeng/udlnitem.hxx>
28 #include <editeng/crossedoutitem.hxx>
29 #include <editeng/shdditem.hxx>
30 #include <editeng/autokernitem.hxx>
31 #include <editeng/wrlmitem.hxx>
32 #include <editeng/contouritem.hxx>
33 #include <editeng/prszitem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/charsetcoloritem.hxx>
36 #include <editeng/kernitem.hxx>
37 #include <editeng/cmapitem.hxx>
38 #include <editeng/escapementitem.hxx>
39 #include <editeng/langitem.hxx>
40 #include <editeng/nlbkitem.hxx>
41 #include <editeng/nhypitem.hxx>
42 #include <editeng/lcolitem.hxx>
43 #include <editeng/blinkitem.hxx>
44 #include <editeng/emphasismarkitem.hxx>
45 #include <editeng/twolinesitem.hxx>
46 #include <editeng/pbinitem.hxx>
47 #include <editeng/sizeitem.hxx>
48 #include <editeng/lrspitem.hxx>
49 #include <editeng/ulspitem.hxx>
50 #include <editeng/prntitem.hxx>
51 #include <editeng/opaqitem.hxx>
52 #include <editeng/protitem.hxx>
53 #include <editeng/shaditem.hxx>
54 #include <editeng/boxitem.hxx>
55 #include <editeng/formatbreakitem.hxx>
56 #include <editeng/keepitem.hxx>
57 #include <editeng/lineitem.hxx>
58 #include <editeng/brushitem.hxx>
59 #include <editeng/lspcitem.hxx>
60 #include <editeng/adjustitem.hxx>
61 #include <editeng/orphitem.hxx>
62 #include <editeng/widwitem.hxx>
63 #include <editeng/tstpitem.hxx>
64 #include <editeng/pmdlitem.hxx>
65 #include <editeng/spltitem.hxx>
66 #include <editeng/hyphenzoneitem.hxx>
67 #include <editeng/charscaleitem.hxx>
68 #include <editeng/charrotateitem.hxx>
69 #include <editeng/charreliefitem.hxx>
70 #include <editeng/paravertalignitem.hxx>
71 #include <editeng/forbiddenruleitem.hxx>
72 #include <editeng/hngpnctitem.hxx>
73 #include <editeng/scriptspaceitem.hxx>
74 #include <editeng/frmdiritem.hxx>
75 #include <editeng/charhiddenitem.hxx>
77 #include <svtools/rtftoken.h>
78 #include <svl/itempool.hxx>
79 #include <svl/itemiter.hxx>
81 #include <editeng/svxrtf.hxx>
82 #include <editeng/editids.hrc>
84 #define BRACELEFT '{'
85 #define BRACERIGHT '}'
87 using namespace ::com::sun::star;
88 using namespace editeng;
90 // Some helper functions
91 // char
92 inline const SvxEscapementItem& GetEscapement(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
93 { return (const SvxEscapementItem&)rSet.Get( nId,bInP); }
94 inline const SvxLineSpacingItem& GetLineSpacing(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
95 { return (const SvxLineSpacingItem&)rSet.Get( nId,bInP); }
96 // frm
97 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
98 { return (const SvxLRSpaceItem&)rSet.Get( nId,bInP); }
99 inline const SvxULSpaceItem& GetULSpace(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
100 { return (const SvxULSpaceItem&)rSet.Get( nId,bInP); }
102 #define PARDID ((RTFPardAttrMapIds*)&aPardMap[0])
103 #define PLAINID ((RTFPlainAttrMapIds*)&aPlainMap[0])
105 void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType, SfxItemSet& rSet,
106 SfxPoolItem& rItem )
108 const sal_uInt16 *pNormal = 0, *pCJK = 0, *pCTL = 0;
109 const RTFPlainAttrMapIds* pIds = (RTFPlainAttrMapIds*)&aPlainMap[0];
110 switch( rItem.Which() )
112 case SID_ATTR_CHAR_FONT:
113 pNormal = &pIds->nFont;
114 pCJK = &pIds->nCJKFont;
115 pCTL = &pIds->nCTLFont;
116 break;
118 case SID_ATTR_CHAR_FONTHEIGHT:
119 pNormal = &pIds->nFontHeight;
120 pCJK = &pIds->nCJKFontHeight;
121 pCTL = &pIds->nCTLFontHeight;
122 break;
124 case SID_ATTR_CHAR_POSTURE:
125 pNormal = &pIds->nPosture;
126 pCJK = &pIds->nCJKPosture;
127 pCTL = &pIds->nCTLPosture;
128 break;
130 case SID_ATTR_CHAR_WEIGHT:
131 pNormal = &pIds->nWeight;
132 pCJK = &pIds->nCJKWeight;
133 pCTL = &pIds->nCTLWeight;
134 break;
136 case SID_ATTR_CHAR_LANGUAGE:
137 pNormal = &pIds->nLanguage;
138 pCJK = &pIds->nCJKLanguage;
139 pCTL = &pIds->nCTLLanguage;
140 break;
142 case 0:
143 // it exist no WhichId - don't set this item
144 break;
146 default:
147 rSet.Put( rItem );
148 break;
151 if( DOUBLEBYTE_CHARTYPE == eType )
153 if( bIsLeftToRightDef && pCJK )
155 rItem.SetWhich( *pCJK );
156 rSet.Put( rItem );
159 else if( !bIsLeftToRightDef )
161 if( pCTL )
163 rItem.SetWhich( *pCTL );
164 rSet.Put( rItem );
167 else
169 if( LOW_CHARTYPE == eType )
171 if( pNormal )
173 rItem.SetWhich( *pNormal );
174 rSet.Put( rItem );
177 else if( HIGH_CHARTYPE == eType )
179 if( pCTL )
181 rItem.SetWhich( *pCTL );
182 rSet.Put( rItem );
185 else
187 if( pCJK )
189 rItem.SetWhich( *pCJK );
190 rSet.Put( rItem );
192 if( pCTL )
194 rItem.SetWhich( *pCTL );
195 rSet.Put( rItem );
197 if( pNormal )
199 rItem.SetWhich( *pNormal );
200 rSet.Put( rItem );
206 // --------------------
208 void SvxRTFParser::ReadAttr( int nToken, SfxItemSet* pSet )
210 DBG_ASSERT( pSet, "A SfxItemSet has to be provided as argument!" );
211 int bFirstToken = sal_True, bWeiter = sal_True;
212 sal_uInt16 nStyleNo = 0; // default
213 FontUnderline eUnderline;
214 FontUnderline eOverline;
215 FontEmphasisMark eEmphasis;
216 bPardTokenRead = sal_False;
217 RTF_CharTypeDef eCharType = NOTDEF_CHARTYPE;
218 sal_uInt16 nFontAlign;
220 int bChkStkPos = !bNewGroup && !aAttrStack.empty();
222 while( bWeiter && IsParserWorking() ) // as long as known Attribute are recognized
224 switch( nToken )
226 case RTF_PARD:
227 RTFPardPlain( sal_True, &pSet );
228 ResetPard();
229 nStyleNo = 0;
230 bPardTokenRead = sal_True;
231 break;
233 case RTF_PLAIN:
234 RTFPardPlain( sal_False, &pSet );
235 break;
237 default:
238 do { // middle checked loop
239 if( !bChkStkPos )
240 break;
242 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
243 if( !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
244 pAkt->nSttCnt == pInsPos->GetCntIdx() ))
245 break;
247 int nLastToken = GetStackPtr(-1)->nTokenId;
248 if( RTF_PARD == nLastToken || RTF_PLAIN == nLastToken )
249 break;
251 if( pAkt->aAttrSet.Count() || pAkt->pChildList ||
252 pAkt->nStyleNo )
254 // Open a new Group
255 SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
256 *pAkt, *pInsPos, sal_True );
257 pNew->SetRTFDefaults( GetRTFDefaults() );
259 // "Set" all valid attributes up until this point
260 AttrGroupEnd();
261 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd!
262 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
264 aAttrStack.push_back( pNew );
265 pAkt = pNew;
267 else
268 // continue to use this entry as a new one
269 pAkt->SetStartPos( *pInsPos );
271 pSet = &pAkt->aAttrSet;
272 } while( false );
274 switch( nToken )
276 case RTF_INTBL:
277 case RTF_PAGEBB:
278 case RTF_SBYS:
279 case RTF_CS:
280 case RTF_LS:
281 case RTF_ILVL:
282 UnknownAttrToken( nToken, pSet );
283 break;
285 case RTF_S:
286 if( bIsInReadStyleTab )
288 if( !bFirstToken )
289 SkipToken( -1 );
290 bWeiter = sal_False;
292 else
294 nStyleNo = -1 == nTokenValue ? 0 : sal_uInt16(nTokenValue);
295 /* setze am akt. auf dem AttrStack stehenden Style die
296 I sit on akt. which is on the immiediate sytle AttrStack */
297 // StyleNummer
298 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
299 if( !pAkt )
300 break;
302 pAkt->nStyleNo = sal_uInt16( nStyleNo );
305 break;
307 case RTF_KEEP:
308 if( PARDID->nSplit )
310 pSet->Put( SvxFmtSplitItem( sal_False, PARDID->nSplit ));
312 break;
314 case RTF_KEEPN:
315 if( PARDID->nKeep )
317 pSet->Put( SvxFmtKeepItem( sal_True, PARDID->nKeep ));
319 break;
321 case RTF_LEVEL:
322 if( PARDID->nOutlineLvl )
324 pSet->Put( SfxUInt16Item( PARDID->nOutlineLvl,
325 (sal_uInt16)nTokenValue ));
327 break;
329 case RTF_QL:
330 if( PARDID->nAdjust )
332 pSet->Put( SvxAdjustItem( SVX_ADJUST_LEFT, PARDID->nAdjust ));
334 break;
335 case RTF_QR:
336 if( PARDID->nAdjust )
338 pSet->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, PARDID->nAdjust ));
340 break;
341 case RTF_QJ:
342 if( PARDID->nAdjust )
344 pSet->Put( SvxAdjustItem( SVX_ADJUST_BLOCK, PARDID->nAdjust ));
346 break;
347 case RTF_QC:
348 if( PARDID->nAdjust )
350 pSet->Put( SvxAdjustItem( SVX_ADJUST_CENTER, PARDID->nAdjust ));
352 break;
354 case RTF_FI:
355 if( PARDID->nLRSpace )
357 SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
358 sal_uInt16 nSz = 0;
359 if( -1 != nTokenValue )
361 if( IsCalcValue() )
362 CalcValue();
363 nSz = sal_uInt16(nTokenValue);
365 aLR.SetTxtFirstLineOfst( nSz );
366 pSet->Put( aLR );
368 break;
370 case RTF_LI:
371 case RTF_LIN:
372 if( PARDID->nLRSpace )
374 SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
375 sal_uInt16 nSz = 0;
376 if( 0 < nTokenValue )
378 if( IsCalcValue() )
379 CalcValue();
380 nSz = sal_uInt16(nTokenValue);
382 aLR.SetTxtLeft( nSz );
383 pSet->Put( aLR );
385 break;
387 case RTF_RI:
388 case RTF_RIN:
389 if( PARDID->nLRSpace )
391 SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
392 sal_uInt16 nSz = 0;
393 if( 0 < nTokenValue )
395 if( IsCalcValue() )
396 CalcValue();
397 nSz = sal_uInt16(nTokenValue);
399 aLR.SetRight( nSz );
400 pSet->Put( aLR );
402 break;
404 case RTF_SB:
405 if( PARDID->nULSpace )
407 SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
408 sal_uInt16 nSz = 0;
409 if( 0 < nTokenValue )
411 if( IsCalcValue() )
412 CalcValue();
413 nSz = sal_uInt16(nTokenValue);
415 aUL.SetUpper( nSz );
416 pSet->Put( aUL );
418 break;
420 case RTF_SA:
421 if( PARDID->nULSpace )
423 SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
424 sal_uInt16 nSz = 0;
425 if( 0 < nTokenValue )
427 if( IsCalcValue() )
428 CalcValue();
429 nSz = sal_uInt16(nTokenValue);
431 aUL.SetLower( nSz );
432 pSet->Put( aUL );
434 break;
436 case RTF_SLMULT:
437 if( PARDID->nLinespacing && 1 == nTokenValue )
439 // then switches to multi-line!
440 SvxLineSpacingItem aLSpace( GetLineSpacing( *pSet,
441 PARDID->nLinespacing, sal_False ));
443 // how much do you get from the line height value?
445 // Proportional-Size:
446 // Ie, the ratio is (n / 240) twips
448 nTokenValue = 240;
449 if( IsCalcValue() )
450 CalcValue();
452 nTokenValue = short( 100L * aLSpace.GetLineHeight()
453 / long( nTokenValue ) );
455 if( nTokenValue > 200 ) // Data value for PropLnSp
456 nTokenValue = 200; // is one BYTE !!!
458 aLSpace.SetPropLineSpace( (const sal_uInt8)nTokenValue );
459 aLSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
461 pSet->Put( aLSpace );
463 break;
465 case RTF_SL:
466 if( PARDID->nLinespacing )
468 // Calculate the ratio between the default font and the
469 // specified size. The distance consists of the line height
470 // (100%) and the space above the line (20%).
471 SvxLineSpacingItem aLSpace(0, PARDID->nLinespacing);
473 nTokenValue = !bTokenHasValue ? 0 : nTokenValue;
474 if (1000 == nTokenValue )
475 nTokenValue = 240;
477 SvxLineSpace eLnSpc;
478 if (nTokenValue < 0)
480 eLnSpc = SVX_LINE_SPACE_FIX;
481 nTokenValue = -nTokenValue;
483 else if (nTokenValue == 0)
485 //if \sl0 is used, the line spacing is automatically
486 //determined
487 eLnSpc = SVX_LINE_SPACE_AUTO;
489 else
490 eLnSpc = SVX_LINE_SPACE_MIN;
492 if (IsCalcValue())
493 CalcValue();
495 if (eLnSpc != SVX_LINE_SPACE_AUTO)
496 aLSpace.SetLineHeight( (const sal_uInt16)nTokenValue );
498 aLSpace.GetLineSpaceRule() = eLnSpc;
499 pSet->Put(aLSpace);
501 break;
503 case RTF_NOCWRAP:
504 if( PARDID->nForbRule )
506 pSet->Put( SvxForbiddenRuleItem( sal_False,
507 PARDID->nForbRule ));
509 break;
510 case RTF_NOOVERFLOW:
511 if( PARDID->nHangPunct )
513 pSet->Put( SvxHangingPunctuationItem( sal_False,
514 PARDID->nHangPunct ));
516 break;
518 case RTF_ASPALPHA:
519 if( PARDID->nScriptSpace )
521 pSet->Put( SvxScriptSpaceItem( sal_True,
522 PARDID->nScriptSpace ));
524 break;
526 case RTF_FAFIXED:
527 case RTF_FAAUTO: nFontAlign = SvxParaVertAlignItem::AUTOMATIC;
528 goto SET_FONTALIGNMENT;
529 case RTF_FAHANG: nFontAlign = SvxParaVertAlignItem::TOP;
530 goto SET_FONTALIGNMENT;
531 case RTF_FAVAR: nFontAlign = SvxParaVertAlignItem::BOTTOM;
532 goto SET_FONTALIGNMENT;
533 case RTF_FACENTER: nFontAlign = SvxParaVertAlignItem::CENTER;
534 goto SET_FONTALIGNMENT;
535 case RTF_FAROMAN: nFontAlign = SvxParaVertAlignItem::BASELINE;
536 goto SET_FONTALIGNMENT;
537 SET_FONTALIGNMENT:
538 if( PARDID->nFontAlign )
540 pSet->Put( SvxParaVertAlignItem( nFontAlign,
541 PARDID->nFontAlign ));
543 break;
545 case RTF_B:
546 case RTF_AB:
547 if( IsAttrSttPos() ) // not in the text flow?
550 SvxWeightItem aTmpItem(
551 nTokenValue ? WEIGHT_BOLD : WEIGHT_NORMAL,
552 SID_ATTR_CHAR_WEIGHT );
553 SetScriptAttr( eCharType, *pSet, aTmpItem);
555 break;
557 case RTF_CAPS:
558 case RTF_SCAPS:
559 if( PLAINID->nCaseMap &&
560 IsAttrSttPos() ) // not in the text flow?
562 SvxCaseMap eCaseMap;
563 if( !nTokenValue )
564 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
565 else if( RTF_CAPS == nToken )
566 eCaseMap = SVX_CASEMAP_VERSALIEN;
567 else
568 eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
570 pSet->Put( SvxCaseMapItem( eCaseMap, PLAINID->nCaseMap ));
572 break;
574 case RTF_DN:
575 case RTF_SUB:
576 if( PLAINID->nEscapement )
578 const sal_uInt16 nEsc = PLAINID->nEscapement;
579 if( -1 == nTokenValue || RTF_SUB == nToken )
580 nTokenValue = 6;
581 if( IsCalcValue() )
582 CalcValue();
583 const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, sal_False );
584 short nEs;
585 sal_uInt8 nProp;
586 if( DFLT_ESC_AUTO_SUPER == rOld.GetEsc() )
588 nEs = DFLT_ESC_AUTO_SUB;
589 nProp = rOld.GetProp();
591 else
593 nEs = (short)-nTokenValue;
594 nProp = (nToken == RTF_SUB) ? DFLT_ESC_PROP : 100;
596 pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
598 break;
600 case RTF_NOSUPERSUB:
601 if( PLAINID->nEscapement )
603 const sal_uInt16 nEsc = PLAINID->nEscapement;
604 pSet->Put( SvxEscapementItem( nEsc ));
606 break;
608 case RTF_EXPND:
609 if( PLAINID->nKering )
611 if( -1 == nTokenValue )
612 nTokenValue = 0;
613 else
614 nTokenValue *= 5;
615 if( IsCalcValue() )
616 CalcValue();
617 pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
619 break;
621 case RTF_KERNING:
622 if( PLAINID->nAutoKerning )
624 if( -1 == nTokenValue )
625 nTokenValue = 0;
626 else
627 nTokenValue *= 10;
628 if( IsCalcValue() )
629 CalcValue();
630 pSet->Put( SvxAutoKernItem( 0 != nTokenValue,
631 PLAINID->nAutoKerning ));
633 break;
635 case RTF_EXPNDTW:
636 if( PLAINID->nKering )
638 if( -1 == nTokenValue )
639 nTokenValue = 0;
640 if( IsCalcValue() )
641 CalcValue();
642 pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
644 break;
646 case RTF_F:
647 case RTF_AF:
649 const Font& rSVFont = GetFont( sal_uInt16(nTokenValue) );
650 SvxFontItem aTmpItem( rSVFont.GetFamily(),
651 rSVFont.GetName(), rSVFont.GetStyleName(),
652 rSVFont.GetPitch(), rSVFont.GetCharSet(),
653 SID_ATTR_CHAR_FONT );
654 SetScriptAttr( eCharType, *pSet, aTmpItem );
655 if( RTF_F == nToken )
657 SetEncoding( rSVFont.GetCharSet() );
658 RereadLookahead();
661 break;
663 case RTF_FS:
664 case RTF_AFS:
666 if( -1 == nTokenValue )
667 nTokenValue = 240;
668 else
669 nTokenValue *= 10;
670 // #i66167#
671 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
672 // the converiosn takes now place in EditRTFParser since for other reasons
673 // the wrong MapUnit might still be use there
674 // if( IsCalcValue() )
675 // CalcValue();
676 SvxFontHeightItem aTmpItem(
677 (const sal_uInt16)nTokenValue, 100,
678 SID_ATTR_CHAR_FONTHEIGHT );
679 SetScriptAttr( eCharType, *pSet, aTmpItem );
681 break;
683 case RTF_I:
684 case RTF_AI:
685 if( IsAttrSttPos() ) // not in the text flow?
687 SvxPostureItem aTmpItem(
688 nTokenValue ? ITALIC_NORMAL : ITALIC_NONE,
689 SID_ATTR_CHAR_POSTURE );
690 SetScriptAttr( eCharType, *pSet, aTmpItem );
692 break;
694 case RTF_OUTL:
695 if( PLAINID->nContour &&
696 IsAttrSttPos() ) // not in the text flow?
698 pSet->Put( SvxContourItem( nTokenValue ? sal_True : sal_False,
699 PLAINID->nContour ));
701 break;
703 case RTF_SHAD:
704 if( PLAINID->nShadowed &&
705 IsAttrSttPos() ) // not in the text flow?
707 pSet->Put( SvxShadowedItem( nTokenValue ? sal_True : sal_False,
708 PLAINID->nShadowed ));
710 break;
712 case RTF_STRIKE:
713 if( PLAINID->nCrossedOut &&
714 IsAttrSttPos() ) // not in the text flow?
716 pSet->Put( SvxCrossedOutItem(
717 nTokenValue ? STRIKEOUT_SINGLE : STRIKEOUT_NONE,
718 PLAINID->nCrossedOut ));
720 break;
722 case RTF_STRIKED:
723 if( PLAINID->nCrossedOut ) // not in the text flow?
725 pSet->Put( SvxCrossedOutItem(
726 nTokenValue ? STRIKEOUT_DOUBLE : STRIKEOUT_NONE,
727 PLAINID->nCrossedOut ));
729 break;
731 case RTF_UL:
732 if( !IsAttrSttPos() )
733 break;
734 eUnderline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
735 goto ATTR_SETUNDERLINE;
737 case RTF_ULD:
738 eUnderline = UNDERLINE_DOTTED;
739 goto ATTR_SETUNDERLINE;
740 case RTF_ULDASH:
741 eUnderline = UNDERLINE_DASH;
742 goto ATTR_SETUNDERLINE;
743 case RTF_ULDASHD:
744 eUnderline = UNDERLINE_DASHDOT;
745 goto ATTR_SETUNDERLINE;
746 case RTF_ULDASHDD:
747 eUnderline = UNDERLINE_DASHDOTDOT;
748 goto ATTR_SETUNDERLINE;
749 case RTF_ULDB:
750 eUnderline = UNDERLINE_DOUBLE;
751 goto ATTR_SETUNDERLINE;
752 case RTF_ULNONE:
753 eUnderline = UNDERLINE_NONE;
754 goto ATTR_SETUNDERLINE;
755 case RTF_ULTH:
756 eUnderline = UNDERLINE_BOLD;
757 goto ATTR_SETUNDERLINE;
758 case RTF_ULWAVE:
759 eUnderline = UNDERLINE_WAVE;
760 goto ATTR_SETUNDERLINE;
761 case RTF_ULTHD:
762 eUnderline = UNDERLINE_BOLDDOTTED;
763 goto ATTR_SETUNDERLINE;
764 case RTF_ULTHDASH:
765 eUnderline = UNDERLINE_BOLDDASH;
766 goto ATTR_SETUNDERLINE;
767 case RTF_ULLDASH:
768 eUnderline = UNDERLINE_LONGDASH;
769 goto ATTR_SETUNDERLINE;
770 case RTF_ULTHLDASH:
771 eUnderline = UNDERLINE_BOLDLONGDASH;
772 goto ATTR_SETUNDERLINE;
773 case RTF_ULTHDASHD:
774 eUnderline = UNDERLINE_BOLDDASHDOT;
775 goto ATTR_SETUNDERLINE;
776 case RTF_ULTHDASHDD:
777 eUnderline = UNDERLINE_BOLDDASHDOTDOT;
778 goto ATTR_SETUNDERLINE;
779 case RTF_ULHWAVE:
780 eUnderline = UNDERLINE_BOLDWAVE;
781 goto ATTR_SETUNDERLINE;
782 case RTF_ULULDBWAVE:
783 eUnderline = UNDERLINE_DOUBLEWAVE;
784 goto ATTR_SETUNDERLINE;
786 case RTF_ULW:
787 eUnderline = UNDERLINE_SINGLE;
789 if( PLAINID->nWordlineMode )
791 pSet->Put( SvxWordLineModeItem( sal_True, PLAINID->nWordlineMode ));
793 goto ATTR_SETUNDERLINE;
795 ATTR_SETUNDERLINE:
796 if( PLAINID->nUnderline )
798 pSet->Put( SvxUnderlineItem( eUnderline, PLAINID->nUnderline ));
800 break;
802 case RTF_ULC:
803 if( PLAINID->nUnderline )
805 SvxUnderlineItem aUL( UNDERLINE_SINGLE, PLAINID->nUnderline );
806 const SfxPoolItem* pItem;
807 if( SFX_ITEM_SET == pSet->GetItemState(
808 PLAINID->nUnderline, sal_False, &pItem ) )
810 // is switched off ?
811 if( UNDERLINE_NONE ==
812 ((SvxUnderlineItem*)pItem)->GetLineStyle() )
813 break;
814 aUL = *(SvxUnderlineItem*)pItem;
816 else
817 aUL = (const SvxUnderlineItem&)pSet->Get( PLAINID->nUnderline, sal_False );
819 if( UNDERLINE_NONE == aUL.GetLineStyle() )
820 aUL.SetLineStyle( UNDERLINE_SINGLE );
821 aUL.SetColor( GetColor( sal_uInt16(nTokenValue) ));
822 pSet->Put( aUL );
824 break;
826 case RTF_OL:
827 if( !IsAttrSttPos() )
828 break;
829 eOverline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
830 goto ATTR_SETOVERLINE;
832 case RTF_OLD:
833 eOverline = UNDERLINE_DOTTED;
834 goto ATTR_SETOVERLINE;
835 case RTF_OLDASH:
836 eOverline = UNDERLINE_DASH;
837 goto ATTR_SETOVERLINE;
838 case RTF_OLDASHD:
839 eOverline = UNDERLINE_DASHDOT;
840 goto ATTR_SETOVERLINE;
841 case RTF_OLDASHDD:
842 eOverline = UNDERLINE_DASHDOTDOT;
843 goto ATTR_SETOVERLINE;
844 case RTF_OLDB:
845 eOverline = UNDERLINE_DOUBLE;
846 goto ATTR_SETOVERLINE;
847 case RTF_OLNONE:
848 eOverline = UNDERLINE_NONE;
849 goto ATTR_SETOVERLINE;
850 case RTF_OLTH:
851 eOverline = UNDERLINE_BOLD;
852 goto ATTR_SETOVERLINE;
853 case RTF_OLWAVE:
854 eOverline = UNDERLINE_WAVE;
855 goto ATTR_SETOVERLINE;
856 case RTF_OLTHD:
857 eOverline = UNDERLINE_BOLDDOTTED;
858 goto ATTR_SETOVERLINE;
859 case RTF_OLTHDASH:
860 eOverline = UNDERLINE_BOLDDASH;
861 goto ATTR_SETOVERLINE;
862 case RTF_OLLDASH:
863 eOverline = UNDERLINE_LONGDASH;
864 goto ATTR_SETOVERLINE;
865 case RTF_OLTHLDASH:
866 eOverline = UNDERLINE_BOLDLONGDASH;
867 goto ATTR_SETOVERLINE;
868 case RTF_OLTHDASHD:
869 eOverline = UNDERLINE_BOLDDASHDOT;
870 goto ATTR_SETOVERLINE;
871 case RTF_OLTHDASHDD:
872 eOverline = UNDERLINE_BOLDDASHDOTDOT;
873 goto ATTR_SETOVERLINE;
874 case RTF_OLHWAVE:
875 eOverline = UNDERLINE_BOLDWAVE;
876 goto ATTR_SETOVERLINE;
877 case RTF_OLOLDBWAVE:
878 eOverline = UNDERLINE_DOUBLEWAVE;
879 goto ATTR_SETOVERLINE;
881 case RTF_OLW:
882 eOverline = UNDERLINE_SINGLE;
884 if( PLAINID->nWordlineMode )
886 pSet->Put( SvxWordLineModeItem( sal_True, PLAINID->nWordlineMode ));
888 goto ATTR_SETOVERLINE;
890 ATTR_SETOVERLINE:
891 if( PLAINID->nUnderline )
893 pSet->Put( SvxOverlineItem( eOverline, PLAINID->nOverline ));
895 break;
897 case RTF_OLC:
898 if( PLAINID->nOverline )
900 SvxOverlineItem aOL( UNDERLINE_SINGLE, PLAINID->nOverline );
901 const SfxPoolItem* pItem;
902 if( SFX_ITEM_SET == pSet->GetItemState(
903 PLAINID->nOverline, sal_False, &pItem ) )
905 // is switched off ?
906 if( UNDERLINE_NONE ==
907 ((SvxOverlineItem*)pItem)->GetLineStyle() )
908 break;
909 aOL = *(SvxOverlineItem*)pItem;
911 else
912 aOL = (const SvxOverlineItem&)pSet->Get( PLAINID->nOverline, sal_False );
914 if( UNDERLINE_NONE == aOL.GetLineStyle() )
915 aOL.SetLineStyle( UNDERLINE_SINGLE );
916 aOL.SetColor( GetColor( sal_uInt16(nTokenValue) ));
917 pSet->Put( aOL );
919 break;
921 case RTF_UP:
922 case RTF_SUPER:
923 if( PLAINID->nEscapement )
925 const sal_uInt16 nEsc = PLAINID->nEscapement;
926 if( -1 == nTokenValue || RTF_SUPER == nToken )
927 nTokenValue = 6;
928 if( IsCalcValue() )
929 CalcValue();
930 const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, sal_False );
931 short nEs;
932 sal_uInt8 nProp;
933 if( DFLT_ESC_AUTO_SUB == rOld.GetEsc() )
935 nEs = DFLT_ESC_AUTO_SUPER;
936 nProp = rOld.GetProp();
938 else
940 nEs = (short)nTokenValue;
941 nProp = (nToken == RTF_SUPER) ? DFLT_ESC_PROP : 100;
943 pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
945 break;
947 case RTF_CF:
948 if( PLAINID->nColor )
950 pSet->Put( SvxColorItem( GetColor( sal_uInt16(nTokenValue) ),
951 PLAINID->nColor ));
953 break;
954 //#i12501# While cb is clearly documented in the rtf spec, word
955 //doesn't accept it at all
956 #if 0
957 case RTF_CB:
958 if( PLAINID->nBgColor )
960 pSet->Put( SvxBrushItem( GetColor( sal_uInt16(nTokenValue) ),
961 PLAINID->nBgColor ));
963 break;
964 #endif
966 case RTF_LANG:
967 if( PLAINID->nLanguage )
969 pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
970 PLAINID->nLanguage ));
972 break;
974 case RTF_LANGFE:
975 if( PLAINID->nCJKLanguage )
977 pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
978 PLAINID->nCJKLanguage ));
980 break;
981 case RTF_ALANG:
983 SvxLanguageItem aTmpItem( (LanguageType)nTokenValue,
984 SID_ATTR_CHAR_LANGUAGE );
985 SetScriptAttr( eCharType, *pSet, aTmpItem );
987 break;
989 case RTF_RTLCH:
990 bIsLeftToRightDef = sal_False;
991 break;
992 case RTF_LTRCH:
993 bIsLeftToRightDef = sal_True;
994 break;
995 case RTF_RTLPAR:
996 if (PARDID->nDirection)
998 pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP,
999 PARDID->nDirection));
1001 break;
1002 case RTF_LTRPAR:
1003 if (PARDID->nDirection)
1005 pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP,
1006 PARDID->nDirection));
1008 break;
1009 case RTF_LOCH: eCharType = LOW_CHARTYPE; break;
1010 case RTF_HICH: eCharType = HIGH_CHARTYPE; break;
1011 case RTF_DBCH: eCharType = DOUBLEBYTE_CHARTYPE; break;
1014 case RTF_ACCNONE:
1015 eEmphasis = EMPHASISMARK_NONE;
1016 goto ATTR_SETEMPHASIS;
1017 case RTF_ACCDOT:
1018 eEmphasis = EMPHASISMARK_DOTS_ABOVE;
1019 goto ATTR_SETEMPHASIS;
1021 case RTF_ACCCOMMA:
1022 eEmphasis = EMPHASISMARK_SIDE_DOTS;
1023 ATTR_SETEMPHASIS:
1024 if( PLAINID->nEmphasis )
1026 pSet->Put( SvxEmphasisMarkItem( eEmphasis,
1027 PLAINID->nEmphasis ));
1029 break;
1031 case RTF_TWOINONE:
1032 if( PLAINID->nTwoLines )
1034 sal_Unicode cStt, cEnd;
1035 switch ( nTokenValue )
1037 case 1: cStt = '(', cEnd = ')'; break;
1038 case 2: cStt = '[', cEnd = ']'; break;
1039 case 3: cStt = '<', cEnd = '>'; break;
1040 case 4: cStt = '{', cEnd = '}'; break;
1041 default: cStt = 0, cEnd = 0; break;
1044 pSet->Put( SvxTwoLinesItem( sal_True, cStt, cEnd,
1045 PLAINID->nTwoLines ));
1047 break;
1049 case RTF_CHARSCALEX :
1050 if (PLAINID->nCharScaleX)
1052 //i21372
1053 if (nTokenValue < 1 || nTokenValue > 600)
1054 nTokenValue = 100;
1055 pSet->Put( SvxCharScaleWidthItem( sal_uInt16(nTokenValue),
1056 PLAINID->nCharScaleX ));
1058 break;
1060 case RTF_HORZVERT:
1061 if( PLAINID->nHorzVert )
1063 // RTF knows only 90deg
1064 pSet->Put( SvxCharRotateItem( 900, 1 == nTokenValue,
1065 PLAINID->nHorzVert ));
1067 break;
1069 case RTF_EMBO:
1070 if (PLAINID->nRelief)
1072 pSet->Put(SvxCharReliefItem(RELIEF_EMBOSSED,
1073 PLAINID->nRelief));
1075 break;
1076 case RTF_IMPR:
1077 if (PLAINID->nRelief)
1079 pSet->Put(SvxCharReliefItem(RELIEF_ENGRAVED,
1080 PLAINID->nRelief));
1082 break;
1083 case RTF_V:
1084 if (PLAINID->nHidden)
1086 pSet->Put(SvxCharHiddenItem(nTokenValue != 0,
1087 PLAINID->nHidden));
1089 break;
1090 case RTF_CHBGFDIAG:
1091 case RTF_CHBGDKVERT:
1092 case RTF_CHBGDKHORIZ:
1093 case RTF_CHBGVERT:
1094 case RTF_CHBGHORIZ:
1095 case RTF_CHBGDKFDIAG:
1096 case RTF_CHBGDCROSS:
1097 case RTF_CHBGCROSS:
1098 case RTF_CHBGBDIAG:
1099 case RTF_CHBGDKDCROSS:
1100 case RTF_CHBGDKCROSS:
1101 case RTF_CHBGDKBDIAG:
1102 case RTF_CHCBPAT:
1103 case RTF_CHCFPAT:
1104 case RTF_CHSHDNG:
1105 if( PLAINID->nBgColor )
1106 ReadBackgroundAttr( nToken, *pSet );
1107 break;
1109 case BRACELEFT:
1111 // tests on Swg internal tokens
1112 bool bHandled = false;
1113 short nSkip = 0;
1114 if( RTF_IGNOREFLAG != GetNextToken())
1115 nSkip = -1;
1116 else if( (nToken = GetNextToken() ) & RTF_SWGDEFS )
1118 bHandled = true;
1119 switch( nToken )
1121 case RTF_PGDSCNO:
1122 case RTF_PGBRK:
1123 case RTF_SOUTLVL:
1124 UnknownAttrToken( nToken, pSet );
1125 // overwrite the closing parenthesis
1126 break;
1128 case RTF_SWG_ESCPROP:
1130 // Store percentage change!
1131 sal_uInt8 nProp = sal_uInt8( nTokenValue / 100 );
1132 short nEsc = 0;
1133 if( 1 == ( nTokenValue % 100 ))
1134 // Recognize own auto-flags!
1135 nEsc = DFLT_ESC_AUTO_SUPER;
1137 if( PLAINID->nEscapement )
1138 pSet->Put( SvxEscapementItem( nEsc, nProp,
1139 PLAINID->nEscapement ));
1141 break;
1143 case RTF_HYPHEN:
1145 SvxHyphenZoneItem aHypenZone(
1146 (nTokenValue & 1) ? sal_True : sal_False,
1147 PARDID->nHyphenzone );
1148 aHypenZone.SetPageEnd(
1149 (nTokenValue & 2) ? sal_True : sal_False );
1151 if( PARDID->nHyphenzone &&
1152 RTF_HYPHLEAD == GetNextToken() &&
1153 RTF_HYPHTRAIL == GetNextToken() &&
1154 RTF_HYPHMAX == GetNextToken() )
1156 aHypenZone.GetMinLead() =
1157 sal_uInt8(GetStackPtr( -2 )->nTokenValue);
1158 aHypenZone.GetMinTrail() =
1159 sal_uInt8(GetStackPtr( -1 )->nTokenValue);
1160 aHypenZone.GetMaxHyphens() =
1161 sal_uInt8(nTokenValue);
1163 pSet->Put( aHypenZone );
1165 else
1166 SkipGroup(); // at the end of the group
1168 break;
1170 case RTF_SHADOW:
1172 int bSkip = sal_True;
1173 do { // middle check loop
1174 SvxShadowLocation eSL = SvxShadowLocation( nTokenValue );
1175 if( RTF_SHDW_DIST != GetNextToken() )
1176 break;
1177 sal_uInt16 nDist = sal_uInt16( nTokenValue );
1179 if( RTF_SHDW_STYLE != GetNextToken() )
1180 break;
1182 if( RTF_SHDW_COL != GetNextToken() )
1183 break;
1184 sal_uInt16 nCol = sal_uInt16( nTokenValue );
1186 if( RTF_SHDW_FCOL != GetNextToken() )
1187 break;
1189 Color aColor = GetColor( nCol );
1191 if( PARDID->nShadow )
1192 pSet->Put( SvxShadowItem( PARDID->nShadow,
1193 &aColor, nDist, eSL ) );
1195 bSkip = sal_False;
1196 } while( false );
1198 if( bSkip )
1199 SkipGroup(); // at the end of the group
1201 break;
1203 default:
1204 bHandled = false;
1205 if( (nToken & ~(0xff | RTF_SWGDEFS)) == RTF_TABSTOPDEF )
1207 nToken = SkipToken( -2 );
1208 ReadTabAttr( nToken, *pSet );
1211 cmc: #i76140, he who consumed the { must consume the }
1212 We rewound to a state of { being the current
1213 token so it is our responsibility to consume the }
1214 token if we consumed the {. We will not have consumed
1215 the { if it belonged to our caller, i.e. if the { we
1216 are handling is the "firsttoken" passed to us then
1217 the *caller* must consume it, not us. Otherwise *we*
1218 should consume it.
1220 if (nToken == BRACELEFT && !bFirstToken)
1222 nToken = GetNextToken();
1223 SAL_WARN_IF( nToken != BRACERIGHT,
1224 "editeng",
1225 "} did not follow { as expected");
1228 else if( (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF)
1230 nToken = SkipToken( -2 );
1231 ReadBorderAttr( nToken, *pSet );
1233 else // so no more attribute
1234 nSkip = -2;
1235 break;
1238 #if 1
1240 cmc: #i4727# / #i12713# Who owns this closing bracket?
1241 If we read the opening one, we must read this one, if
1242 other is counting the brackets so as to push/pop off
1243 the correct environment then we will have pushed a new
1244 environment for the start { of this, but will not see
1245 the } and so is out of sync for the rest of the
1246 document.
1248 if (bHandled && !bFirstToken)
1249 GetNextToken();
1250 #endif
1252 else
1253 nSkip = -2;
1255 if( nSkip ) // all completely unknown
1257 if (!bFirstToken)
1258 --nSkip; // BRACELEFT: is the next token
1259 SkipToken( nSkip );
1260 bWeiter = sal_False;
1263 break;
1264 default:
1265 if( (nToken & ~0xff ) == RTF_TABSTOPDEF )
1266 ReadTabAttr( nToken, *pSet );
1267 else if( (nToken & ~0xff ) == RTF_BRDRDEF )
1268 ReadBorderAttr( nToken, *pSet );
1269 else if( (nToken & ~0xff ) == RTF_SHADINGDEF )
1270 ReadBackgroundAttr( nToken, *pSet );
1271 else
1273 // unknown token, so token "returned in Parser"
1274 if( !bFirstToken )
1275 SkipToken( -1 );
1276 bWeiter = sal_False;
1280 if( bWeiter )
1282 nToken = GetNextToken();
1284 bFirstToken = sal_False;
1288 void SvxRTFParser::ReadTabAttr( int nToken, SfxItemSet& rSet )
1290 bool bMethodOwnsToken = false; // #i52542# patch from cmc.
1291 // then read all the TabStops
1292 SvxTabStop aTabStop;
1293 SvxTabStopItem aAttr( 0, 0, SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
1294 int bWeiter = sal_True;
1295 do {
1296 switch( nToken )
1298 case RTF_TB: // BarTab ???
1299 case RTF_TX:
1301 if( IsCalcValue() )
1302 CalcValue();
1303 aTabStop.GetTabPos() = nTokenValue;
1304 aAttr.Insert( aTabStop );
1305 aTabStop = SvxTabStop(); // all values default
1307 break;
1309 case RTF_TQL:
1310 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
1311 break;
1312 case RTF_TQR:
1313 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
1314 break;
1315 case RTF_TQC:
1316 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
1317 break;
1318 case RTF_TQDEC:
1319 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL;
1320 break;
1322 case RTF_TLDOT: aTabStop.GetFill() = '.'; break;
1323 case RTF_TLHYPH: aTabStop.GetFill() = ' '; break;
1324 case RTF_TLUL: aTabStop.GetFill() = '_'; break;
1325 case RTF_TLTH: aTabStop.GetFill() = '-'; break;
1326 case RTF_TLEQ: aTabStop.GetFill() = '='; break;
1328 case BRACELEFT:
1330 // Swg - control BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1331 short nSkip = 0;
1332 if( RTF_IGNOREFLAG != GetNextToken() )
1333 nSkip = -1;
1334 else if( RTF_TLSWG != ( nToken = GetNextToken() ))
1335 nSkip = -2;
1336 else
1338 aTabStop.GetDecimal() = sal_uInt8(nTokenValue & 0xff);
1339 aTabStop.GetFill() = sal_uInt8((nTokenValue >> 8) & 0xff);
1340 // overwrite the closing parenthesis
1341 if (bMethodOwnsToken)
1342 GetNextToken();
1344 if( nSkip )
1346 SkipToken( nSkip ); // Ignore back again
1347 bWeiter = sal_False;
1350 break;
1352 default:
1353 bWeiter = sal_False;
1355 if( bWeiter )
1357 nToken = GetNextToken();
1358 bMethodOwnsToken = true;
1360 } while( bWeiter );
1362 // Fill with defaults is still missing!
1363 rSet.Put( aAttr );
1364 SkipToken( -1 );
1367 static void SetBorderLine( int nBorderTyp, SvxBoxItem& rItem,
1368 const SvxBorderLine& rBorder )
1370 switch( nBorderTyp )
1372 case RTF_BOX: // run through all levels
1374 case RTF_BRDRT:
1375 rItem.SetLine( &rBorder, BOX_LINE_TOP );
1376 if( RTF_BOX != nBorderTyp )
1377 return;
1379 case RTF_BRDRB:
1380 rItem.SetLine( &rBorder, BOX_LINE_BOTTOM );
1381 if( RTF_BOX != nBorderTyp )
1382 return;
1384 case RTF_BRDRL:
1385 rItem.SetLine( &rBorder, BOX_LINE_LEFT );
1386 if( RTF_BOX != nBorderTyp )
1387 return;
1389 case RTF_BRDRR:
1390 rItem.SetLine( &rBorder, BOX_LINE_RIGHT );
1391 if( RTF_BOX != nBorderTyp )
1392 return;
1396 void SvxRTFParser::ReadBorderAttr( int nToken, SfxItemSet& rSet,
1397 int bTableDef )
1399 // then read the border attribute
1400 SvxBoxItem aAttr( PARDID->nBox );
1401 const SfxPoolItem* pItem;
1402 if( SFX_ITEM_SET == rSet.GetItemState( PARDID->nBox, sal_False, &pItem ) )
1403 aAttr = *(SvxBoxItem*)pItem;
1405 SvxBorderLine aBrd( 0, DEF_LINE_WIDTH_0 ); // Simple plain line
1406 int bWeiter = sal_True, nBorderTyp = 0;
1408 long nWidth = 1;
1409 bool bDoubleWidth = false;
1411 do {
1412 switch( nToken )
1414 case RTF_BOX:
1415 case RTF_BRDRT:
1416 case RTF_BRDRB:
1417 case RTF_BRDRL:
1418 case RTF_BRDRR:
1419 nBorderTyp = nToken;
1420 break;
1422 case RTF_CLBRDRT: // Cell top border
1424 if( bTableDef )
1426 if (nBorderTyp != 0)
1427 SetBorderLine( nBorderTyp, aAttr, aBrd );
1428 nBorderTyp = RTF_BRDRT;
1430 break;
1432 case RTF_CLBRDRB: // Cell bottom border
1434 if( bTableDef )
1436 if (nBorderTyp != 0)
1437 SetBorderLine( nBorderTyp, aAttr, aBrd );
1438 nBorderTyp = RTF_BRDRB;
1440 break;
1442 case RTF_CLBRDRL: // Cell left border
1444 if( bTableDef )
1446 if (nBorderTyp != 0)
1447 SetBorderLine( nBorderTyp, aAttr, aBrd );
1448 nBorderTyp = RTF_BRDRL;
1450 break;
1452 case RTF_CLBRDRR: // Cell right border
1454 if( bTableDef )
1456 if (nBorderTyp != 0)
1457 SetBorderLine( nBorderTyp, aAttr, aBrd );
1458 nBorderTyp = RTF_BRDRR;
1460 break;
1463 case RTF_BRDRDOT: // dotted border
1464 aBrd.SetBorderLineStyle(table::BorderLineStyle::DOTTED);
1465 break;
1466 case RTF_BRDRDASH: // dashed border
1467 aBrd.SetBorderLineStyle(table::BorderLineStyle::DASHED);
1468 break;
1469 case RTF_BRDRHAIR: // hairline border
1471 aBrd.SetBorderLineStyle( table::BorderLineStyle::SOLID);
1472 aBrd.SetWidth( DEF_LINE_WIDTH_0 );
1474 break;
1475 case RTF_BRDRDB: // Double border
1476 aBrd.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
1477 break;
1478 case RTF_BRDRINSET: // inset border
1479 aBrd.SetBorderLineStyle(table::BorderLineStyle::INSET);
1480 break;
1481 case RTF_BRDROUTSET: // outset border
1482 aBrd.SetBorderLineStyle(table::BorderLineStyle::OUTSET);
1483 break;
1484 case RTF_BRDRTNTHSG: // ThinThick Small gap
1485 aBrd.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_SMALLGAP);
1486 break;
1487 case RTF_BRDRTNTHMG: // ThinThick Medium gap
1488 aBrd.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_MEDIUMGAP);
1489 break;
1490 case RTF_BRDRTNTHLG: // ThinThick Large gap
1491 aBrd.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_LARGEGAP);
1492 break;
1493 case RTF_BRDRTHTNSG: // ThickThin Small gap
1494 aBrd.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_SMALLGAP);
1495 break;
1496 case RTF_BRDRTHTNMG: // ThickThin Medium gap
1497 aBrd.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_MEDIUMGAP);
1498 break;
1499 case RTF_BRDRTHTNLG: // ThickThin Large gap
1500 aBrd.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_LARGEGAP);
1501 break;
1502 case RTF_BRDREMBOSS: // Embossed border
1503 aBrd.SetBorderLineStyle(table::BorderLineStyle::EMBOSSED);
1504 break;
1505 case RTF_BRDRENGRAVE: // Engraved border
1506 aBrd.SetBorderLineStyle(table::BorderLineStyle::ENGRAVED);
1507 break;
1509 case RTF_BRDRS: // single thickness border
1510 bDoubleWidth = false;
1511 break;
1512 case RTF_BRDRTH: // double thickness border width*2
1513 bDoubleWidth = true;
1514 break;
1515 case RTF_BRDRW: // border width <255
1516 nWidth = nTokenValue;
1517 break;
1519 case RTF_BRDRCF: // Border color
1520 aBrd.SetColor( GetColor( sal_uInt16(nTokenValue) ) );
1521 break;
1523 case RTF_BRDRSH: // Shadowed border
1524 rSet.Put( SvxShadowItem( PARDID->nShadow, (Color*) 0, 60 /*3pt*/,
1525 SVX_SHADOW_BOTTOMRIGHT ) );
1526 break;
1528 case RTF_BRSP: // Spacing to content in twip
1530 switch( nBorderTyp )
1532 case RTF_BRDRB:
1533 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_BOTTOM );
1534 break;
1536 case RTF_BRDRT:
1537 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_TOP );
1538 break;
1540 case RTF_BRDRL:
1541 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_LEFT );
1542 break;
1544 case RTF_BRDRR:
1545 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_RIGHT );
1546 break;
1548 case RTF_BOX:
1549 aAttr.SetDistance( (sal_uInt16)nTokenValue );
1550 break;
1553 break;
1555 case RTF_BRDRBTW: // Border formatting group
1556 case RTF_BRDRBAR: // Border outside
1557 // TODO unhandled ATM
1558 break;
1560 default:
1561 bWeiter = (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF;
1563 if( bWeiter )
1564 nToken = GetNextToken();
1565 } while( bWeiter );
1567 // Finally compute the border width
1568 if ( bDoubleWidth ) nWidth *= 2;
1569 aBrd.SetWidth( nWidth );
1571 SetBorderLine( nBorderTyp, aAttr, aBrd );
1573 rSet.Put( aAttr );
1574 SkipToken( -1 );
1577 inline sal_uInt32 CalcShading( sal_uInt32 nColor, sal_uInt32 nFillColor, sal_uInt8 nShading )
1579 nColor = (nColor * nShading) / 100;
1580 nFillColor = (nFillColor * ( 100 - nShading )) / 100;
1581 return nColor + nFillColor;
1584 void SvxRTFParser::ReadBackgroundAttr( int nToken, SfxItemSet& rSet,
1585 int bTableDef )
1587 // then read the border attribute
1588 int bWeiter = sal_True;
1589 sal_uInt16 nColor = USHRT_MAX, nFillColor = USHRT_MAX;
1590 sal_uInt8 nFillValue = 0;
1592 sal_uInt16 nWh = ( nToken & ~0xff ) == RTF_CHRFMT
1593 ? PLAINID->nBgColor
1594 : PARDID->nBrush;
1596 do {
1597 switch( nToken )
1599 case RTF_CLCBPAT:
1600 case RTF_CHCBPAT:
1601 case RTF_CBPAT:
1602 nFillColor = sal_uInt16( nTokenValue );
1603 break;
1605 case RTF_CLCFPAT:
1606 case RTF_CHCFPAT:
1607 case RTF_CFPAT:
1608 nColor = sal_uInt16( nTokenValue );
1609 break;
1611 case RTF_CLSHDNG:
1612 case RTF_CHSHDNG:
1613 case RTF_SHADING:
1614 nFillValue = (sal_uInt8)( nTokenValue / 100 );
1615 break;
1617 case RTF_CLBGDKHOR:
1618 case RTF_CHBGDKHORIZ:
1619 case RTF_BGDKHORIZ:
1620 case RTF_CLBGDKVERT:
1621 case RTF_CHBGDKVERT:
1622 case RTF_BGDKVERT:
1623 case RTF_CLBGDKBDIAG:
1624 case RTF_CHBGDKBDIAG:
1625 case RTF_BGDKBDIAG:
1626 case RTF_CLBGDKFDIAG:
1627 case RTF_CHBGDKFDIAG:
1628 case RTF_BGDKFDIAG:
1629 case RTF_CLBGDKCROSS:
1630 case RTF_CHBGDKCROSS:
1631 case RTF_BGDKCROSS:
1632 case RTF_CLBGDKDCROSS:
1633 case RTF_CHBGDKDCROSS:
1634 case RTF_BGDKDCROSS:
1635 // dark -> 60%
1636 nFillValue = 60;
1637 break;
1639 case RTF_CLBGHORIZ:
1640 case RTF_CHBGHORIZ:
1641 case RTF_BGHORIZ:
1642 case RTF_CLBGVERT:
1643 case RTF_CHBGVERT:
1644 case RTF_BGVERT:
1645 case RTF_CLBGBDIAG:
1646 case RTF_CHBGBDIAG:
1647 case RTF_BGBDIAG:
1648 case RTF_CLBGFDIAG:
1649 case RTF_CHBGFDIAG:
1650 case RTF_BGFDIAG:
1651 case RTF_CLBGCROSS:
1652 case RTF_CHBGCROSS:
1653 case RTF_BGCROSS:
1654 case RTF_CLBGDCROSS:
1655 case RTF_CHBGDCROSS:
1656 case RTF_BGDCROSS:
1657 // light -> 20%
1658 nFillValue = 20;
1659 break;
1661 default:
1662 if( bTableDef )
1663 bWeiter = (nToken & ~(0xff | RTF_TABLEDEF) ) == RTF_SHADINGDEF;
1664 else
1665 bWeiter = (nToken & ~0xff) == RTF_SHADINGDEF;
1667 if( bWeiter )
1668 nToken = GetNextToken();
1669 } while( bWeiter );
1671 Color aCol( COL_WHITE ), aFCol;
1672 if( !nFillValue )
1674 // there was only one of two colors specified or no BrushTyp
1675 if( USHRT_MAX != nFillColor )
1677 nFillValue = 100;
1678 aCol = GetColor( nFillColor );
1680 else if( USHRT_MAX != nColor )
1681 aFCol = GetColor( nColor );
1683 else
1685 if( USHRT_MAX != nColor )
1686 aCol = GetColor( nColor );
1687 else
1688 aCol = Color( COL_BLACK );
1690 if( USHRT_MAX != nFillColor )
1691 aFCol = GetColor( nFillColor );
1692 else
1693 aFCol = Color( COL_WHITE );
1696 Color aColor;
1697 if( 0 == nFillValue || 100 == nFillValue )
1698 aColor = aCol;
1699 else
1700 aColor = Color(
1701 (sal_uInt8)CalcShading( aCol.GetRed(), aFCol.GetRed(), nFillValue ),
1702 (sal_uInt8)CalcShading( aCol.GetGreen(), aFCol.GetGreen(), nFillValue ),
1703 (sal_uInt8)CalcShading( aCol.GetBlue(), aFCol.GetBlue(), nFillValue ) );
1705 rSet.Put( SvxBrushItem( aColor, nWh ) );
1706 SkipToken( -1 );
1710 // pard / plain abarbeiten
1711 void SvxRTFParser::RTFPardPlain( int bPard, SfxItemSet** ppSet )
1713 if( !bNewGroup && !aAttrStack.empty() ) // not at the beginning of a new group
1715 SvxRTFItemStackType* pAkt = aAttrStack.back();
1717 int nLastToken = GetStackPtr(-1)->nTokenId;
1718 int bNewStkEntry = sal_True;
1719 if( RTF_PARD != nLastToken &&
1720 RTF_PLAIN != nLastToken &&
1721 BRACELEFT != nLastToken )
1723 if( pAkt->aAttrSet.Count() || pAkt->pChildList || pAkt->nStyleNo )
1725 // open a new group
1726 SvxRTFItemStackType* pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, sal_True );
1727 pNew->SetRTFDefaults( GetRTFDefaults() );
1729 // Set all until here valid attributes
1730 AttrGroupEnd();
1731 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd!
1732 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1733 aAttrStack.push_back( pNew );
1734 pAkt = pNew;
1736 else
1738 // continue to use this entry as new
1739 pAkt->SetStartPos( *pInsPos );
1740 bNewStkEntry = sal_False;
1744 // now reset all to default
1745 if( bNewStkEntry &&
1746 ( pAkt->aAttrSet.GetParent() || pAkt->aAttrSet.Count() ))
1748 const SfxPoolItem *pItem, *pDef;
1749 const sal_uInt16* pPtr;
1750 sal_uInt16 nCnt;
1751 const SfxItemSet* pDfltSet = &GetRTFDefaults();
1752 if( bPard )
1754 pAkt->nStyleNo = 0;
1755 pPtr = &aPardMap[0];
1756 nCnt = aPardMap.size();
1758 else
1760 pPtr = &aPlainMap[0];
1761 nCnt = aPlainMap.size();
1764 for( sal_uInt16 n = 0; n < nCnt; ++n, ++pPtr )
1766 // Item set and different -> Set the Default Pool
1767 if( !*pPtr )
1769 else if( SFX_WHICH_MAX < *pPtr )
1770 pAkt->aAttrSet.ClearItem( *pPtr );
1771 else if( IsChkStyleAttr() )
1772 pAkt->aAttrSet.Put( pDfltSet->Get( *pPtr ) );
1773 else if( !pAkt->aAttrSet.GetParent() )
1775 if( SFX_ITEM_SET ==
1776 pDfltSet->GetItemState( *pPtr, sal_False, &pDef ))
1777 pAkt->aAttrSet.Put( *pDef );
1778 else
1779 pAkt->aAttrSet.ClearItem( *pPtr );
1781 else if( SFX_ITEM_SET == pAkt->aAttrSet.GetParent()->
1782 GetItemState( *pPtr, sal_True, &pItem ) &&
1783 *( pDef = &pDfltSet->Get( *pPtr )) != *pItem )
1784 pAkt->aAttrSet.Put( *pDef );
1785 else
1787 if( SFX_ITEM_SET ==
1788 pDfltSet->GetItemState( *pPtr, sal_False, &pDef ))
1789 pAkt->aAttrSet.Put( *pDef );
1790 else
1791 pAkt->aAttrSet.ClearItem( *pPtr );
1795 else if( bPard )
1796 pAkt->nStyleNo = 0; // reset Style number
1798 *ppSet = &pAkt->aAttrSet;
1800 if (!bPard)
1802 //Once we have a default font, then any text without a font specifier is
1803 //in the default font, and thus has the default font charset, otherwise
1804 //we can fall back to the ansicpg set codeset
1805 if (nDfltFont != -1)
1807 const Font& rSVFont = GetFont(sal_uInt16(nDfltFont));
1808 SetEncoding(rSVFont.GetCharSet());
1810 else
1811 SetEncoding(GetCodeSet());
1816 void SvxRTFParser::SetDefault( int nToken, int nValue )
1818 if( !bNewDoc )
1819 return;
1821 SfxItemSet aTmp( *pAttrPool, &aWhichMap[0] );
1822 sal_Bool bOldFlag = bIsLeftToRightDef;
1823 bIsLeftToRightDef = sal_True;
1824 switch( nToken )
1826 case RTF_ADEFF: bIsLeftToRightDef = sal_False; // no break!
1827 case RTF_DEFF:
1829 if( -1 == nValue )
1830 nValue = 0;
1831 const Font& rSVFont = GetFont( sal_uInt16(nValue) );
1832 SvxFontItem aTmpItem(
1833 rSVFont.GetFamily(), rSVFont.GetName(),
1834 rSVFont.GetStyleName(), rSVFont.GetPitch(),
1835 rSVFont.GetCharSet(), SID_ATTR_CHAR_FONT );
1836 SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
1838 break;
1840 case RTF_ADEFLANG: bIsLeftToRightDef = sal_False; // no break!
1841 case RTF_DEFLANG:
1842 // store default Language
1843 if( -1 != nValue )
1845 SvxLanguageItem aTmpItem( (const LanguageType)nValue,
1846 SID_ATTR_CHAR_LANGUAGE );
1847 SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
1849 break;
1851 case RTF_DEFTAB:
1852 if( PARDID->nTabStop )
1854 // RTF defines 720 twips as default
1855 bIsSetDfltTab = sal_True;
1856 if( -1 == nValue || !nValue )
1857 nValue = 720;
1859 // who would like to have no twips ...
1860 if( IsCalcValue() )
1862 nTokenValue = nValue;
1863 CalcValue();
1864 nValue = nTokenValue;
1867 // Calculate the ratio of default TabWidth / Tabs and
1868 // calculate the corresponding new number.
1869 // ?? how did one come up with 13 ??
1870 sal_uInt16 nAnzTabs = (SVX_TAB_DEFDIST * 13 ) / sal_uInt16(nValue);
1872 cmc, make sure we have at least one, or all hell breaks loose in
1873 everybodies exporters, #i8247#
1875 if (nAnzTabs < 1)
1876 nAnzTabs = 1;
1878 // we want Defaulttabs
1879 SvxTabStopItem aNewTab( nAnzTabs, sal_uInt16(nValue),
1880 SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
1881 while( nAnzTabs )
1882 ((SvxTabStop&)aNewTab[ --nAnzTabs ]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
1884 pAttrPool->SetPoolDefaultItem( aNewTab );
1886 break;
1888 bIsLeftToRightDef = bOldFlag;
1890 if( aTmp.Count() )
1892 SfxItemIter aIter( aTmp );
1893 const SfxPoolItem* pItem = aIter.GetCurItem();
1894 while( true )
1896 pAttrPool->SetPoolDefaultItem( *pItem );
1897 if( aIter.IsAtEnd() )
1898 break;
1899 pItem = aIter.NextItem();
1904 // default: no conversion, leaving everything in twips.
1905 void SvxRTFParser::CalcValue()
1909 // for tokens that are not evaluated in ReadAttr
1910 void SvxRTFParser::UnknownAttrToken( int, SfxItemSet* )
1914 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */