Bump for 3.6-28
[LibreOffice.git] / editeng / source / rtf / rtfitem.cxx
blobf99bfb59f447257284724aebb23eb73ef6f1b562
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <editeng/flstitem.hxx>
31 #include <editeng/fontitem.hxx>
32 #include <editeng/postitem.hxx>
33 #include <editeng/wghtitem.hxx>
34 #include <editeng/fhgtitem.hxx>
35 #include <editeng/fwdtitem.hxx>
36 #include <editeng/udlnitem.hxx>
37 #include <editeng/crsditem.hxx>
38 #include <editeng/shdditem.hxx>
39 #include <editeng/akrnitem.hxx>
40 #include <editeng/wrlmitem.hxx>
41 #include <editeng/cntritem.hxx>
42 #include <editeng/prszitem.hxx>
43 #include <editeng/colritem.hxx>
44 #include <editeng/cscoitem.hxx>
45 #include <editeng/kernitem.hxx>
46 #include <editeng/cmapitem.hxx>
47 #include <editeng/escpitem.hxx>
48 #include <editeng/langitem.hxx>
49 #include <editeng/nlbkitem.hxx>
50 #include <editeng/nhypitem.hxx>
51 #include <editeng/lcolitem.hxx>
52 #include <editeng/blnkitem.hxx>
53 #include <editeng/emphitem.hxx>
54 #include <editeng/twolinesitem.hxx>
55 #include <editeng/pbinitem.hxx>
56 #include <editeng/sizeitem.hxx>
57 #include <editeng/lrspitem.hxx>
58 #include <editeng/ulspitem.hxx>
59 #include <editeng/prntitem.hxx>
60 #include <editeng/opaqitem.hxx>
61 #include <editeng/protitem.hxx>
62 #include <editeng/shaditem.hxx>
63 #include <editeng/boxitem.hxx>
64 #include <editeng/brkitem.hxx>
65 #include <editeng/keepitem.hxx>
66 #include <editeng/bolnitem.hxx>
67 #include <editeng/brshitem.hxx>
68 #include <editeng/lspcitem.hxx>
69 #include <editeng/adjitem.hxx>
70 #include <editeng/orphitem.hxx>
71 #include <editeng/widwitem.hxx>
72 #include <editeng/tstpitem.hxx>
73 #include <editeng/pmdlitem.hxx>
74 #include <editeng/spltitem.hxx>
75 #include <editeng/hyznitem.hxx>
76 #include <editeng/charscaleitem.hxx>
77 #include <editeng/charrotateitem.hxx>
78 #include <editeng/charreliefitem.hxx>
79 #include <editeng/paravertalignitem.hxx>
80 #include <editeng/forbiddenruleitem.hxx>
81 #include <editeng/hngpnctitem.hxx>
82 #include <editeng/scriptspaceitem.hxx>
83 #include <editeng/frmdiritem.hxx>
84 #include <editeng/charhiddenitem.hxx>
86 #include <svtools/rtftoken.h>
87 #include <svl/itempool.hxx>
88 #include <svl/itemiter.hxx>
90 #include <editeng/svxrtf.hxx>
91 #include <editeng/editids.hrc>
93 #define BRACELEFT '{'
94 #define BRACERIGHT '}'
96 using namespace ::com::sun::star;
97 using namespace editeng;
99 // Some helper functions
100 // char
101 inline const SvxEscapementItem& GetEscapement(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
102 { return (const SvxEscapementItem&)rSet.Get( nId,bInP); }
103 inline const SvxLineSpacingItem& GetLineSpacing(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
104 { return (const SvxLineSpacingItem&)rSet.Get( nId,bInP); }
105 // frm
106 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
107 { return (const SvxLRSpaceItem&)rSet.Get( nId,bInP); }
108 inline const SvxULSpaceItem& GetULSpace(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
109 { return (const SvxULSpaceItem&)rSet.Get( nId,bInP); }
111 #define PARDID ((RTFPardAttrMapIds*)&aPardMap[0])
112 #define PLAINID ((RTFPlainAttrMapIds*)&aPlainMap[0])
114 void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType, SfxItemSet& rSet,
115 SfxPoolItem& rItem )
117 const sal_uInt16 *pNormal = 0, *pCJK = 0, *pCTL = 0;
118 const RTFPlainAttrMapIds* pIds = (RTFPlainAttrMapIds*)&aPlainMap[0];
119 switch( rItem.Which() )
121 case SID_ATTR_CHAR_FONT:
122 pNormal = &pIds->nFont;
123 pCJK = &pIds->nCJKFont;
124 pCTL = &pIds->nCTLFont;
125 break;
127 case SID_ATTR_CHAR_FONTHEIGHT:
128 pNormal = &pIds->nFontHeight;
129 pCJK = &pIds->nCJKFontHeight;
130 pCTL = &pIds->nCTLFontHeight;
131 break;
133 case SID_ATTR_CHAR_POSTURE:
134 pNormal = &pIds->nPosture;
135 pCJK = &pIds->nCJKPosture;
136 pCTL = &pIds->nCTLPosture;
137 break;
139 case SID_ATTR_CHAR_WEIGHT:
140 pNormal = &pIds->nWeight;
141 pCJK = &pIds->nCJKWeight;
142 pCTL = &pIds->nCTLWeight;
143 break;
145 case SID_ATTR_CHAR_LANGUAGE:
146 pNormal = &pIds->nLanguage;
147 pCJK = &pIds->nCJKLanguage;
148 pCTL = &pIds->nCTLLanguage;
149 break;
151 case 0:
152 // it exist no WhichId - don't set this item
153 break;
155 default:
156 rSet.Put( rItem );
157 break;
161 if( DOUBLEBYTE_CHARTYPE == eType )
163 if( bIsLeftToRightDef && *pCJK )
165 rItem.SetWhich( *pCJK );
166 rSet.Put( rItem );
169 else if( !bIsLeftToRightDef )
171 if( *pCTL )
173 rItem.SetWhich( *pCTL );
174 rSet.Put( rItem );
177 else
179 if( LOW_CHARTYPE == eType )
181 if( *pNormal )
183 rItem.SetWhich( *pNormal );
184 rSet.Put( rItem );
187 else if( HIGH_CHARTYPE == eType )
189 if( *pCTL )
191 rItem.SetWhich( *pCTL );
192 rSet.Put( rItem );
195 else
197 if( *pCJK )
199 rItem.SetWhich( *pCJK );
200 rSet.Put( rItem );
202 if( *pCTL )
204 rItem.SetWhich( *pCTL );
205 rSet.Put( rItem );
207 if( *pNormal )
209 rItem.SetWhich( *pNormal );
210 rSet.Put( rItem );
216 // --------------------
218 void SvxRTFParser::ReadAttr( int nToken, SfxItemSet* pSet )
220 DBG_ASSERT( pSet, "A SfxItemSet has to be provided as argument!" );
221 int bFirstToken = sal_True, bWeiter = sal_True;
222 sal_uInt16 nStyleNo = 0; // default
223 FontUnderline eUnderline;
224 FontUnderline eOverline;
225 FontEmphasisMark eEmphasis;
226 bPardTokenRead = sal_False;
227 RTF_CharTypeDef eCharType = NOTDEF_CHARTYPE;
228 sal_uInt16 nFontAlign;
230 int bChkStkPos = !bNewGroup && !aAttrStack.empty();
232 while( bWeiter && IsParserWorking() ) // as long as known Attribute are recognized
234 switch( nToken )
236 case RTF_PARD:
237 RTFPardPlain( sal_True, &pSet );
238 ResetPard();
239 nStyleNo = 0;
240 bPardTokenRead = sal_True;
241 break;
243 case RTF_PLAIN:
244 RTFPardPlain( sal_False, &pSet );
245 break;
247 default:
248 do { // middle checked loop
249 if( !bChkStkPos )
250 break;
252 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
253 if( !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
254 pAkt->nSttCnt == pInsPos->GetCntIdx() ))
255 break;
257 int nLastToken = GetStackPtr(-1)->nTokenId;
258 if( RTF_PARD == nLastToken || RTF_PLAIN == nLastToken )
259 break;
261 if( pAkt->aAttrSet.Count() || pAkt->pChildList ||
262 pAkt->nStyleNo )
264 // Open a new Group
265 SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
266 *pAkt, *pInsPos, sal_True );
267 pNew->SetRTFDefaults( GetRTFDefaults() );
269 // "Set" all valid attributes up until this point
270 AttrGroupEnd();
271 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd!
272 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
274 aAttrStack.push_back( pNew );
275 pAkt = pNew;
277 else
278 // continue to use this entry as a new one
279 pAkt->SetStartPos( *pInsPos );
281 pSet = &pAkt->aAttrSet;
282 } while( sal_False );
284 switch( nToken )
286 case RTF_INTBL:
287 case RTF_PAGEBB:
288 case RTF_SBYS:
289 case RTF_CS:
290 case RTF_LS:
291 case RTF_ILVL:
292 UnknownAttrToken( nToken, pSet );
293 break;
295 case RTF_S:
296 if( bIsInReadStyleTab )
298 if( !bFirstToken )
299 SkipToken( -1 );
300 bWeiter = sal_False;
302 else
304 nStyleNo = -1 == nTokenValue ? 0 : sal_uInt16(nTokenValue);
305 // setze am akt. auf dem AttrStack stehenden Style die
306 // StyleNummer
307 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
308 if( !pAkt )
309 break;
311 pAkt->nStyleNo = sal_uInt16( nStyleNo );
314 break;
316 case RTF_KEEP:
317 if( PARDID->nSplit )
319 pSet->Put( SvxFmtSplitItem( sal_False, PARDID->nSplit ));
321 break;
323 case RTF_KEEPN:
324 if( PARDID->nKeep )
326 pSet->Put( SvxFmtKeepItem( sal_True, PARDID->nKeep ));
328 break;
330 case RTF_LEVEL:
331 if( PARDID->nOutlineLvl )
333 pSet->Put( SfxUInt16Item( PARDID->nOutlineLvl,
334 (sal_uInt16)nTokenValue ));
336 break;
338 case RTF_QL:
339 if( PARDID->nAdjust )
341 pSet->Put( SvxAdjustItem( SVX_ADJUST_LEFT, PARDID->nAdjust ));
343 break;
344 case RTF_QR:
345 if( PARDID->nAdjust )
347 pSet->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, PARDID->nAdjust ));
349 break;
350 case RTF_QJ:
351 if( PARDID->nAdjust )
353 pSet->Put( SvxAdjustItem( SVX_ADJUST_BLOCK, PARDID->nAdjust ));
355 break;
356 case RTF_QC:
357 if( PARDID->nAdjust )
359 pSet->Put( SvxAdjustItem( SVX_ADJUST_CENTER, PARDID->nAdjust ));
361 break;
363 case RTF_FI:
364 if( PARDID->nLRSpace )
366 SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
367 sal_uInt16 nSz = 0;
368 if( -1 != nTokenValue )
370 if( IsCalcValue() )
371 CalcValue();
372 nSz = sal_uInt16(nTokenValue);
374 aLR.SetTxtFirstLineOfst( nSz );
375 pSet->Put( aLR );
377 break;
379 case RTF_LI:
380 case RTF_LIN:
381 if( PARDID->nLRSpace )
383 SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
384 sal_uInt16 nSz = 0;
385 if( 0 < nTokenValue )
387 if( IsCalcValue() )
388 CalcValue();
389 nSz = sal_uInt16(nTokenValue);
391 aLR.SetTxtLeft( nSz );
392 pSet->Put( aLR );
394 break;
396 case RTF_RI:
397 case RTF_RIN:
398 if( PARDID->nLRSpace )
400 SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
401 sal_uInt16 nSz = 0;
402 if( 0 < nTokenValue )
404 if( IsCalcValue() )
405 CalcValue();
406 nSz = sal_uInt16(nTokenValue);
408 aLR.SetRight( nSz );
409 pSet->Put( aLR );
411 break;
413 case RTF_SB:
414 if( PARDID->nULSpace )
416 SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
417 sal_uInt16 nSz = 0;
418 if( 0 < nTokenValue )
420 if( IsCalcValue() )
421 CalcValue();
422 nSz = sal_uInt16(nTokenValue);
424 aUL.SetUpper( nSz );
425 pSet->Put( aUL );
427 break;
429 case RTF_SA:
430 if( PARDID->nULSpace )
432 SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
433 sal_uInt16 nSz = 0;
434 if( 0 < nTokenValue )
436 if( IsCalcValue() )
437 CalcValue();
438 nSz = sal_uInt16(nTokenValue);
440 aUL.SetLower( nSz );
441 pSet->Put( aUL );
443 break;
445 case RTF_SLMULT:
446 if( PARDID->nLinespacing && 1 == nTokenValue )
448 // then switches to multi-line!
449 SvxLineSpacingItem aLSpace( GetLineSpacing( *pSet,
450 PARDID->nLinespacing, sal_False ));
452 // how much do you get from the line height value?
454 // Proportional-Size:
455 // Ie, the ratio is (n / 240) twips
457 nTokenValue = 240;
458 if( IsCalcValue() )
459 CalcValue();
461 nTokenValue = short( 100L * aLSpace.GetLineHeight()
462 / long( nTokenValue ) );
464 if( nTokenValue > 200 ) // Data value for PropLnSp
465 nTokenValue = 200; // is one BYTE !!!
467 aLSpace.SetPropLineSpace( (const sal_uInt8)nTokenValue );
468 aLSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
470 pSet->Put( aLSpace );
472 break;
474 case RTF_SL:
475 if( PARDID->nLinespacing )
477 // Calculate the ratio between the default font and the
478 // specified size. The distance consists of the line height
479 // (100%) and the space above the line (20%).
480 SvxLineSpacingItem aLSpace(0, PARDID->nLinespacing);
482 nTokenValue = !bTokenHasValue ? 0 : nTokenValue;
483 if (1000 == nTokenValue )
484 nTokenValue = 240;
486 SvxLineSpace eLnSpc;
487 if (nTokenValue < 0)
489 eLnSpc = SVX_LINE_SPACE_FIX;
490 nTokenValue = -nTokenValue;
492 else if (nTokenValue == 0)
494 //if \sl0 is used, the line spacing is automatically
495 //determined
496 eLnSpc = SVX_LINE_SPACE_AUTO;
498 else
499 eLnSpc = SVX_LINE_SPACE_MIN;
501 if (IsCalcValue())
502 CalcValue();
504 if (eLnSpc != SVX_LINE_SPACE_AUTO)
505 aLSpace.SetLineHeight( (const sal_uInt16)nTokenValue );
507 aLSpace.GetLineSpaceRule() = eLnSpc;
508 pSet->Put(aLSpace);
510 break;
512 case RTF_NOCWRAP:
513 if( PARDID->nForbRule )
515 pSet->Put( SvxForbiddenRuleItem( sal_False,
516 PARDID->nForbRule ));
518 break;
519 case RTF_NOOVERFLOW:
520 if( PARDID->nHangPunct )
522 pSet->Put( SvxHangingPunctuationItem( sal_False,
523 PARDID->nHangPunct ));
525 break;
527 case RTF_ASPALPHA:
528 if( PARDID->nScriptSpace )
530 pSet->Put( SvxScriptSpaceItem( sal_True,
531 PARDID->nScriptSpace ));
533 break;
535 case RTF_FAFIXED:
536 case RTF_FAAUTO: nFontAlign = SvxParaVertAlignItem::AUTOMATIC;
537 goto SET_FONTALIGNMENT;
538 case RTF_FAHANG: nFontAlign = SvxParaVertAlignItem::TOP;
539 goto SET_FONTALIGNMENT;
540 case RTF_FAVAR: nFontAlign = SvxParaVertAlignItem::BOTTOM;
541 goto SET_FONTALIGNMENT;
542 case RTF_FACENTER: nFontAlign = SvxParaVertAlignItem::CENTER;
543 goto SET_FONTALIGNMENT;
544 case RTF_FAROMAN: nFontAlign = SvxParaVertAlignItem::BASELINE;
545 goto SET_FONTALIGNMENT;
546 SET_FONTALIGNMENT:
547 if( PARDID->nFontAlign )
549 pSet->Put( SvxParaVertAlignItem( nFontAlign,
550 PARDID->nFontAlign ));
552 break;
554 case RTF_B:
555 case RTF_AB:
556 if( IsAttrSttPos() ) // not in the text flow?
559 SvxWeightItem aTmpItem(
560 nTokenValue ? WEIGHT_BOLD : WEIGHT_NORMAL,
561 SID_ATTR_CHAR_WEIGHT );
562 SetScriptAttr( eCharType, *pSet, aTmpItem);
564 break;
566 case RTF_CAPS:
567 case RTF_SCAPS:
568 if( PLAINID->nCaseMap &&
569 IsAttrSttPos() ) // not in the text flow?
571 SvxCaseMap eCaseMap;
572 if( !nTokenValue )
573 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
574 else if( RTF_CAPS == nToken )
575 eCaseMap = SVX_CASEMAP_VERSALIEN;
576 else
577 eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
579 pSet->Put( SvxCaseMapItem( eCaseMap, PLAINID->nCaseMap ));
581 break;
583 case RTF_DN:
584 case RTF_SUB:
585 if( PLAINID->nEscapement )
587 const sal_uInt16 nEsc = PLAINID->nEscapement;
588 if( -1 == nTokenValue || RTF_SUB == nToken )
589 nTokenValue = 6;
590 if( IsCalcValue() )
591 CalcValue();
592 const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, sal_False );
593 short nEs;
594 sal_uInt8 nProp;
595 if( DFLT_ESC_AUTO_SUPER == rOld.GetEsc() )
597 nEs = DFLT_ESC_AUTO_SUB;
598 nProp = rOld.GetProp();
600 else
602 nEs = (short)-nTokenValue;
603 nProp = (nToken == RTF_SUB) ? DFLT_ESC_PROP : 100;
605 pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
607 break;
609 case RTF_NOSUPERSUB:
610 if( PLAINID->nEscapement )
612 const sal_uInt16 nEsc = PLAINID->nEscapement;
613 pSet->Put( SvxEscapementItem( nEsc ));
615 break;
617 case RTF_EXPND:
618 if( PLAINID->nKering )
620 if( -1 == nTokenValue )
621 nTokenValue = 0;
622 else
623 nTokenValue *= 5;
624 if( IsCalcValue() )
625 CalcValue();
626 pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
628 break;
630 case RTF_KERNING:
631 if( PLAINID->nAutoKerning )
633 if( -1 == nTokenValue )
634 nTokenValue = 0;
635 else
636 nTokenValue *= 10;
637 if( IsCalcValue() )
638 CalcValue();
639 pSet->Put( SvxAutoKernItem( 0 != nTokenValue,
640 PLAINID->nAutoKerning ));
642 break;
644 case RTF_EXPNDTW:
645 if( PLAINID->nKering )
647 if( -1 == nTokenValue )
648 nTokenValue = 0;
649 if( IsCalcValue() )
650 CalcValue();
651 pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
653 break;
655 case RTF_F:
656 case RTF_AF:
658 const Font& rSVFont = GetFont( sal_uInt16(nTokenValue) );
659 SvxFontItem aTmpItem( rSVFont.GetFamily(),
660 rSVFont.GetName(), rSVFont.GetStyleName(),
661 rSVFont.GetPitch(), rSVFont.GetCharSet(),
662 SID_ATTR_CHAR_FONT );
663 SetScriptAttr( eCharType, *pSet, aTmpItem );
664 if( RTF_F == nToken )
666 SetEncoding( rSVFont.GetCharSet() );
667 RereadLookahead();
670 break;
672 case RTF_FS:
673 case RTF_AFS:
675 if( -1 == nTokenValue )
676 nTokenValue = 240;
677 else
678 nTokenValue *= 10;
679 // #i66167#
680 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
681 // the converiosn takes now place in EditRTFParser since for other reasons
682 // the wrong MapUnit might still be use there
683 // if( IsCalcValue() )
684 // CalcValue();
685 SvxFontHeightItem aTmpItem(
686 (const sal_uInt16)nTokenValue, 100,
687 SID_ATTR_CHAR_FONTHEIGHT );
688 SetScriptAttr( eCharType, *pSet, aTmpItem );
690 break;
692 case RTF_I:
693 case RTF_AI:
694 if( IsAttrSttPos() ) // not in the text flow?
696 SvxPostureItem aTmpItem(
697 nTokenValue ? ITALIC_NORMAL : ITALIC_NONE,
698 SID_ATTR_CHAR_POSTURE );
699 SetScriptAttr( eCharType, *pSet, aTmpItem );
701 break;
703 case RTF_OUTL:
704 if( PLAINID->nContour &&
705 IsAttrSttPos() ) // not in the text flow?
707 pSet->Put( SvxContourItem( nTokenValue ? sal_True : sal_False,
708 PLAINID->nContour ));
710 break;
712 case RTF_SHAD:
713 if( PLAINID->nShadowed &&
714 IsAttrSttPos() ) // not in the text flow?
716 pSet->Put( SvxShadowedItem( nTokenValue ? sal_True : sal_False,
717 PLAINID->nShadowed ));
719 break;
721 case RTF_STRIKE:
722 if( PLAINID->nCrossedOut &&
723 IsAttrSttPos() ) // not in the text flow?
725 pSet->Put( SvxCrossedOutItem(
726 nTokenValue ? STRIKEOUT_SINGLE : STRIKEOUT_NONE,
727 PLAINID->nCrossedOut ));
729 break;
731 case RTF_STRIKED:
732 if( PLAINID->nCrossedOut ) // not in the text flow?
734 pSet->Put( SvxCrossedOutItem(
735 nTokenValue ? STRIKEOUT_DOUBLE : STRIKEOUT_NONE,
736 PLAINID->nCrossedOut ));
738 break;
740 case RTF_UL:
741 if( !IsAttrSttPos() )
742 break;
743 eUnderline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
744 goto ATTR_SETUNDERLINE;
746 case RTF_ULD:
747 eUnderline = UNDERLINE_DOTTED;
748 goto ATTR_SETUNDERLINE;
749 case RTF_ULDASH:
750 eUnderline = UNDERLINE_DASH;
751 goto ATTR_SETUNDERLINE;
752 case RTF_ULDASHD:
753 eUnderline = UNDERLINE_DASHDOT;
754 goto ATTR_SETUNDERLINE;
755 case RTF_ULDASHDD:
756 eUnderline = UNDERLINE_DASHDOTDOT;
757 goto ATTR_SETUNDERLINE;
758 case RTF_ULDB:
759 eUnderline = UNDERLINE_DOUBLE;
760 goto ATTR_SETUNDERLINE;
761 case RTF_ULNONE:
762 eUnderline = UNDERLINE_NONE;
763 goto ATTR_SETUNDERLINE;
764 case RTF_ULTH:
765 eUnderline = UNDERLINE_BOLD;
766 goto ATTR_SETUNDERLINE;
767 case RTF_ULWAVE:
768 eUnderline = UNDERLINE_WAVE;
769 goto ATTR_SETUNDERLINE;
770 case RTF_ULTHD:
771 eUnderline = UNDERLINE_BOLDDOTTED;
772 goto ATTR_SETUNDERLINE;
773 case RTF_ULTHDASH:
774 eUnderline = UNDERLINE_BOLDDASH;
775 goto ATTR_SETUNDERLINE;
776 case RTF_ULLDASH:
777 eUnderline = UNDERLINE_LONGDASH;
778 goto ATTR_SETUNDERLINE;
779 case RTF_ULTHLDASH:
780 eUnderline = UNDERLINE_BOLDLONGDASH;
781 goto ATTR_SETUNDERLINE;
782 case RTF_ULTHDASHD:
783 eUnderline = UNDERLINE_BOLDDASHDOT;
784 goto ATTR_SETUNDERLINE;
785 case RTF_ULTHDASHDD:
786 eUnderline = UNDERLINE_BOLDDASHDOTDOT;
787 goto ATTR_SETUNDERLINE;
788 case RTF_ULHWAVE:
789 eUnderline = UNDERLINE_BOLDWAVE;
790 goto ATTR_SETUNDERLINE;
791 case RTF_ULULDBWAVE:
792 eUnderline = UNDERLINE_DOUBLEWAVE;
793 goto ATTR_SETUNDERLINE;
795 case RTF_ULW:
796 eUnderline = UNDERLINE_SINGLE;
798 if( PLAINID->nWordlineMode )
800 pSet->Put( SvxWordLineModeItem( sal_True, PLAINID->nWordlineMode ));
802 goto ATTR_SETUNDERLINE;
804 ATTR_SETUNDERLINE:
805 if( PLAINID->nUnderline )
807 pSet->Put( SvxUnderlineItem( eUnderline, PLAINID->nUnderline ));
809 break;
811 case RTF_ULC:
812 if( PLAINID->nUnderline )
814 SvxUnderlineItem aUL( UNDERLINE_SINGLE, PLAINID->nUnderline );
815 const SfxPoolItem* pItem;
816 if( SFX_ITEM_SET == pSet->GetItemState(
817 PLAINID->nUnderline, sal_False, &pItem ) )
819 // is switched off ?
820 if( UNDERLINE_NONE ==
821 ((SvxUnderlineItem*)pItem)->GetLineStyle() )
822 break;
823 aUL = *(SvxUnderlineItem*)pItem;
825 else
826 aUL = (const SvxUnderlineItem&)pSet->Get( PLAINID->nUnderline, sal_False );
828 if( UNDERLINE_NONE == aUL.GetLineStyle() )
829 aUL.SetLineStyle( UNDERLINE_SINGLE );
830 aUL.SetColor( GetColor( sal_uInt16(nTokenValue) ));
831 pSet->Put( aUL );
833 break;
835 case RTF_OL:
836 if( !IsAttrSttPos() )
837 break;
838 eOverline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
839 goto ATTR_SETOVERLINE;
841 case RTF_OLD:
842 eOverline = UNDERLINE_DOTTED;
843 goto ATTR_SETOVERLINE;
844 case RTF_OLDASH:
845 eOverline = UNDERLINE_DASH;
846 goto ATTR_SETOVERLINE;
847 case RTF_OLDASHD:
848 eOverline = UNDERLINE_DASHDOT;
849 goto ATTR_SETOVERLINE;
850 case RTF_OLDASHDD:
851 eOverline = UNDERLINE_DASHDOTDOT;
852 goto ATTR_SETOVERLINE;
853 case RTF_OLDB:
854 eOverline = UNDERLINE_DOUBLE;
855 goto ATTR_SETOVERLINE;
856 case RTF_OLNONE:
857 eOverline = UNDERLINE_NONE;
858 goto ATTR_SETOVERLINE;
859 case RTF_OLTH:
860 eOverline = UNDERLINE_BOLD;
861 goto ATTR_SETOVERLINE;
862 case RTF_OLWAVE:
863 eOverline = UNDERLINE_WAVE;
864 goto ATTR_SETOVERLINE;
865 case RTF_OLTHD:
866 eOverline = UNDERLINE_BOLDDOTTED;
867 goto ATTR_SETOVERLINE;
868 case RTF_OLTHDASH:
869 eOverline = UNDERLINE_BOLDDASH;
870 goto ATTR_SETOVERLINE;
871 case RTF_OLLDASH:
872 eOverline = UNDERLINE_LONGDASH;
873 goto ATTR_SETOVERLINE;
874 case RTF_OLTHLDASH:
875 eOverline = UNDERLINE_BOLDLONGDASH;
876 goto ATTR_SETOVERLINE;
877 case RTF_OLTHDASHD:
878 eOverline = UNDERLINE_BOLDDASHDOT;
879 goto ATTR_SETOVERLINE;
880 case RTF_OLTHDASHDD:
881 eOverline = UNDERLINE_BOLDDASHDOTDOT;
882 goto ATTR_SETOVERLINE;
883 case RTF_OLHWAVE:
884 eOverline = UNDERLINE_BOLDWAVE;
885 goto ATTR_SETOVERLINE;
886 case RTF_OLOLDBWAVE:
887 eOverline = UNDERLINE_DOUBLEWAVE;
888 goto ATTR_SETOVERLINE;
890 case RTF_OLW:
891 eOverline = UNDERLINE_SINGLE;
893 if( PLAINID->nWordlineMode )
895 pSet->Put( SvxWordLineModeItem( sal_True, PLAINID->nWordlineMode ));
897 goto ATTR_SETOVERLINE;
899 ATTR_SETOVERLINE:
900 if( PLAINID->nUnderline )
902 pSet->Put( SvxOverlineItem( eOverline, PLAINID->nOverline ));
904 break;
906 case RTF_OLC:
907 if( PLAINID->nOverline )
909 SvxOverlineItem aOL( UNDERLINE_SINGLE, PLAINID->nOverline );
910 const SfxPoolItem* pItem;
911 if( SFX_ITEM_SET == pSet->GetItemState(
912 PLAINID->nOverline, sal_False, &pItem ) )
914 // is switched off ?
915 if( UNDERLINE_NONE ==
916 ((SvxOverlineItem*)pItem)->GetLineStyle() )
917 break;
918 aOL = *(SvxOverlineItem*)pItem;
920 else
921 aOL = (const SvxOverlineItem&)pSet->Get( PLAINID->nUnderline, sal_False );
923 if( UNDERLINE_NONE == aOL.GetLineStyle() )
924 aOL.SetLineStyle( UNDERLINE_SINGLE );
925 aOL.SetColor( GetColor( sal_uInt16(nTokenValue) ));
926 pSet->Put( aOL );
928 break;
930 case RTF_UP:
931 case RTF_SUPER:
932 if( PLAINID->nEscapement )
934 const sal_uInt16 nEsc = PLAINID->nEscapement;
935 if( -1 == nTokenValue || RTF_SUPER == nToken )
936 nTokenValue = 6;
937 if( IsCalcValue() )
938 CalcValue();
939 const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, sal_False );
940 short nEs;
941 sal_uInt8 nProp;
942 if( DFLT_ESC_AUTO_SUB == rOld.GetEsc() )
944 nEs = DFLT_ESC_AUTO_SUPER;
945 nProp = rOld.GetProp();
947 else
949 nEs = (short)nTokenValue;
950 nProp = (nToken == RTF_SUPER) ? DFLT_ESC_PROP : 100;
952 pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
954 break;
956 case RTF_CF:
957 if( PLAINID->nColor )
959 pSet->Put( SvxColorItem( GetColor( sal_uInt16(nTokenValue) ),
960 PLAINID->nColor ));
962 break;
963 //#i12501# While cb is clearly documented in the rtf spec, word
964 //doesn't accept it at all
965 #if 0
966 case RTF_CB:
967 if( PLAINID->nBgColor )
969 pSet->Put( SvxBrushItem( GetColor( sal_uInt16(nTokenValue) ),
970 PLAINID->nBgColor ));
972 break;
973 #endif
975 case RTF_LANG:
976 if( PLAINID->nLanguage )
978 pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
979 PLAINID->nLanguage ));
981 break;
983 case RTF_LANGFE:
984 if( PLAINID->nCJKLanguage )
986 pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
987 PLAINID->nCJKLanguage ));
989 break;
990 case RTF_ALANG:
992 SvxLanguageItem aTmpItem( (LanguageType)nTokenValue,
993 SID_ATTR_CHAR_LANGUAGE );
994 SetScriptAttr( eCharType, *pSet, aTmpItem );
996 break;
998 case RTF_RTLCH:
999 bIsLeftToRightDef = sal_False;
1000 break;
1001 case RTF_LTRCH:
1002 bIsLeftToRightDef = sal_True;
1003 break;
1004 case RTF_RTLPAR:
1005 if (PARDID->nDirection)
1007 pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP,
1008 PARDID->nDirection));
1010 break;
1011 case RTF_LTRPAR:
1012 if (PARDID->nDirection)
1014 pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP,
1015 PARDID->nDirection));
1017 break;
1018 case RTF_LOCH: eCharType = LOW_CHARTYPE; break;
1019 case RTF_HICH: eCharType = HIGH_CHARTYPE; break;
1020 case RTF_DBCH: eCharType = DOUBLEBYTE_CHARTYPE; break;
1023 case RTF_ACCNONE:
1024 eEmphasis = EMPHASISMARK_NONE;
1025 goto ATTR_SETEMPHASIS;
1026 case RTF_ACCDOT:
1027 eEmphasis = EMPHASISMARK_DOTS_ABOVE;
1028 goto ATTR_SETEMPHASIS;
1030 case RTF_ACCCOMMA:
1031 eEmphasis = EMPHASISMARK_SIDE_DOTS;
1032 ATTR_SETEMPHASIS:
1033 if( PLAINID->nEmphasis )
1035 pSet->Put( SvxEmphasisMarkItem( eEmphasis,
1036 PLAINID->nEmphasis ));
1038 break;
1040 case RTF_TWOINONE:
1041 if( PLAINID->nTwoLines )
1043 sal_Unicode cStt, cEnd;
1044 switch ( nTokenValue )
1046 case 1: cStt = '(', cEnd = ')'; break;
1047 case 2: cStt = '[', cEnd = ']'; break;
1048 case 3: cStt = '<', cEnd = '>'; break;
1049 case 4: cStt = '{', cEnd = '}'; break;
1050 default: cStt = 0, cEnd = 0; break;
1053 pSet->Put( SvxTwoLinesItem( sal_True, cStt, cEnd,
1054 PLAINID->nTwoLines ));
1056 break;
1058 case RTF_CHARSCALEX :
1059 if (PLAINID->nCharScaleX)
1061 //i21372
1062 if (nTokenValue < 1 || nTokenValue > 600)
1063 nTokenValue = 100;
1064 pSet->Put( SvxCharScaleWidthItem( sal_uInt16(nTokenValue),
1065 PLAINID->nCharScaleX ));
1067 break;
1069 case RTF_HORZVERT:
1070 if( PLAINID->nHorzVert )
1072 // RTF knows only 90deg
1073 pSet->Put( SvxCharRotateItem( 900, 1 == nTokenValue,
1074 PLAINID->nHorzVert ));
1076 break;
1078 case RTF_EMBO:
1079 if (PLAINID->nRelief)
1081 pSet->Put(SvxCharReliefItem(RELIEF_EMBOSSED,
1082 PLAINID->nRelief));
1084 break;
1085 case RTF_IMPR:
1086 if (PLAINID->nRelief)
1088 pSet->Put(SvxCharReliefItem(RELIEF_ENGRAVED,
1089 PLAINID->nRelief));
1091 break;
1092 case RTF_V:
1093 if (PLAINID->nHidden)
1095 pSet->Put(SvxCharHiddenItem(nTokenValue != 0,
1096 PLAINID->nHidden));
1098 break;
1099 case RTF_CHBGFDIAG:
1100 case RTF_CHBGDKVERT:
1101 case RTF_CHBGDKHORIZ:
1102 case RTF_CHBGVERT:
1103 case RTF_CHBGHORIZ:
1104 case RTF_CHBGDKFDIAG:
1105 case RTF_CHBGDCROSS:
1106 case RTF_CHBGCROSS:
1107 case RTF_CHBGBDIAG:
1108 case RTF_CHBGDKDCROSS:
1109 case RTF_CHBGDKCROSS:
1110 case RTF_CHBGDKBDIAG:
1111 case RTF_CHCBPAT:
1112 case RTF_CHCFPAT:
1113 case RTF_CHSHDNG:
1114 if( PLAINID->nBgColor )
1115 ReadBackgroundAttr( nToken, *pSet );
1116 break;
1118 case BRACELEFT:
1120 // tests on Swg internal tokens
1121 bool bHandled = false;
1122 short nSkip = 0;
1123 if( RTF_IGNOREFLAG != GetNextToken())
1124 nSkip = -1;
1125 else if( (nToken = GetNextToken() ) & RTF_SWGDEFS )
1127 bHandled = true;
1128 switch( nToken )
1130 case RTF_PGDSCNO:
1131 case RTF_PGBRK:
1132 case RTF_SOUTLVL:
1133 UnknownAttrToken( nToken, pSet );
1134 // overwrite the closing parenthesis
1135 break;
1137 case RTF_SWG_ESCPROP:
1139 // Store percentage change!
1140 sal_uInt8 nProp = sal_uInt8( nTokenValue / 100 );
1141 short nEsc = 0;
1142 if( 1 == ( nTokenValue % 100 ))
1143 // Recognize own auto-flags!
1144 nEsc = DFLT_ESC_AUTO_SUPER;
1146 if( PLAINID->nEscapement )
1147 pSet->Put( SvxEscapementItem( nEsc, nProp,
1148 PLAINID->nEscapement ));
1150 break;
1152 case RTF_HYPHEN:
1154 SvxHyphenZoneItem aHypenZone(
1155 (nTokenValue & 1) ? sal_True : sal_False,
1156 PARDID->nHyphenzone );
1157 aHypenZone.SetPageEnd(
1158 (nTokenValue & 2) ? sal_True : sal_False );
1160 if( PARDID->nHyphenzone &&
1161 RTF_HYPHLEAD == GetNextToken() &&
1162 RTF_HYPHTRAIL == GetNextToken() &&
1163 RTF_HYPHMAX == GetNextToken() )
1165 aHypenZone.GetMinLead() =
1166 sal_uInt8(GetStackPtr( -2 )->nTokenValue);
1167 aHypenZone.GetMinTrail() =
1168 sal_uInt8(GetStackPtr( -1 )->nTokenValue);
1169 aHypenZone.GetMaxHyphens() =
1170 sal_uInt8(nTokenValue);
1172 pSet->Put( aHypenZone );
1174 else
1175 SkipGroup(); // at the end of the group
1177 break;
1179 case RTF_SHADOW:
1181 int bSkip = sal_True;
1182 do { // middle check loop
1183 SvxShadowLocation eSL = SvxShadowLocation( nTokenValue );
1184 if( RTF_SHDW_DIST != GetNextToken() )
1185 break;
1186 sal_uInt16 nDist = sal_uInt16( nTokenValue );
1188 if( RTF_SHDW_STYLE != GetNextToken() )
1189 break;
1191 if( RTF_SHDW_COL != GetNextToken() )
1192 break;
1193 sal_uInt16 nCol = sal_uInt16( nTokenValue );
1195 if( RTF_SHDW_FCOL != GetNextToken() )
1196 break;
1198 Color aColor = GetColor( nCol );
1200 if( PARDID->nShadow )
1201 pSet->Put( SvxShadowItem( PARDID->nShadow,
1202 &aColor, nDist, eSL ) );
1204 bSkip = sal_False;
1205 } while( sal_False );
1207 if( bSkip )
1208 SkipGroup(); // at the end of the group
1210 break;
1212 default:
1213 bHandled = false;
1214 if( (nToken & ~(0xff | RTF_SWGDEFS)) == RTF_TABSTOPDEF )
1216 nToken = SkipToken( -2 );
1217 ReadTabAttr( nToken, *pSet );
1220 cmc: #i76140, he who consumed the { must consume the }
1221 We rewound to a state of { being the current
1222 token so it is our responsibility to consume the }
1223 token if we consumed the {. We will not have consumed
1224 the { if it belonged to our caller, i.e. if the { we
1225 are handling is the "firsttoken" passed to us then
1226 the *caller* must consume it, not us. Otherwise *we*
1227 should consume it.
1229 if (nToken == BRACELEFT && !bFirstToken)
1231 nToken = GetNextToken();
1232 DBG_ASSERT( nToken == BRACERIGHT,
1233 "} did not follow { as expected\n");
1236 else if( (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF)
1238 nToken = SkipToken( -2 );
1239 ReadBorderAttr( nToken, *pSet );
1241 else // so no more attribute
1242 nSkip = -2;
1243 break;
1246 #if 1
1248 cmc: #i4727# / #i12713# Who owns this closing bracket?
1249 If we read the opening one, we must read this one, if
1250 other is counting the brackets so as to push/pop off
1251 the correct environment then we will have pushed a new
1252 environment for the start { of this, but will not see
1253 the } and so is out of sync for the rest of the
1254 document.
1256 if (bHandled && !bFirstToken)
1257 GetNextToken();
1258 #endif
1260 else
1261 nSkip = -2;
1263 if( nSkip ) // all completely unknown
1265 if (!bFirstToken)
1266 --nSkip; // BRACELEFT: is the next token
1267 SkipToken( nSkip );
1268 bWeiter = sal_False;
1271 break;
1272 default:
1273 if( (nToken & ~0xff ) == RTF_TABSTOPDEF )
1274 ReadTabAttr( nToken, *pSet );
1275 else if( (nToken & ~0xff ) == RTF_BRDRDEF )
1276 ReadBorderAttr( nToken, *pSet );
1277 else if( (nToken & ~0xff ) == RTF_SHADINGDEF )
1278 ReadBackgroundAttr( nToken, *pSet );
1279 else
1281 // unknown token, so token "returned in Parser"
1282 if( !bFirstToken )
1283 SkipToken( -1 );
1284 bWeiter = sal_False;
1288 if( bWeiter )
1290 nToken = GetNextToken();
1292 bFirstToken = sal_False;
1296 void SvxRTFParser::ReadTabAttr( int nToken, SfxItemSet& rSet )
1298 bool bMethodOwnsToken = false; // #i52542# patch from cmc.
1299 // then read all the TabStops
1300 SvxTabStop aTabStop;
1301 SvxTabStopItem aAttr( 0, 0, SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
1302 int bWeiter = sal_True;
1303 do {
1304 switch( nToken )
1306 case RTF_TB: // BarTab ???
1307 case RTF_TX:
1309 if( IsCalcValue() )
1310 CalcValue();
1311 aTabStop.GetTabPos() = nTokenValue;
1312 aAttr.Insert( aTabStop );
1313 aTabStop = SvxTabStop(); // all values default
1315 break;
1317 case RTF_TQL:
1318 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
1319 break;
1320 case RTF_TQR:
1321 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
1322 break;
1323 case RTF_TQC:
1324 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
1325 break;
1326 case RTF_TQDEC:
1327 aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL;
1328 break;
1330 case RTF_TLDOT: aTabStop.GetFill() = '.'; break;
1331 case RTF_TLHYPH: aTabStop.GetFill() = ' '; break;
1332 case RTF_TLUL: aTabStop.GetFill() = '_'; break;
1333 case RTF_TLTH: aTabStop.GetFill() = '-'; break;
1334 case RTF_TLEQ: aTabStop.GetFill() = '='; break;
1336 case BRACELEFT:
1338 // Swg - control BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1339 short nSkip = 0;
1340 if( RTF_IGNOREFLAG != GetNextToken() )
1341 nSkip = -1;
1342 else if( RTF_TLSWG != ( nToken = GetNextToken() ))
1343 nSkip = -2;
1344 else
1346 aTabStop.GetDecimal() = sal_uInt8(nTokenValue & 0xff);
1347 aTabStop.GetFill() = sal_uInt8((nTokenValue >> 8) & 0xff);
1348 // overwrite the closing parenthesis
1349 if (bMethodOwnsToken)
1350 GetNextToken();
1352 if( nSkip )
1354 SkipToken( nSkip ); // Ignore back again
1355 bWeiter = sal_False;
1358 break;
1360 default:
1361 bWeiter = sal_False;
1363 if( bWeiter )
1365 nToken = GetNextToken();
1366 bMethodOwnsToken = true;
1368 } while( bWeiter );
1370 // Fill with defaults is still missing!
1371 rSet.Put( aAttr );
1372 SkipToken( -1 );
1375 static void SetBorderLine( int nBorderTyp, SvxBoxItem& rItem,
1376 const SvxBorderLine& rBorder )
1378 switch( nBorderTyp )
1380 case RTF_BOX: // run through all levels
1382 case RTF_BRDRT:
1383 rItem.SetLine( &rBorder, BOX_LINE_TOP );
1384 if( RTF_BOX != nBorderTyp )
1385 return;
1387 case RTF_BRDRB:
1388 rItem.SetLine( &rBorder, BOX_LINE_BOTTOM );
1389 if( RTF_BOX != nBorderTyp )
1390 return;
1392 case RTF_BRDRL:
1393 rItem.SetLine( &rBorder, BOX_LINE_LEFT );
1394 if( RTF_BOX != nBorderTyp )
1395 return;
1397 case RTF_BRDRR:
1398 rItem.SetLine( &rBorder, BOX_LINE_RIGHT );
1399 if( RTF_BOX != nBorderTyp )
1400 return;
1404 void SvxRTFParser::ReadBorderAttr( int nToken, SfxItemSet& rSet,
1405 int bTableDef )
1407 // then read the border attribute
1408 SvxBoxItem aAttr( PARDID->nBox );
1409 const SfxPoolItem* pItem;
1410 if( SFX_ITEM_SET == rSet.GetItemState( PARDID->nBox, sal_False, &pItem ) )
1411 aAttr = *(SvxBoxItem*)pItem;
1413 SvxBorderLine aBrd( 0, DEF_LINE_WIDTH_0 ); // Simple plain line
1414 int bWeiter = sal_True, nBorderTyp = 0;
1416 long nWidth = 1;
1417 bool bDoubleWidth = false;
1419 do {
1420 switch( nToken )
1422 case RTF_BOX:
1423 case RTF_BRDRT:
1424 case RTF_BRDRB:
1425 case RTF_BRDRL:
1426 case RTF_BRDRR:
1427 nBorderTyp = nToken;
1428 break;
1430 case RTF_CLBRDRT: // Cell top border
1432 if( bTableDef )
1434 if (nBorderTyp != 0)
1435 SetBorderLine( nBorderTyp, aAttr, aBrd );
1436 nBorderTyp = RTF_BRDRT;
1438 break;
1440 case RTF_CLBRDRB: // Cell bottom border
1442 if( bTableDef )
1444 if (nBorderTyp != 0)
1445 SetBorderLine( nBorderTyp, aAttr, aBrd );
1446 nBorderTyp = RTF_BRDRB;
1448 break;
1450 case RTF_CLBRDRL: // Cell left border
1452 if( bTableDef )
1454 if (nBorderTyp != 0)
1455 SetBorderLine( nBorderTyp, aAttr, aBrd );
1456 nBorderTyp = RTF_BRDRL;
1458 break;
1460 case RTF_CLBRDRR: // Cell right border
1462 if( bTableDef )
1464 if (nBorderTyp != 0)
1465 SetBorderLine( nBorderTyp, aAttr, aBrd );
1466 nBorderTyp = RTF_BRDRR;
1468 break;
1471 case RTF_BRDRDOT: // dotted border
1472 aBrd.SetBorderLineStyle(table::BorderLineStyle::DOTTED);
1473 break;
1474 case RTF_BRDRDASH: // dashed border
1475 aBrd.SetBorderLineStyle(table::BorderLineStyle::DASHED);
1476 break;
1477 case RTF_BRDRHAIR: // hairline border
1479 aBrd.SetBorderLineStyle( table::BorderLineStyle::SOLID);
1480 aBrd.SetWidth( DEF_LINE_WIDTH_0 );
1482 break;
1483 case RTF_BRDRDB: // Double border
1484 aBrd.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
1485 break;
1486 case RTF_BRDRINSET: // inset border
1487 aBrd.SetBorderLineStyle(table::BorderLineStyle::INSET);
1488 break;
1489 case RTF_BRDROUTSET: // outset border
1490 aBrd.SetBorderLineStyle(table::BorderLineStyle::OUTSET);
1491 break;
1492 case RTF_BRDRTNTHSG: // ThinThick Small gap
1493 aBrd.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_SMALLGAP);
1494 break;
1495 case RTF_BRDRTNTHMG: // ThinThick Medium gap
1496 aBrd.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_MEDIUMGAP);
1497 break;
1498 case RTF_BRDRTNTHLG: // ThinThick Large gap
1499 aBrd.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_LARGEGAP);
1500 break;
1501 case RTF_BRDRTHTNSG: // ThickThin Small gap
1502 aBrd.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_SMALLGAP);
1503 break;
1504 case RTF_BRDRTHTNMG: // ThickThin Medium gap
1505 aBrd.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_MEDIUMGAP);
1506 break;
1507 case RTF_BRDRTHTNLG: // ThickThin Large gap
1508 aBrd.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_LARGEGAP);
1509 break;
1510 case RTF_BRDREMBOSS: // Embossed border
1511 aBrd.SetBorderLineStyle(table::BorderLineStyle::EMBOSSED);
1512 break;
1513 case RTF_BRDRENGRAVE: // Engraved border
1514 aBrd.SetBorderLineStyle(table::BorderLineStyle::ENGRAVED);
1515 break;
1517 case RTF_BRDRS: // single thickness border
1518 bDoubleWidth = false;
1519 break;
1520 case RTF_BRDRTH: // double thickness border width*2
1521 bDoubleWidth = true;
1522 break;
1523 case RTF_BRDRW: // border width <255
1524 nWidth = nTokenValue;
1525 break;
1527 case RTF_BRDRCF: // Border color
1528 aBrd.SetColor( GetColor( sal_uInt16(nTokenValue) ) );
1529 break;
1531 case RTF_BRDRSH: // Shadowed border
1532 rSet.Put( SvxShadowItem( PARDID->nShadow, (Color*) 0, 60 /*3pt*/,
1533 SVX_SHADOW_BOTTOMRIGHT ) );
1534 break;
1536 case RTF_BRSP: // Spacing to content in twip
1538 switch( nBorderTyp )
1540 case RTF_BRDRB:
1541 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_BOTTOM );
1542 break;
1544 case RTF_BRDRT:
1545 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_TOP );
1546 break;
1548 case RTF_BRDRL:
1549 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_LEFT );
1550 break;
1552 case RTF_BRDRR:
1553 aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_RIGHT );
1554 break;
1556 case RTF_BOX:
1557 aAttr.SetDistance( (sal_uInt16)nTokenValue );
1558 break;
1561 break;
1563 case RTF_BRDRBTW: // Border formatting group
1564 case RTF_BRDRBAR: // Border outside
1565 // TODO unhandled ATM
1566 break;
1568 default:
1569 bWeiter = (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF;
1571 if( bWeiter )
1572 nToken = GetNextToken();
1573 } while( bWeiter );
1575 // Finally compute the border width
1576 if ( bDoubleWidth ) nWidth *= 2;
1577 aBrd.SetWidth( nWidth );
1579 SetBorderLine( nBorderTyp, aAttr, aBrd );
1581 rSet.Put( aAttr );
1582 SkipToken( -1 );
1585 inline sal_uInt32 CalcShading( sal_uInt32 nColor, sal_uInt32 nFillColor, sal_uInt8 nShading )
1587 nColor = (nColor * nShading) / 100;
1588 nFillColor = (nFillColor * ( 100 - nShading )) / 100;
1589 return nColor + nFillColor;
1592 void SvxRTFParser::ReadBackgroundAttr( int nToken, SfxItemSet& rSet,
1593 int bTableDef )
1595 // then read the border attribute
1596 int bWeiter = sal_True;
1597 sal_uInt16 nColor = USHRT_MAX, nFillColor = USHRT_MAX;
1598 sal_uInt8 nFillValue = 0;
1600 sal_uInt16 nWh = ( nToken & ~0xff ) == RTF_CHRFMT
1601 ? PLAINID->nBgColor
1602 : PARDID->nBrush;
1604 do {
1605 switch( nToken )
1607 case RTF_CLCBPAT:
1608 case RTF_CHCBPAT:
1609 case RTF_CBPAT:
1610 nFillColor = sal_uInt16( nTokenValue );
1611 break;
1613 case RTF_CLCFPAT:
1614 case RTF_CHCFPAT:
1615 case RTF_CFPAT:
1616 nColor = sal_uInt16( nTokenValue );
1617 break;
1619 case RTF_CLSHDNG:
1620 case RTF_CHSHDNG:
1621 case RTF_SHADING:
1622 nFillValue = (sal_uInt8)( nTokenValue / 100 );
1623 break;
1625 case RTF_CLBGDKHOR:
1626 case RTF_CHBGDKHORIZ:
1627 case RTF_BGDKHORIZ:
1628 case RTF_CLBGDKVERT:
1629 case RTF_CHBGDKVERT:
1630 case RTF_BGDKVERT:
1631 case RTF_CLBGDKBDIAG:
1632 case RTF_CHBGDKBDIAG:
1633 case RTF_BGDKBDIAG:
1634 case RTF_CLBGDKFDIAG:
1635 case RTF_CHBGDKFDIAG:
1636 case RTF_BGDKFDIAG:
1637 case RTF_CLBGDKCROSS:
1638 case RTF_CHBGDKCROSS:
1639 case RTF_BGDKCROSS:
1640 case RTF_CLBGDKDCROSS:
1641 case RTF_CHBGDKDCROSS:
1642 case RTF_BGDKDCROSS:
1643 // dark -> 60%
1644 nFillValue = 60;
1645 break;
1647 case RTF_CLBGHORIZ:
1648 case RTF_CHBGHORIZ:
1649 case RTF_BGHORIZ:
1650 case RTF_CLBGVERT:
1651 case RTF_CHBGVERT:
1652 case RTF_BGVERT:
1653 case RTF_CLBGBDIAG:
1654 case RTF_CHBGBDIAG:
1655 case RTF_BGBDIAG:
1656 case RTF_CLBGFDIAG:
1657 case RTF_CHBGFDIAG:
1658 case RTF_BGFDIAG:
1659 case RTF_CLBGCROSS:
1660 case RTF_CHBGCROSS:
1661 case RTF_BGCROSS:
1662 case RTF_CLBGDCROSS:
1663 case RTF_CHBGDCROSS:
1664 case RTF_BGDCROSS:
1665 // light -> 20%
1666 nFillValue = 20;
1667 break;
1669 default:
1670 if( bTableDef )
1671 bWeiter = (nToken & ~(0xff | RTF_TABLEDEF) ) == RTF_SHADINGDEF;
1672 else
1673 bWeiter = (nToken & ~0xff) == RTF_SHADINGDEF;
1675 if( bWeiter )
1676 nToken = GetNextToken();
1677 } while( bWeiter );
1679 Color aCol( COL_WHITE ), aFCol;
1680 if( !nFillValue )
1682 // there was only one of two colors specified or no BrushTyp
1683 if( USHRT_MAX != nFillColor )
1685 nFillValue = 100;
1686 aCol = GetColor( nFillColor );
1688 else if( USHRT_MAX != nColor )
1689 aFCol = GetColor( nColor );
1691 else
1693 if( USHRT_MAX != nColor )
1694 aCol = GetColor( nColor );
1695 else
1696 aCol = Color( COL_BLACK );
1698 if( USHRT_MAX != nFillColor )
1699 aFCol = GetColor( nFillColor );
1700 else
1701 aFCol = Color( COL_WHITE );
1704 Color aColor;
1705 if( 0 == nFillValue || 100 == nFillValue )
1706 aColor = aCol;
1707 else
1708 aColor = Color(
1709 (sal_uInt8)CalcShading( aCol.GetRed(), aFCol.GetRed(), nFillValue ),
1710 (sal_uInt8)CalcShading( aCol.GetGreen(), aFCol.GetGreen(), nFillValue ),
1711 (sal_uInt8)CalcShading( aCol.GetBlue(), aFCol.GetBlue(), nFillValue ) );
1713 rSet.Put( SvxBrushItem( aColor, nWh ) );
1714 SkipToken( -1 );
1718 // pard / plain abarbeiten
1719 void SvxRTFParser::RTFPardPlain( int bPard, SfxItemSet** ppSet )
1721 if( !bNewGroup && !aAttrStack.empty() ) // not at the beginning of a new group
1723 SvxRTFItemStackType* pAkt = aAttrStack.back();
1725 int nLastToken = GetStackPtr(-1)->nTokenId;
1726 int bNewStkEntry = sal_True;
1727 if( RTF_PARD != nLastToken &&
1728 RTF_PLAIN != nLastToken &&
1729 BRACELEFT != nLastToken )
1731 if( pAkt->aAttrSet.Count() || pAkt->pChildList || pAkt->nStyleNo )
1733 // open a new group
1734 SvxRTFItemStackType* pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, sal_True );
1735 pNew->SetRTFDefaults( GetRTFDefaults() );
1737 // Set all until here valid attributes
1738 AttrGroupEnd();
1739 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back(); // can be changed after AttrGroupEnd!
1740 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1741 aAttrStack.push_back( pNew );
1742 pAkt = pNew;
1744 else
1746 // continue to use this entry as new
1747 pAkt->SetStartPos( *pInsPos );
1748 bNewStkEntry = sal_False;
1752 // now reset all to default
1753 if( bNewStkEntry &&
1754 ( pAkt->aAttrSet.GetParent() || pAkt->aAttrSet.Count() ))
1756 const SfxPoolItem *pItem, *pDef;
1757 const sal_uInt16* pPtr;
1758 sal_uInt16 nCnt;
1759 const SfxItemSet* pDfltSet = &GetRTFDefaults();
1760 if( bPard )
1762 pAkt->nStyleNo = 0;
1763 pPtr = &aPardMap[0];
1764 nCnt = aPardMap.size();
1766 else
1768 pPtr = &aPlainMap[0];
1769 nCnt = aPlainMap.size();
1772 for( sal_uInt16 n = 0; n < nCnt; ++n, ++pPtr )
1774 // Item set and different -> Set the Default Pool
1775 if( !*pPtr )
1777 else if( SFX_WHICH_MAX < *pPtr )
1778 pAkt->aAttrSet.ClearItem( *pPtr );
1779 else if( IsChkStyleAttr() )
1780 pAkt->aAttrSet.Put( pDfltSet->Get( *pPtr ) );
1781 else if( !pAkt->aAttrSet.GetParent() )
1783 if( SFX_ITEM_SET ==
1784 pDfltSet->GetItemState( *pPtr, sal_False, &pDef ))
1785 pAkt->aAttrSet.Put( *pDef );
1786 else
1787 pAkt->aAttrSet.ClearItem( *pPtr );
1789 else if( SFX_ITEM_SET == pAkt->aAttrSet.GetParent()->
1790 GetItemState( *pPtr, sal_True, &pItem ) &&
1791 *( pDef = &pDfltSet->Get( *pPtr )) != *pItem )
1792 pAkt->aAttrSet.Put( *pDef );
1793 else
1795 if( SFX_ITEM_SET ==
1796 pDfltSet->GetItemState( *pPtr, sal_False, &pDef ))
1797 pAkt->aAttrSet.Put( *pDef );
1798 else
1799 pAkt->aAttrSet.ClearItem( *pPtr );
1803 else if( bPard )
1804 pAkt->nStyleNo = 0; // reset Style number
1806 *ppSet = &pAkt->aAttrSet;
1808 if (!bPard)
1810 //Once we have a default font, then any text without a font specifier is
1811 //in the default font, and thus has the default font charset, otherwise
1812 //we can fall back to the ansicpg set codeset
1813 if (nDfltFont != -1)
1815 const Font& rSVFont = GetFont(sal_uInt16(nDfltFont));
1816 SetEncoding(rSVFont.GetCharSet());
1818 else
1819 SetEncoding(GetCodeSet());
1824 void SvxRTFParser::SetDefault( int nToken, int nValue )
1826 if( !bNewDoc )
1827 return;
1829 SfxItemSet aTmp( *pAttrPool, &aWhichMap[0] );
1830 sal_Bool bOldFlag = bIsLeftToRightDef;
1831 bIsLeftToRightDef = sal_True;
1832 switch( nToken )
1834 case RTF_ADEFF: bIsLeftToRightDef = sal_False; // no break!
1835 case RTF_DEFF:
1837 if( -1 == nValue )
1838 nValue = 0;
1839 const Font& rSVFont = GetFont( sal_uInt16(nValue) );
1840 SvxFontItem aTmpItem(
1841 rSVFont.GetFamily(), rSVFont.GetName(),
1842 rSVFont.GetStyleName(), rSVFont.GetPitch(),
1843 rSVFont.GetCharSet(), SID_ATTR_CHAR_FONT );
1844 SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
1846 break;
1848 case RTF_ADEFLANG: bIsLeftToRightDef = sal_False; // no break!
1849 case RTF_DEFLANG:
1850 // store default Language
1851 if( -1 != nValue )
1853 SvxLanguageItem aTmpItem( (const LanguageType)nValue,
1854 SID_ATTR_CHAR_LANGUAGE );
1855 SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
1857 break;
1859 case RTF_DEFTAB:
1860 if( PARDID->nTabStop )
1862 // RTF defines 720 twips as default
1863 bIsSetDfltTab = sal_True;
1864 if( -1 == nValue || !nValue )
1865 nValue = 720;
1867 // who would like to have no twips ...
1868 if( IsCalcValue() )
1870 nTokenValue = nValue;
1871 CalcValue();
1872 nValue = nTokenValue;
1875 // Calculate the ratio of default TabWidth / Tabs and
1876 // calculate the corresponding new number.
1877 // ?? how did one come up with 13 ??
1878 sal_uInt16 nAnzTabs = (SVX_TAB_DEFDIST * 13 ) / sal_uInt16(nValue);
1880 cmc, make sure we have at least one, or all hell breaks loose in
1881 everybodies exporters, #i8247#
1883 if (nAnzTabs < 1)
1884 nAnzTabs = 1;
1886 // we want Defaulttabs
1887 SvxTabStopItem aNewTab( nAnzTabs, sal_uInt16(nValue),
1888 SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
1889 while( nAnzTabs )
1890 ((SvxTabStop&)aNewTab[ --nAnzTabs ]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
1892 pAttrPool->SetPoolDefaultItem( aNewTab );
1894 break;
1896 bIsLeftToRightDef = bOldFlag;
1898 if( aTmp.Count() )
1900 SfxItemIter aIter( aTmp );
1901 const SfxPoolItem* pItem = aIter.GetCurItem();
1902 while( sal_True )
1904 pAttrPool->SetPoolDefaultItem( *pItem );
1905 if( aIter.IsAtEnd() )
1906 break;
1907 pItem = aIter.NextItem();
1912 // default: no conversion, leaving everything in twips.
1913 void SvxRTFParser::CalcValue()
1917 // for tokens that are not evaluated in ReadAttr
1918 void SvxRTFParser::UnknownAttrToken( int, SfxItemSet* )
1922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */