xref: /trunk/main/editeng/source/rtf/rtfitem.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_editeng.hxx"
30 
31 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
32 
33 #include <editeng/flstitem.hxx>
34 #include <editeng/fontitem.hxx>
35 #include <editeng/postitem.hxx>
36 #include <editeng/wghtitem.hxx>
37 #include <editeng/fhgtitem.hxx>
38 #include <editeng/fwdtitem.hxx>
39 #include <editeng/udlnitem.hxx>
40 #include <editeng/crsditem.hxx>
41 #include <editeng/shdditem.hxx>
42 #include <editeng/akrnitem.hxx>
43 #include <editeng/wrlmitem.hxx>
44 #include <editeng/cntritem.hxx>
45 #include <editeng/prszitem.hxx>
46 #include <editeng/colritem.hxx>
47 #include <editeng/cscoitem.hxx>
48 #include <editeng/kernitem.hxx>
49 #include <editeng/cmapitem.hxx>
50 #include <editeng/escpitem.hxx>
51 #include <editeng/langitem.hxx>
52 #include <editeng/nlbkitem.hxx>
53 #include <editeng/nhypitem.hxx>
54 #include <editeng/lcolitem.hxx>
55 #include <editeng/blnkitem.hxx>
56 #include <editeng/emphitem.hxx>
57 #include <editeng/twolinesitem.hxx>
58 #include <editeng/pbinitem.hxx>
59 #include <editeng/sizeitem.hxx>
60 #include <editeng/lrspitem.hxx>
61 #include <editeng/ulspitem.hxx>
62 #include <editeng/prntitem.hxx>
63 #include <editeng/opaqitem.hxx>
64 #include <editeng/protitem.hxx>
65 #include <editeng/shaditem.hxx>
66 #include <editeng/boxitem.hxx>
67 #include <editeng/brkitem.hxx>
68 #include <editeng/keepitem.hxx>
69 #include <editeng/bolnitem.hxx>
70 #include <editeng/brshitem.hxx>
71 #include <editeng/lspcitem.hxx>
72 #include <editeng/adjitem.hxx>
73 #include <editeng/orphitem.hxx>
74 #include <editeng/widwitem.hxx>
75 #include <editeng/tstpitem.hxx>
76 #include <editeng/pmdlitem.hxx>
77 #include <editeng/spltitem.hxx>
78 #include <editeng/hyznitem.hxx>
79 #include <editeng/charscaleitem.hxx>
80 #include <editeng/charrotateitem.hxx>
81 #include <editeng/charreliefitem.hxx>
82 #include <editeng/paravertalignitem.hxx>
83 #include <editeng/forbiddenruleitem.hxx>
84 #include <editeng/hngpnctitem.hxx>
85 #include <editeng/scriptspaceitem.hxx>
86 #include <editeng/frmdiritem.hxx>
87 #include <editeng/charhiddenitem.hxx>
88 
89 #include <svtools/rtftoken.h>
90 #include <svl/itempool.hxx>
91 #include <svl/itemiter.hxx>
92 
93 #include <editeng/svxrtf.hxx>
94 #include <editeng/editids.hrc>
95 
96 #define BRACELEFT   '{'
97 #define BRACERIGHT  '}'
98 
99 
100 // einige Hilfs-Funktionen
101 // char
102 inline const SvxEscapementItem& GetEscapement(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
103     { return (const SvxEscapementItem&)rSet.Get( nId,bInP); }
104 inline const SvxLineSpacingItem& GetLineSpacing(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
105     { return (const SvxLineSpacingItem&)rSet.Get( nId,bInP); }
106 // frm
107 inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
108     { return (const SvxLRSpaceItem&)rSet.Get( nId,bInP); }
109 inline const SvxULSpaceItem& GetULSpace(const SfxItemSet& rSet,sal_uInt16 nId,sal_Bool bInP=sal_True)
110     { return (const SvxULSpaceItem&)rSet.Get( nId,bInP); }
111 
112 #define PARDID      ((RTFPardAttrMapIds*)aPardMap.GetData())
113 #define PLAINID     ((RTFPlainAttrMapIds*)aPlainMap.GetData())
114 
115 void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType, SfxItemSet& rSet,
116                                     SfxPoolItem& rItem )
117 {
118     const sal_uInt16 *pNormal = 0, *pCJK = 0, *pCTL = 0;
119     const RTFPlainAttrMapIds* pIds = (RTFPlainAttrMapIds*)aPlainMap.GetData();
120     switch( rItem.Which() )
121     {
122     case SID_ATTR_CHAR_FONT:
123         pNormal = &pIds->nFont;
124         pCJK = &pIds->nCJKFont;
125         pCTL = &pIds->nCTLFont;
126         break;
127 
128     case SID_ATTR_CHAR_FONTHEIGHT:
129         pNormal = &pIds->nFontHeight;
130         pCJK = &pIds->nCJKFontHeight;
131         pCTL = &pIds->nCTLFontHeight;
132         break;
133 
134     case SID_ATTR_CHAR_POSTURE:
135         pNormal = &pIds->nPosture;
136         pCJK = &pIds->nCJKPosture;
137         pCTL = &pIds->nCTLPosture;
138         break;
139 
140     case SID_ATTR_CHAR_WEIGHT:
141         pNormal = &pIds->nWeight;
142         pCJK = &pIds->nCJKWeight;
143         pCTL = &pIds->nCTLWeight;
144         break;
145 
146     case SID_ATTR_CHAR_LANGUAGE:
147         pNormal = &pIds->nLanguage;
148         pCJK = &pIds->nCJKLanguage;
149         pCTL = &pIds->nCTLLanguage;
150         break;
151 
152     case 0:
153         // it exist no WhichId - don't set this item
154         break;
155 
156     default:
157        rSet.Put( rItem );
158        break;
159     }
160 
161 
162     if( DOUBLEBYTE_CHARTYPE == eType )
163     {
164         if( bIsLeftToRightDef && *pCJK )
165         {
166             rItem.SetWhich( *pCJK );
167             rSet.Put( rItem );
168         }
169     }
170     else if( !bIsLeftToRightDef )
171     {
172         if( *pCTL )
173         {
174             rItem.SetWhich( *pCTL );
175             rSet.Put( rItem );
176         }
177     }
178     else
179     {
180         if( LOW_CHARTYPE == eType )
181         {
182             if( *pNormal )
183             {
184                 rItem.SetWhich( *pNormal );
185                 rSet.Put( rItem );
186             }
187         }
188         else if( HIGH_CHARTYPE == eType )
189         {
190             if( *pCTL )
191             {
192                 rItem.SetWhich( *pCTL );
193                 rSet.Put( rItem );
194             }
195         }
196         else
197         {
198             if( *pCJK )
199             {
200                 rItem.SetWhich( *pCJK );
201                 rSet.Put( rItem );
202             }
203             if( *pCTL )
204             {
205                 rItem.SetWhich( *pCTL );
206                 rSet.Put( rItem );
207             }
208             if( *pNormal )
209             {
210                 rItem.SetWhich( *pNormal );
211                 rSet.Put( rItem );
212             }
213         }
214     }
215 }
216 
217 // --------------------
218 
219 void SvxRTFParser::ReadAttr( int nToken, SfxItemSet* pSet )
220 {
221     DBG_ASSERT( pSet, "Es muss ein SfxItemSet uebergeben werden!" );
222     int bFirstToken = sal_True, bWeiter = sal_True;
223     sal_uInt16 nStyleNo = 0;        // default
224     FontUnderline eUnderline;
225     FontUnderline eOverline;
226     FontEmphasisMark eEmphasis;
227     bPardTokenRead = sal_False;
228     RTF_CharTypeDef eCharType = NOTDEF_CHARTYPE;
229     sal_uInt16 nFontAlign;
230 
231     int bChkStkPos = !bNewGroup && !aAttrStack.empty();
232 
233     while( bWeiter && IsParserWorking() )           // solange bekannte Attribute erkannt werden
234     {
235         switch( nToken )
236         {
237         case RTF_PARD:
238             RTFPardPlain( sal_True, &pSet );
239             ResetPard();
240             nStyleNo = 0;
241             bPardTokenRead = sal_True;
242             break;
243 
244         case RTF_PLAIN:
245             RTFPardPlain( sal_False, &pSet );
246             break;
247 
248         default:
249             do {        // middle checked loop
250                 if( !bChkStkPos )
251                     break;
252 
253                 SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
254                 if( !pAkt || (pAkt->pSttNd->GetIdx() == pInsPos->GetNodeIdx() &&
255                     pAkt->nSttCnt == pInsPos->GetCntIdx() ))
256                     break;
257 
258                 int nLastToken = GetStackPtr(-1)->nTokenId;
259                 if( RTF_PARD == nLastToken || RTF_PLAIN == nLastToken )
260                     break;
261 
262                 if( pAkt->aAttrSet.Count() || pAkt->pChildList ||
263                     pAkt->nStyleNo )
264                 {
265                     // eine neue Gruppe aufmachen
266                     SvxRTFItemStackType* pNew = new SvxRTFItemStackType(
267                                                 *pAkt, *pInsPos, sal_True );
268                     pNew->SetRTFDefaults( GetRTFDefaults() );
269 
270                     // alle bis hierher gueltigen Attribute "setzen"
271                     AttrGroupEnd();
272                     pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();  // can be changed after AttrGroupEnd!
273                     pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
274 
275                     aAttrStack.push_back( pNew );
276                     pAkt = pNew;
277                 }
278                 else
279                     // diesen Eintrag als neuen weiterbenutzen
280                     pAkt->SetStartPos( *pInsPos );
281 
282                 pSet = &pAkt->aAttrSet;
283             } while( sal_False );
284 
285             switch( nToken )
286             {
287             case RTF_INTBL:
288             case RTF_PAGEBB:
289             case RTF_SBYS:
290             case RTF_CS:
291             case RTF_LS:
292             case RTF_ILVL:
293                     UnknownAttrToken( nToken, pSet );
294                     break;
295 
296             case RTF_S:
297                 if( bIsInReadStyleTab )
298                 {
299                     if( !bFirstToken )
300                         SkipToken( -1 );
301                     bWeiter = sal_False;
302                 }
303                 else
304                 {
305                     nStyleNo = -1 == nTokenValue ? 0 : sal_uInt16(nTokenValue);
306                     // setze am akt. auf dem AttrStack stehenden Style die
307                     // StyleNummer
308                     SvxRTFItemStackType* pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();
309                     if( !pAkt )
310                         break;
311 
312                     pAkt->nStyleNo = sal_uInt16( nStyleNo );
313 
314 #if 0
315 // JP 05.09.95: zuruecksetzen der Style-Attribute fuehrt nur zu Problemen.
316 //              Es muss reichen, wenn das ueber pard/plain erfolgt
317 //  ansonsten Bugdoc 15304.rtf - nach nur "\pard" falscher Font !!
318 
319                     SvxRTFStyleType* pStyle = aStyleTbl.Get( pAkt->nStyleNo );
320                     if( pStyle && pStyle->aAttrSet.Count() )
321                     {
322                         //JP 07.07.95:
323                         // alle Attribute, die in der Vorlage gesetzt werden
324                         // auf defaults setzen. In RTF werden die Attribute
325                         // der Vorlage danach ja wiederholt.
326                         // WICHTIG: Attribute die in der Vorlage definiert
327                         //          sind, werden zurueckgesetzt !!!!
328                         // pAkt->aAttrSet.Put( pStyle->aAttrSet );
329 
330                         SfxItemIter aIter( pStyle->aAttrSet );
331                         SfxItemPool* pPool = pStyle->aAttrSet.GetPool();
332                         sal_uInt16 nWh = aIter.GetCurItem()->Which();
333                         while( sal_True )
334                         {
335                             pAkt->aAttrSet.Put( pPool->GetDefaultItem( nWh ));
336                             if( aIter.IsAtEnd() )
337                                 break;
338                             nWh = aIter.NextItem()->Which();
339                         }
340                     }
341 #endif
342                 }
343                 break;
344 
345             case RTF_KEEP:
346                 if( PARDID->nSplit )
347                 {
348                     pSet->Put( SvxFmtSplitItem( sal_False, PARDID->nSplit ));
349                 }
350                 break;
351 
352             case RTF_KEEPN:
353                 if( PARDID->nKeep )
354                 {
355                     pSet->Put( SvxFmtKeepItem( sal_True, PARDID->nKeep ));
356                 }
357                 break;
358 
359             case RTF_LEVEL:
360                 if( PARDID->nOutlineLvl )
361                 {
362                     pSet->Put( SfxUInt16Item( PARDID->nOutlineLvl,
363                                                 (sal_uInt16)nTokenValue ));
364                 }
365                 break;
366 
367             case RTF_QL:
368                 if( PARDID->nAdjust )
369                 {
370                     pSet->Put( SvxAdjustItem( SVX_ADJUST_LEFT, PARDID->nAdjust ));
371                 }
372                 break;
373             case RTF_QR:
374                 if( PARDID->nAdjust )
375                 {
376                     pSet->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, PARDID->nAdjust ));
377                 }
378                 break;
379             case RTF_QJ:
380                 if( PARDID->nAdjust )
381                 {
382                     pSet->Put( SvxAdjustItem( SVX_ADJUST_BLOCK, PARDID->nAdjust ));
383                 }
384                 break;
385             case RTF_QC:
386                 if( PARDID->nAdjust )
387                 {
388                     pSet->Put( SvxAdjustItem( SVX_ADJUST_CENTER, PARDID->nAdjust ));
389                 }
390                 break;
391 
392             case RTF_FI:
393                 if( PARDID->nLRSpace )
394                 {
395                     SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
396                     sal_uInt16 nSz = 0;
397                     if( -1 != nTokenValue )
398                     {
399                         if( IsCalcValue() )
400                             CalcValue();
401                         nSz = sal_uInt16(nTokenValue);
402                     }
403                     aLR.SetTxtFirstLineOfst( nSz );
404                     pSet->Put( aLR );
405                 }
406                 break;
407 
408             case RTF_LI:
409             case RTF_LIN:
410                 if( PARDID->nLRSpace )
411                 {
412                     SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
413                     sal_uInt16 nSz = 0;
414                     if( 0 < nTokenValue )
415                     {
416                         if( IsCalcValue() )
417                             CalcValue();
418                         nSz = sal_uInt16(nTokenValue);
419                     }
420                     aLR.SetTxtLeft( nSz );
421                     pSet->Put( aLR );
422                 }
423                 break;
424 
425             case RTF_RI:
426             case RTF_RIN:
427                 if( PARDID->nLRSpace )
428                 {
429                     SvxLRSpaceItem aLR( GetLRSpace(*pSet, PARDID->nLRSpace ));
430                     sal_uInt16 nSz = 0;
431                     if( 0 < nTokenValue )
432                     {
433                         if( IsCalcValue() )
434                             CalcValue();
435                         nSz = sal_uInt16(nTokenValue);
436                     }
437                     aLR.SetRight( nSz );
438                     pSet->Put( aLR );
439                 }
440                 break;
441 
442             case RTF_SB:
443                 if( PARDID->nULSpace )
444                 {
445                     SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
446                     sal_uInt16 nSz = 0;
447                     if( 0 < nTokenValue )
448                     {
449                         if( IsCalcValue() )
450                             CalcValue();
451                         nSz = sal_uInt16(nTokenValue);
452                     }
453                     aUL.SetUpper( nSz );
454                     pSet->Put( aUL );
455                 }
456                 break;
457 
458             case RTF_SA:
459                 if( PARDID->nULSpace )
460                 {
461                     SvxULSpaceItem aUL( GetULSpace(*pSet, PARDID->nULSpace ));
462                     sal_uInt16 nSz = 0;
463                     if( 0 < nTokenValue )
464                     {
465                         if( IsCalcValue() )
466                             CalcValue();
467                         nSz = sal_uInt16(nTokenValue);
468                     }
469                     aUL.SetLower( nSz );
470                     pSet->Put( aUL );
471                 }
472                 break;
473 
474             case RTF_SLMULT:
475                 if( PARDID->nLinespacing && 1 == nTokenValue )
476                 {
477                     // dann wird auf mehrzeilig umgeschaltet!
478                     SvxLineSpacingItem aLSpace( GetLineSpacing( *pSet,
479                                                 PARDID->nLinespacing, sal_False ));
480 
481                     // wieviel bekommt man aus dem LineHeight Wert heraus
482 
483                     // Proportionale-Groesse:
484                     // D.H. das Verhaeltnis ergibt sich aus ( n / 240 ) Twips
485 
486                     nTokenValue = 240;
487                     if( IsCalcValue() )
488                         CalcValue();
489 
490                     nTokenValue = short( 100L * aLSpace.GetLineHeight()
491                                             / long( nTokenValue ) );
492 
493                     if( nTokenValue > 200 )     // Datenwert fuer PropLnSp
494                         nTokenValue = 200;      // ist ein sal_uInt8 !!!
495 
496                     aLSpace.SetPropLineSpace( (const sal_uInt8)nTokenValue );
497                     aLSpace.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
498 
499                     pSet->Put( aLSpace );
500                 }
501                 break;
502 
503             case RTF_SL:
504                 if( PARDID->nLinespacing )
505                 {
506                     // errechne das Verhaeltnis aus dem default Font zu der
507                     // Size Angabe. Der Abstand besteht aus der Zeilenhoehe
508                     // (100%) und dem Leerraum ueber der Zeile (20%).
509                     SvxLineSpacingItem aLSpace(0, PARDID->nLinespacing);
510 
511                     nTokenValue = !bTokenHasValue ? 0 : nTokenValue;
512                     if (1000 == nTokenValue )
513                         nTokenValue = 240;
514 
515                     SvxLineSpace eLnSpc;
516                     if (nTokenValue < 0)
517                     {
518                         eLnSpc = SVX_LINE_SPACE_FIX;
519                         nTokenValue = -nTokenValue;
520                     }
521                     else if (nTokenValue == 0)
522                     {
523                         //if \sl0 is used, the line spacing is automatically
524                         //determined
525                         eLnSpc = SVX_LINE_SPACE_AUTO;
526                     }
527                     else
528                         eLnSpc = SVX_LINE_SPACE_MIN;
529 
530                     if (IsCalcValue())
531                         CalcValue();
532 
533                     if (eLnSpc != SVX_LINE_SPACE_AUTO)
534                         aLSpace.SetLineHeight( (const sal_uInt16)nTokenValue );
535 
536                     aLSpace.GetLineSpaceRule() = eLnSpc;
537                     pSet->Put(aLSpace);
538                 }
539                 break;
540 
541             case RTF_NOCWRAP:
542                 if( PARDID->nForbRule )
543                 {
544                     pSet->Put( SvxForbiddenRuleItem( sal_False,
545                                                     PARDID->nForbRule ));
546                 }
547                 break;
548             case RTF_NOOVERFLOW:
549                 if( PARDID->nHangPunct )
550                 {
551                     pSet->Put( SvxHangingPunctuationItem( sal_False,
552                                                     PARDID->nHangPunct ));
553                 }
554                 break;
555 
556             case RTF_ASPALPHA:
557                 if( PARDID->nScriptSpace )
558                 {
559                     pSet->Put( SvxScriptSpaceItem( sal_True,
560                                                 PARDID->nScriptSpace ));
561                 }
562                 break;
563 
564             case RTF_FAFIXED:
565             case RTF_FAAUTO:    nFontAlign = SvxParaVertAlignItem::AUTOMATIC;
566                                 goto SET_FONTALIGNMENT;
567             case RTF_FAHANG:    nFontAlign = SvxParaVertAlignItem::TOP;
568                                 goto SET_FONTALIGNMENT;
569             case RTF_FAVAR:     nFontAlign = SvxParaVertAlignItem::BOTTOM;
570                                 goto SET_FONTALIGNMENT;
571             case RTF_FACENTER:  nFontAlign = SvxParaVertAlignItem::CENTER;
572                                 goto SET_FONTALIGNMENT;
573             case RTF_FAROMAN:   nFontAlign = SvxParaVertAlignItem::BASELINE;
574                                 goto SET_FONTALIGNMENT;
575 SET_FONTALIGNMENT:
576             if( PARDID->nFontAlign )
577             {
578                 pSet->Put( SvxParaVertAlignItem( nFontAlign,
579                                                 PARDID->nFontAlign ));
580             }
581             break;
582 
583 /*  */
584             case RTF_B:
585             case RTF_AB:
586                 if( IsAttrSttPos() )    // nicht im Textfluss ?
587                 {
588 
589                     SvxWeightItem aTmpItem(
590                                     nTokenValue ? WEIGHT_BOLD : WEIGHT_NORMAL,
591                                     SID_ATTR_CHAR_WEIGHT );
592                     SetScriptAttr( eCharType, *pSet, aTmpItem);
593                 }
594                 break;
595 
596             case RTF_CAPS:
597             case RTF_SCAPS:
598                 if( PLAINID->nCaseMap &&
599                     IsAttrSttPos() )        // nicht im Textfluss ?
600                 {
601                     SvxCaseMap eCaseMap;
602                     if( !nTokenValue )
603                         eCaseMap = SVX_CASEMAP_NOT_MAPPED;
604                     else if( RTF_CAPS == nToken )
605                         eCaseMap = SVX_CASEMAP_VERSALIEN;
606                     else
607                         eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
608 
609                     pSet->Put( SvxCaseMapItem( eCaseMap, PLAINID->nCaseMap ));
610                 }
611                 break;
612 
613             case RTF_DN:
614             case RTF_SUB:
615                 if( PLAINID->nEscapement )
616                 {
617                     const sal_uInt16 nEsc = PLAINID->nEscapement;
618                     if( -1 == nTokenValue || RTF_SUB == nToken )
619                         nTokenValue = 6;
620                     if( IsCalcValue() )
621                         CalcValue();
622                     const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, sal_False );
623                     short nEs;
624                     sal_uInt8 nProp;
625                     if( DFLT_ESC_AUTO_SUPER == rOld.GetEsc() )
626                     {
627                         nEs = DFLT_ESC_AUTO_SUB;
628                         nProp = rOld.GetProp();
629                     }
630                     else
631                     {
632                         nEs = (short)-nTokenValue;
633                         nProp = (nToken == RTF_SUB) ? DFLT_ESC_PROP : 100;
634                     }
635                     pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
636                 }
637                 break;
638 
639             case RTF_NOSUPERSUB:
640                 if( PLAINID->nEscapement )
641                 {
642                     const sal_uInt16 nEsc = PLAINID->nEscapement;
643                     pSet->Put( SvxEscapementItem( nEsc ));
644                 }
645                 break;
646 
647             case RTF_EXPND:
648                 if( PLAINID->nKering )
649                 {
650                     if( -1 == nTokenValue )
651                         nTokenValue = 0;
652                     else
653                         nTokenValue *= 5;
654                     if( IsCalcValue() )
655                         CalcValue();
656                     pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
657                 }
658                 break;
659 
660             case RTF_KERNING:
661                 if( PLAINID->nAutoKerning )
662                 {
663                     if( -1 == nTokenValue )
664                         nTokenValue = 0;
665                     else
666                         nTokenValue *= 10;
667                     if( IsCalcValue() )
668                         CalcValue();
669                     pSet->Put( SvxAutoKernItem( 0 != nTokenValue,
670                                                 PLAINID->nAutoKerning ));
671                 }
672                 break;
673 
674             case RTF_EXPNDTW:
675                 if( PLAINID->nKering )
676                 {
677                     if( -1 == nTokenValue )
678                         nTokenValue = 0;
679                     if( IsCalcValue() )
680                         CalcValue();
681                     pSet->Put( SvxKerningItem( (short)nTokenValue, PLAINID->nKering ));
682                 }
683                 break;
684 
685             case RTF_F:
686             case RTF_AF:
687                 {
688                     const Font& rSVFont = GetFont( sal_uInt16(nTokenValue) );
689                     SvxFontItem aTmpItem( rSVFont.GetFamily(),
690                                     rSVFont.GetName(), rSVFont.GetStyleName(),
691                                     rSVFont.GetPitch(), rSVFont.GetCharSet(),
692                                     SID_ATTR_CHAR_FONT );
693                     SetScriptAttr( eCharType, *pSet, aTmpItem );
694                     if( RTF_F == nToken )
695                     {
696                         SetEncoding( rSVFont.GetCharSet() );
697                         RereadLookahead();
698                     }
699                 }
700                 break;
701 
702             case RTF_FS:
703             case RTF_AFS:
704                 {
705                     if( -1 == nTokenValue )
706                         nTokenValue = 240;
707                     else
708                         nTokenValue *= 10;
709 // #i66167#
710 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
711 // the converiosn takes now place in EditRTFParser since for other reasons
712 // the wrong MapUnit might still be use there
713 //                   if( IsCalcValue() )
714 //                       CalcValue();
715                     SvxFontHeightItem aTmpItem(
716                             (const sal_uInt16)nTokenValue, 100,
717                             SID_ATTR_CHAR_FONTHEIGHT );
718                     SetScriptAttr( eCharType, *pSet, aTmpItem );
719                 }
720                 break;
721 
722             case RTF_I:
723             case RTF_AI:
724                 if( IsAttrSttPos() )        // nicht im Textfluss ?
725                 {
726                     SvxPostureItem aTmpItem(
727                                     nTokenValue ? ITALIC_NORMAL : ITALIC_NONE,
728                                     SID_ATTR_CHAR_POSTURE );
729                     SetScriptAttr( eCharType, *pSet, aTmpItem );
730                 }
731                 break;
732 
733             case RTF_OUTL:
734                 if( PLAINID->nContour &&
735                     IsAttrSttPos() )        // nicht im Textfluss ?
736                 {
737                     pSet->Put( SvxContourItem( nTokenValue ? sal_True : sal_False,
738                                 PLAINID->nContour ));
739                 }
740                 break;
741 
742             case RTF_SHAD:
743                 if( PLAINID->nShadowed &&
744                     IsAttrSttPos() )        // nicht im Textfluss ?
745                 {
746                     pSet->Put( SvxShadowedItem( nTokenValue ? sal_True : sal_False,
747                                 PLAINID->nShadowed ));
748                 }
749                 break;
750 
751             case RTF_STRIKE:
752                 if( PLAINID->nCrossedOut &&
753                     IsAttrSttPos() )        // nicht im Textfluss ?
754                 {
755                     pSet->Put( SvxCrossedOutItem(
756                         nTokenValue ? STRIKEOUT_SINGLE : STRIKEOUT_NONE,
757                         PLAINID->nCrossedOut ));
758                 }
759                 break;
760 
761             case RTF_STRIKED:
762                 if( PLAINID->nCrossedOut )      // nicht im Textfluss ?
763                 {
764                     pSet->Put( SvxCrossedOutItem(
765                         nTokenValue ? STRIKEOUT_DOUBLE : STRIKEOUT_NONE,
766                         PLAINID->nCrossedOut ));
767                 }
768                 break;
769 
770             case RTF_UL:
771                 if( !IsAttrSttPos() )
772                     break;
773                 eUnderline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
774                 goto ATTR_SETUNDERLINE;
775 
776             case RTF_ULD:
777                 eUnderline = UNDERLINE_DOTTED;
778                 goto ATTR_SETUNDERLINE;
779             case RTF_ULDASH:
780                 eUnderline = UNDERLINE_DASH;
781                 goto ATTR_SETUNDERLINE;
782             case RTF_ULDASHD:
783                 eUnderline = UNDERLINE_DASHDOT;
784                 goto ATTR_SETUNDERLINE;
785             case RTF_ULDASHDD:
786                 eUnderline = UNDERLINE_DASHDOTDOT;
787                 goto ATTR_SETUNDERLINE;
788             case RTF_ULDB:
789                 eUnderline = UNDERLINE_DOUBLE;
790                 goto ATTR_SETUNDERLINE;
791             case RTF_ULNONE:
792                 eUnderline = UNDERLINE_NONE;
793                 goto ATTR_SETUNDERLINE;
794             case RTF_ULTH:
795                 eUnderline = UNDERLINE_BOLD;
796                 goto ATTR_SETUNDERLINE;
797             case RTF_ULWAVE:
798                 eUnderline = UNDERLINE_WAVE;
799                 goto ATTR_SETUNDERLINE;
800             case RTF_ULTHD:
801                 eUnderline = UNDERLINE_BOLDDOTTED;
802                 goto ATTR_SETUNDERLINE;
803             case RTF_ULTHDASH:
804                 eUnderline = UNDERLINE_BOLDDASH;
805                 goto ATTR_SETUNDERLINE;
806             case RTF_ULLDASH:
807                 eUnderline = UNDERLINE_LONGDASH;
808                 goto ATTR_SETUNDERLINE;
809             case RTF_ULTHLDASH:
810                 eUnderline = UNDERLINE_BOLDLONGDASH;
811                 goto ATTR_SETUNDERLINE;
812             case RTF_ULTHDASHD:
813                 eUnderline = UNDERLINE_BOLDDASHDOT;
814                 goto ATTR_SETUNDERLINE;
815             case RTF_ULTHDASHDD:
816                 eUnderline = UNDERLINE_BOLDDASHDOTDOT;
817                 goto ATTR_SETUNDERLINE;
818             case RTF_ULHWAVE:
819                 eUnderline = UNDERLINE_BOLDWAVE;
820                 goto ATTR_SETUNDERLINE;
821             case RTF_ULULDBWAVE:
822                 eUnderline = UNDERLINE_DOUBLEWAVE;
823                 goto ATTR_SETUNDERLINE;
824 
825             case RTF_ULW:
826                 eUnderline = UNDERLINE_SINGLE;
827 
828                 if( PLAINID->nWordlineMode )
829                 {
830                     pSet->Put( SvxWordLineModeItem( sal_True, PLAINID->nWordlineMode ));
831                 }
832                 goto ATTR_SETUNDERLINE;
833 
834 ATTR_SETUNDERLINE:
835                 if( PLAINID->nUnderline )
836                 {
837                     pSet->Put( SvxUnderlineItem( eUnderline, PLAINID->nUnderline ));
838                 }
839                 break;
840 
841             case RTF_ULC:
842                 if( PLAINID->nUnderline )
843                 {
844                     SvxUnderlineItem aUL( UNDERLINE_SINGLE, PLAINID->nUnderline );
845                     const SfxPoolItem* pItem;
846                     if( SFX_ITEM_SET == pSet->GetItemState(
847                         PLAINID->nUnderline, sal_False, &pItem ) )
848                     {
849                         // is switched off ?
850                         if( UNDERLINE_NONE ==
851                             ((SvxUnderlineItem*)pItem)->GetLineStyle() )
852                             break;
853                         aUL = *(SvxUnderlineItem*)pItem;
854                     }
855                     else
856                         aUL = (const SvxUnderlineItem&)pSet->Get( PLAINID->nUnderline, sal_False );
857 
858                     if( UNDERLINE_NONE == aUL.GetLineStyle() )
859                         aUL.SetLineStyle( UNDERLINE_SINGLE );
860                     aUL.SetColor( GetColor( sal_uInt16(nTokenValue) ));
861                     pSet->Put( aUL );
862                 }
863                 break;
864 
865             case RTF_OL:
866                 if( !IsAttrSttPos() )
867                     break;
868                 eOverline = nTokenValue ? UNDERLINE_SINGLE : UNDERLINE_NONE;
869                 goto ATTR_SETOVERLINE;
870 
871             case RTF_OLD:
872                 eOverline = UNDERLINE_DOTTED;
873                 goto ATTR_SETOVERLINE;
874             case RTF_OLDASH:
875                 eOverline = UNDERLINE_DASH;
876                 goto ATTR_SETOVERLINE;
877             case RTF_OLDASHD:
878                 eOverline = UNDERLINE_DASHDOT;
879                 goto ATTR_SETOVERLINE;
880             case RTF_OLDASHDD:
881                 eOverline = UNDERLINE_DASHDOTDOT;
882                 goto ATTR_SETOVERLINE;
883             case RTF_OLDB:
884                 eOverline = UNDERLINE_DOUBLE;
885                 goto ATTR_SETOVERLINE;
886             case RTF_OLNONE:
887                 eOverline = UNDERLINE_NONE;
888                 goto ATTR_SETOVERLINE;
889             case RTF_OLTH:
890                 eOverline = UNDERLINE_BOLD;
891                 goto ATTR_SETOVERLINE;
892             case RTF_OLWAVE:
893                 eOverline = UNDERLINE_WAVE;
894                 goto ATTR_SETOVERLINE;
895             case RTF_OLTHD:
896                 eOverline = UNDERLINE_BOLDDOTTED;
897                 goto ATTR_SETOVERLINE;
898             case RTF_OLTHDASH:
899                 eOverline = UNDERLINE_BOLDDASH;
900                 goto ATTR_SETOVERLINE;
901             case RTF_OLLDASH:
902                 eOverline = UNDERLINE_LONGDASH;
903                 goto ATTR_SETOVERLINE;
904             case RTF_OLTHLDASH:
905                 eOverline = UNDERLINE_BOLDLONGDASH;
906                 goto ATTR_SETOVERLINE;
907             case RTF_OLTHDASHD:
908                 eOverline = UNDERLINE_BOLDDASHDOT;
909                 goto ATTR_SETOVERLINE;
910             case RTF_OLTHDASHDD:
911                 eOverline = UNDERLINE_BOLDDASHDOTDOT;
912                 goto ATTR_SETOVERLINE;
913             case RTF_OLHWAVE:
914                 eOverline = UNDERLINE_BOLDWAVE;
915                 goto ATTR_SETOVERLINE;
916             case RTF_OLOLDBWAVE:
917                 eOverline = UNDERLINE_DOUBLEWAVE;
918                 goto ATTR_SETOVERLINE;
919 
920             case RTF_OLW:
921                 eOverline = UNDERLINE_SINGLE;
922 
923                 if( PLAINID->nWordlineMode )
924                 {
925                     pSet->Put( SvxWordLineModeItem( sal_True, PLAINID->nWordlineMode ));
926                 }
927                 goto ATTR_SETOVERLINE;
928 
929 ATTR_SETOVERLINE:
930                 if( PLAINID->nUnderline )
931                 {
932                     pSet->Put( SvxOverlineItem( eOverline, PLAINID->nOverline ));
933                 }
934                 break;
935 
936             case RTF_OLC:
937                 if( PLAINID->nOverline )
938                 {
939                     SvxOverlineItem aOL( UNDERLINE_SINGLE, PLAINID->nOverline );
940                     const SfxPoolItem* pItem;
941                     if( SFX_ITEM_SET == pSet->GetItemState(
942                         PLAINID->nOverline, sal_False, &pItem ) )
943                     {
944                         // is switched off ?
945                         if( UNDERLINE_NONE ==
946                             ((SvxOverlineItem*)pItem)->GetLineStyle() )
947                             break;
948                         aOL = *(SvxOverlineItem*)pItem;
949                     }
950                     else
951                         aOL = (const SvxOverlineItem&)pSet->Get( PLAINID->nUnderline, sal_False );
952 
953                     if( UNDERLINE_NONE == aOL.GetLineStyle() )
954                         aOL.SetLineStyle( UNDERLINE_SINGLE );
955                     aOL.SetColor( GetColor( sal_uInt16(nTokenValue) ));
956                     pSet->Put( aOL );
957                 }
958                 break;
959 
960             case RTF_UP:
961             case RTF_SUPER:
962                 if( PLAINID->nEscapement )
963                 {
964                     const sal_uInt16 nEsc = PLAINID->nEscapement;
965                     if( -1 == nTokenValue || RTF_SUPER == nToken )
966                         nTokenValue = 6;
967                     if( IsCalcValue() )
968                         CalcValue();
969                     const SvxEscapementItem& rOld = GetEscapement( *pSet, nEsc, sal_False );
970                     short nEs;
971                     sal_uInt8 nProp;
972                     if( DFLT_ESC_AUTO_SUB == rOld.GetEsc() )
973                     {
974                         nEs = DFLT_ESC_AUTO_SUPER;
975                         nProp = rOld.GetProp();
976                     }
977                     else
978                     {
979                         nEs = (short)nTokenValue;
980                         nProp = (nToken == RTF_SUPER) ? DFLT_ESC_PROP : 100;
981                     }
982                     pSet->Put( SvxEscapementItem( nEs, nProp, nEsc ));
983                 }
984                 break;
985 
986             case RTF_CF:
987                 if( PLAINID->nColor )
988                 {
989                     pSet->Put( SvxColorItem( GetColor( sal_uInt16(nTokenValue) ),
990                                 PLAINID->nColor ));
991                 }
992                 break;
993 #if 0
994             //#i12501# While cb is clearly documented in the rtf spec, word
995             //doesn't accept it at all
996             case RTF_CB:
997                 if( PLAINID->nBgColor )
998                 {
999                     pSet->Put( SvxBrushItem( GetColor( sal_uInt16(nTokenValue) ),
1000                                 PLAINID->nBgColor ));
1001                 }
1002                 break;
1003 #endif
1004             case RTF_LANG:
1005                 if( PLAINID->nLanguage )
1006                 {
1007                     pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
1008                                 PLAINID->nLanguage ));
1009                 }
1010                 break;
1011 
1012             case RTF_LANGFE:
1013                 if( PLAINID->nCJKLanguage )
1014                 {
1015                     pSet->Put( SvxLanguageItem( (LanguageType)nTokenValue,
1016                                                 PLAINID->nCJKLanguage ));
1017                 }
1018                 break;
1019             case RTF_ALANG:
1020                 {
1021                     SvxLanguageItem aTmpItem( (LanguageType)nTokenValue,
1022                                     SID_ATTR_CHAR_LANGUAGE );
1023                     SetScriptAttr( eCharType, *pSet, aTmpItem );
1024                 }
1025                 break;
1026 
1027             case RTF_RTLCH:
1028                 bIsLeftToRightDef = sal_False;
1029                 break;
1030             case RTF_LTRCH:
1031                 bIsLeftToRightDef = sal_True;
1032                 break;
1033             case RTF_RTLPAR:
1034                 if (PARDID->nDirection)
1035                 {
1036                     pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP,
1037                         PARDID->nDirection));
1038                 }
1039                 break;
1040             case RTF_LTRPAR:
1041                 if (PARDID->nDirection)
1042                 {
1043                     pSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP,
1044                         PARDID->nDirection));
1045                 }
1046                 break;
1047             case RTF_LOCH:      eCharType = LOW_CHARTYPE;           break;
1048             case RTF_HICH:      eCharType = HIGH_CHARTYPE;          break;
1049             case RTF_DBCH:      eCharType = DOUBLEBYTE_CHARTYPE;    break;
1050 
1051 
1052             case RTF_ACCNONE:
1053                 eEmphasis = EMPHASISMARK_NONE;
1054                 goto ATTR_SETEMPHASIS;
1055             case RTF_ACCDOT:
1056                 eEmphasis = EMPHASISMARK_DOTS_ABOVE;
1057                 goto ATTR_SETEMPHASIS;
1058 
1059             case RTF_ACCCOMMA:
1060                 eEmphasis = EMPHASISMARK_SIDE_DOTS;
1061 ATTR_SETEMPHASIS:
1062                 if( PLAINID->nEmphasis )
1063                 {
1064                     pSet->Put( SvxEmphasisMarkItem( eEmphasis,
1065                                                     PLAINID->nEmphasis ));
1066                 }
1067                 break;
1068 
1069             case RTF_TWOINONE:
1070                 if( PLAINID->nTwoLines )
1071                 {
1072                     sal_Unicode cStt, cEnd;
1073                     switch ( nTokenValue )
1074                     {
1075                     case 1: cStt = '(', cEnd = ')'; break;
1076                     case 2: cStt = '[', cEnd = ']'; break;
1077                     case 3: cStt = '<', cEnd = '>'; break;
1078                     case 4: cStt = '{', cEnd = '}'; break;
1079                     default: cStt = 0, cEnd = 0; break;
1080                     }
1081 
1082                     pSet->Put( SvxTwoLinesItem( sal_True, cStt, cEnd,
1083                                                     PLAINID->nTwoLines ));
1084                 }
1085                 break;
1086 
1087             case RTF_CHARSCALEX :
1088                 if (PLAINID->nCharScaleX)
1089                 {
1090                     //i21372
1091                     if (nTokenValue < 1 || nTokenValue > 600)
1092                         nTokenValue = 100;
1093                     pSet->Put( SvxCharScaleWidthItem( sal_uInt16(nTokenValue),
1094                                                     PLAINID->nCharScaleX ));
1095                 }
1096                 break;
1097 
1098             case RTF_HORZVERT:
1099                 if( PLAINID->nHorzVert )
1100                 {
1101                     // RTF knows only 90deg
1102                     pSet->Put( SvxCharRotateItem( 900, 1 == nTokenValue,
1103                                                     PLAINID->nHorzVert ));
1104                 }
1105                 break;
1106 
1107             case RTF_EMBO:
1108                 if (PLAINID->nRelief)
1109                 {
1110                     pSet->Put(SvxCharReliefItem(RELIEF_EMBOSSED,
1111                         PLAINID->nRelief));
1112                 }
1113                 break;
1114             case RTF_IMPR:
1115                 if (PLAINID->nRelief)
1116                 {
1117                     pSet->Put(SvxCharReliefItem(RELIEF_ENGRAVED,
1118                         PLAINID->nRelief));
1119                 }
1120                 break;
1121             case RTF_V:
1122                 if (PLAINID->nHidden)
1123                 {
1124                     pSet->Put(SvxCharHiddenItem(nTokenValue != 0,
1125                         PLAINID->nHidden));
1126                 }
1127                 break;
1128             case RTF_CHBGFDIAG:
1129             case RTF_CHBGDKVERT:
1130             case RTF_CHBGDKHORIZ:
1131             case RTF_CHBGVERT:
1132             case RTF_CHBGHORIZ:
1133             case RTF_CHBGDKFDIAG:
1134             case RTF_CHBGDCROSS:
1135             case RTF_CHBGCROSS:
1136             case RTF_CHBGBDIAG:
1137             case RTF_CHBGDKDCROSS:
1138             case RTF_CHBGDKCROSS:
1139             case RTF_CHBGDKBDIAG:
1140             case RTF_CHCBPAT:
1141             case RTF_CHCFPAT:
1142             case RTF_CHSHDNG:
1143                 if( PLAINID->nBgColor )
1144                     ReadBackgroundAttr( nToken, *pSet );
1145                 break;
1146 
1147 
1148 /*  */
1149 
1150             case BRACELEFT:
1151                 {
1152                     // teste auf Swg-Interne Tokens
1153                     bool bHandled = false;
1154                     short nSkip = 0;
1155                     if( RTF_IGNOREFLAG != GetNextToken())
1156                         nSkip = -1;
1157                     else if( (nToken = GetNextToken() ) & RTF_SWGDEFS )
1158                     {
1159                         bHandled = true;
1160                         switch( nToken )
1161                         {
1162                         case RTF_PGDSCNO:
1163                         case RTF_PGBRK:
1164                         case RTF_SOUTLVL:
1165                             UnknownAttrToken( nToken, pSet );
1166                             // ueberlese die schliessende Klammer
1167                             break;
1168 
1169                         case RTF_SWG_ESCPROP:
1170                             {
1171                                 // prozentuale Veraenderung speichern !
1172                                 sal_uInt8 nProp = sal_uInt8( nTokenValue / 100 );
1173                                 short nEsc = 0;
1174                                 if( 1 == ( nTokenValue % 100 ))
1175                                     // Erkennung unseres AutoFlags!
1176                                     nEsc = DFLT_ESC_AUTO_SUPER;
1177 
1178                                 if( PLAINID->nEscapement )
1179                                     pSet->Put( SvxEscapementItem( nEsc, nProp,
1180                                                     PLAINID->nEscapement ));
1181                             }
1182                             break;
1183 
1184                         case RTF_HYPHEN:
1185                             {
1186                                 SvxHyphenZoneItem aHypenZone(
1187                                             (nTokenValue & 1) ? sal_True : sal_False,
1188                                                 PARDID->nHyphenzone );
1189                                 aHypenZone.SetPageEnd(
1190                                             (nTokenValue & 2) ? sal_True : sal_False );
1191 
1192                                 if( PARDID->nHyphenzone &&
1193                                     RTF_HYPHLEAD == GetNextToken() &&
1194                                     RTF_HYPHTRAIL == GetNextToken() &&
1195                                     RTF_HYPHMAX == GetNextToken() )
1196                                 {
1197                                     aHypenZone.GetMinLead() =
1198                                         sal_uInt8(GetStackPtr( -2 )->nTokenValue);
1199                                     aHypenZone.GetMinTrail() =
1200                                             sal_uInt8(GetStackPtr( -1 )->nTokenValue);
1201                                     aHypenZone.GetMaxHyphens() =
1202                                             sal_uInt8(nTokenValue);
1203 
1204                                     pSet->Put( aHypenZone );
1205                                 }
1206                                 else
1207                                     SkipGroup();        // ans Ende der Gruppe
1208                             }
1209                             break;
1210 
1211                         case RTF_SHADOW:
1212                             {
1213                                 int bSkip = sal_True;
1214                                 do {    // middle check loop
1215                                     SvxShadowLocation eSL = SvxShadowLocation( nTokenValue );
1216                                     if( RTF_SHDW_DIST != GetNextToken() )
1217                                         break;
1218                                     sal_uInt16 nDist = sal_uInt16( nTokenValue );
1219 
1220                                     if( RTF_SHDW_STYLE != GetNextToken() )
1221                                         break;
1222                                     //! (pb) class Brush removed -> obsolete
1223                                     //! BrushStyle eStyle = BrushStyle( nTokenValue );
1224 
1225                                     if( RTF_SHDW_COL != GetNextToken() )
1226                                         break;
1227                                     sal_uInt16 nCol = sal_uInt16( nTokenValue );
1228 
1229                                     if( RTF_SHDW_FCOL != GetNextToken() )
1230                                         break;
1231 //                                  sal_uInt16 nFillCol = sal_uInt16( nTokenValue );
1232 
1233                                     Color aColor = GetColor( nCol );
1234 
1235                                     if( PARDID->nShadow )
1236                                         pSet->Put( SvxShadowItem( PARDID->nShadow,
1237                                                                   &aColor, nDist, eSL ) );
1238 
1239                                     bSkip = sal_False;
1240                                 } while( sal_False );
1241 
1242                                 if( bSkip )
1243                                     SkipGroup();        // ans Ende der Gruppe
1244                             }
1245                             break;
1246 
1247                         default:
1248                             bHandled = false;
1249                             if( (nToken & ~(0xff | RTF_SWGDEFS)) == RTF_TABSTOPDEF )
1250                             {
1251                                 nToken = SkipToken( -2 );
1252                                 ReadTabAttr( nToken, *pSet );
1253 
1254                                 /*
1255                                 cmc: #i76140, he who consumed the { must consume the }
1256                                 We rewound to a state of { being the current
1257                                 token so it is our responsibility to consume the }
1258                                 token if we consumed the {. We will not have consumed
1259                                 the { if it belonged to our caller, i.e. if the { we
1260                                 are handling is the "firsttoken" passed to us then
1261                                 the *caller* must consume it, not us. Otherwise *we*
1262                                 should consume it.
1263                                 */
1264                                 if (nToken == BRACELEFT && !bFirstToken)
1265                                 {
1266                                     nToken = GetNextToken();
1267                                     DBG_ASSERT( nToken == BRACERIGHT,
1268                                         "} did not follow { as expected\n");
1269                                 }
1270                             }
1271                             else if( (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF)
1272                             {
1273                                 nToken = SkipToken( -2 );
1274                                 ReadBorderAttr( nToken, *pSet );
1275                             }
1276                             else        // also kein Attribut mehr
1277                                 nSkip = -2;
1278                             break;
1279                         }
1280 
1281 #if 1
1282                         /*
1283                         cmc: #i4727# / #i12713# Who owns this closing bracket?
1284                         If we read the opening one, we must read this one, if
1285                         other is counting the brackets so as to push/pop off
1286                         the correct environment then we will have pushed a new
1287                         environment for the start { of this, but will not see
1288                         the } and so is out of sync for the rest of the
1289                         document.
1290                         */
1291                         if (bHandled && !bFirstToken)
1292                             GetNextToken();
1293 #endif
1294                     }
1295                     else
1296                         nSkip = -2;
1297 
1298                     if( nSkip )             // alles voellig unbekannt
1299                     {
1300                         if (!bFirstToken)
1301                             --nSkip;    // BRACELEFT: ist das naechste Token
1302                         SkipToken( nSkip );
1303                         bWeiter = sal_False;
1304                     }
1305                 }
1306                 break;
1307             default:
1308                 if( (nToken & ~0xff ) == RTF_TABSTOPDEF )
1309                     ReadTabAttr( nToken, *pSet );
1310                 else if( (nToken & ~0xff ) == RTF_BRDRDEF )
1311                     ReadBorderAttr( nToken, *pSet );
1312                 else if( (nToken & ~0xff ) == RTF_SHADINGDEF )
1313                     ReadBackgroundAttr( nToken, *pSet );
1314                 else
1315                 {
1316                     // kenne das Token nicht also das Token "in den Parser zurueck"
1317                     if( !bFirstToken )
1318                         SkipToken( -1 );
1319                     bWeiter = sal_False;
1320                 }
1321             }
1322         }
1323         if( bWeiter )
1324         {
1325             nToken = GetNextToken();
1326         }
1327         bFirstToken = sal_False;
1328     }
1329 
1330 /*
1331     // teste Attribute gegen ihre Styles
1332     if( IsChkStyleAttr() && pSet->Count() && !pInsPos->GetCntIdx() )
1333     {
1334         SvxRTFStyleType* pStyle = aStyleTbl.Get( nStyleNo );
1335         if( pStyle && pStyle->aAttrSet.Count() )
1336         {
1337             // alle Attribute, die schon vom Style definiert sind, aus dem
1338             // akt. Set entfernen
1339             const SfxPoolItem* pItem;
1340             SfxItemIter aIter( *pSet );
1341             sal_uInt16 nWhich = aIter.GetCurItem()->Which();
1342             while( sal_True )
1343             {
1344                 if( SFX_ITEM_SET == pStyle->aAttrSet.GetItemState(
1345                     nWhich, sal_False, &pItem ) && *pItem == *aIter.GetCurItem())
1346                     pSet->ClearItem( nWhich );      // loeschen
1347 
1348                 if( aIter.IsAtEnd() )
1349                     break;
1350                 nWhich = aIter.NextItem()->Which();
1351             }
1352         }
1353     }
1354 */
1355 }
1356 
1357 void SvxRTFParser::ReadTabAttr( int nToken, SfxItemSet& rSet )
1358 {
1359     bool bMethodOwnsToken = false; // #i52542# patch from cmc.
1360 // dann lese doch mal alle TabStops ein
1361     SvxTabStop aTabStop;
1362     SvxTabStopItem aAttr( 0, 0, SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
1363     int bWeiter = sal_True;
1364     do {
1365         switch( nToken )
1366         {
1367         case RTF_TB:        // BarTab ???
1368         case RTF_TX:
1369             {
1370                 if( IsCalcValue() )
1371                     CalcValue();
1372                 aTabStop.GetTabPos() = nTokenValue;
1373                 aAttr.Insert( aTabStop );
1374                 aTabStop = SvxTabStop();    // alle Werte default
1375             }
1376             break;
1377 
1378         case RTF_TQL:
1379             aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT;
1380             break;
1381         case RTF_TQR:
1382             aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT;
1383             break;
1384         case RTF_TQC:
1385             aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER;
1386             break;
1387         case RTF_TQDEC:
1388             aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL;
1389             break;
1390 
1391         case RTF_TLDOT:     aTabStop.GetFill() = '.';   break;
1392         case RTF_TLHYPH:    aTabStop.GetFill() = ' ';   break;
1393         case RTF_TLUL:      aTabStop.GetFill() = '_';   break;
1394         case RTF_TLTH:      aTabStop.GetFill() = '-';   break;
1395         case RTF_TLEQ:      aTabStop.GetFill() = '=';   break;
1396 
1397         case BRACELEFT:
1398             {
1399                 // Swg - Kontrol BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1400                 short nSkip = 0;
1401                 if( RTF_IGNOREFLAG != GetNextToken() )
1402                     nSkip = -1;
1403                 else if( RTF_TLSWG != ( nToken = GetNextToken() ))
1404                     nSkip = -2;
1405                 else
1406                 {
1407                     aTabStop.GetDecimal() = sal_uInt8(nTokenValue & 0xff);
1408                     aTabStop.GetFill() = sal_uInt8((nTokenValue >> 8) & 0xff);
1409                     // ueberlese noch die schliessende Klammer
1410                     if (bMethodOwnsToken)
1411                         GetNextToken();
1412                 }
1413                 if( nSkip )
1414                 {
1415                     SkipToken( nSkip );     // Ignore wieder zurueck
1416                     bWeiter = sal_False;
1417                 }
1418             }
1419             break;
1420 
1421         default:
1422             bWeiter = sal_False;
1423         }
1424         if( bWeiter )
1425         {
1426             nToken = GetNextToken();
1427             bMethodOwnsToken = true;
1428         }
1429     } while( bWeiter );
1430 
1431     // mit Defaults aufuellen fehlt noch !!!
1432     rSet.Put( aAttr );
1433     SkipToken( -1 );
1434 }
1435 
1436 static void SetBorderLine( int nBorderTyp, SvxBoxItem& rItem,
1437                             const SvxBorderLine& rBorder )
1438 {
1439     switch( nBorderTyp )
1440     {
1441     case RTF_BOX:           // alle Stufen durchlaufen
1442 
1443     case RTF_BRDRT:
1444         rItem.SetLine( &rBorder, BOX_LINE_TOP );
1445         if( RTF_BOX != nBorderTyp )
1446             return;
1447 
1448     case RTF_BRDRB:
1449         rItem.SetLine( &rBorder, BOX_LINE_BOTTOM );
1450         if( RTF_BOX != nBorderTyp )
1451             return;
1452 
1453     case RTF_BRDRL:
1454         rItem.SetLine( &rBorder, BOX_LINE_LEFT );
1455         if( RTF_BOX != nBorderTyp )
1456             return;
1457 
1458     case RTF_BRDRR:
1459         rItem.SetLine( &rBorder, BOX_LINE_RIGHT );
1460         if( RTF_BOX != nBorderTyp )
1461             return;
1462     }
1463 }
1464 
1465 void SvxRTFParser::ReadBorderAttr( int nToken, SfxItemSet& rSet,
1466                                     int bTableDef )
1467 {
1468     // dann lese doch mal das BoderAttribut ein
1469     SvxBoxItem aAttr( PARDID->nBox );
1470     const SfxPoolItem* pItem;
1471     if( SFX_ITEM_SET == rSet.GetItemState( PARDID->nBox, sal_False, &pItem ) )
1472         aAttr = *(SvxBoxItem*)pItem;
1473 
1474     SvxBorderLine aBrd( 0, DEF_LINE_WIDTH_0, 0, 0 );    // einfache Linien
1475     int bWeiter = sal_True, nBorderTyp = 0;
1476 
1477     do {
1478         switch( nToken )
1479         {
1480         case RTF_BOX:
1481         case RTF_BRDRT:
1482         case RTF_BRDRB:
1483         case RTF_BRDRL:
1484         case RTF_BRDRR:
1485             nBorderTyp = nToken;
1486             goto SETBORDER;
1487 
1488         case RTF_CLBRDRT:
1489             if( !bTableDef )
1490                 break;
1491             nBorderTyp = RTF_BRDRT;
1492             goto SETBORDER;
1493         case RTF_CLBRDRB:
1494             if( !bTableDef )
1495                 break;
1496             nBorderTyp = RTF_BRDRB;
1497             goto SETBORDER;
1498         case RTF_CLBRDRL:
1499             if( !bTableDef )
1500                 break;
1501             nBorderTyp = RTF_BRDRL;
1502             goto SETBORDER;
1503         case RTF_CLBRDRR:
1504             if( !bTableDef )
1505                 break;
1506             nBorderTyp = RTF_BRDRR;
1507             goto SETBORDER;
1508 
1509 SETBORDER:
1510             {
1511                 // auf defaults setzen
1512                 aBrd.SetOutWidth( DEF_LINE_WIDTH_0 );
1513                 aBrd.SetInWidth( 0 );
1514                 aBrd.SetDistance( 0 );
1515                 aBrd.SetColor( Color( COL_BLACK ) );
1516             }
1517             break;
1518 
1519 
1520 // werden noch nicht ausgewertet
1521         case RTF_BRSP:
1522             {
1523                 switch( nBorderTyp )
1524                 {
1525                 case RTF_BRDRB:
1526                     aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_BOTTOM );
1527                     break;
1528 
1529                 case RTF_BRDRT:
1530                     aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_TOP );
1531                     break;
1532 
1533                 case RTF_BRDRL:
1534                     aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_LEFT );
1535                     break;
1536 
1537                 case RTF_BRDRR:
1538                     aAttr.SetDistance( (sal_uInt16)nTokenValue, BOX_LINE_RIGHT );
1539                     break;
1540 
1541                 case RTF_BOX:
1542                     aAttr.SetDistance( (sal_uInt16)nTokenValue );
1543                     break;
1544                 }
1545             }
1546             break;
1547 
1548 case RTF_BRDRBTW:
1549 case RTF_BRDRBAR:           break;
1550 
1551 
1552         case RTF_BRDRCF:
1553             {
1554                 aBrd.SetColor( GetColor( sal_uInt16(nTokenValue) ) );
1555                 SetBorderLine( nBorderTyp, aAttr, aBrd );
1556             }
1557             break;
1558 
1559         case RTF_BRDRTH:
1560             aBrd.SetOutWidth( DEF_LINE_WIDTH_1 );
1561             aBrd.SetInWidth( 0 );
1562             aBrd.SetDistance( 0 );
1563             goto SETBORDERLINE;
1564 
1565         case RTF_BRDRDB:
1566             aBrd.SetOutWidth( DEF_DOUBLE_LINE0_OUT );
1567             aBrd.SetInWidth( DEF_DOUBLE_LINE0_IN );
1568             aBrd.SetDistance( DEF_DOUBLE_LINE0_DIST );
1569             goto SETBORDERLINE;
1570 
1571         case RTF_BRDRSH:
1572             // schattierte Box
1573             {
1574                 rSet.Put( SvxShadowItem( PARDID->nShadow, (Color*) 0, 60 /*3pt*/,
1575                                         SVX_SHADOW_BOTTOMRIGHT ) );
1576             }
1577             break;
1578 
1579         case RTF_BRDRW:
1580             if( -1 != nTokenValue )
1581             {
1582                 // sollte es eine "dicke" Linie sein ?
1583                 if( DEF_LINE_WIDTH_0 != aBrd.GetOutWidth() )
1584                     nTokenValue *= 2;
1585 
1586                 // eine Doppelline?
1587                 if( aBrd.GetInWidth() )
1588                 {
1589                     // WinWord - Werte an StarOffice anpassen
1590                     if( nTokenValue < DEF_LINE_WIDTH_1 - (DEF_LINE_WIDTH_1/10))
1591                     {
1592                         aBrd.SetOutWidth( DEF_DOUBLE_LINE0_OUT );
1593                         aBrd.SetInWidth( DEF_DOUBLE_LINE0_IN );
1594                         aBrd.SetDistance( DEF_DOUBLE_LINE0_DIST );
1595                     }
1596                     else
1597                     if( nTokenValue < DEF_LINE_WIDTH_2 - (DEF_LINE_WIDTH_2/10))
1598                     {
1599                         aBrd.SetOutWidth( DEF_DOUBLE_LINE1_OUT );
1600                         aBrd.SetInWidth( DEF_DOUBLE_LINE1_IN );
1601                         aBrd.SetDistance( DEF_DOUBLE_LINE1_DIST );
1602                     }
1603                     else
1604                     {
1605                         aBrd.SetOutWidth( DEF_DOUBLE_LINE2_OUT );
1606                         aBrd.SetInWidth( DEF_DOUBLE_LINE2_IN );
1607                         aBrd.SetDistance( DEF_DOUBLE_LINE2_DIST );
1608                     }
1609                 }
1610                 else
1611                 {
1612                     // WinWord - Werte an StarOffice anpassen
1613                     if( nTokenValue < DEF_LINE_WIDTH_1 - (DEF_LINE_WIDTH_1/10))
1614                         aBrd.SetOutWidth( DEF_LINE_WIDTH_0 );
1615                     else
1616                     if( nTokenValue < DEF_LINE_WIDTH_2 - (DEF_LINE_WIDTH_2/10))
1617                         aBrd.SetOutWidth( DEF_LINE_WIDTH_1 );
1618                     else
1619                     if( nTokenValue < DEF_LINE_WIDTH_3 - (DEF_LINE_WIDTH_3/10))
1620                         aBrd.SetOutWidth( DEF_LINE_WIDTH_2 );
1621                     else
1622                     if( nTokenValue < DEF_LINE_WIDTH_4 )
1623                         aBrd.SetOutWidth( DEF_LINE_WIDTH_3 );
1624                     else
1625                         aBrd.SetOutWidth( DEF_LINE_WIDTH_4 );
1626                 }
1627             }
1628             goto SETBORDERLINE;
1629 
1630         case RTF_BRDRS:
1631         case RTF_BRDRDOT:
1632         case RTF_BRDRHAIR:
1633         case RTF_BRDRDASH:
1634 SETBORDERLINE:
1635             SetBorderLine( nBorderTyp, aAttr, aBrd );
1636             break;
1637 
1638         case BRACELEFT:
1639             {
1640                 short nSkip = 0;
1641                 if( RTF_IGNOREFLAG != GetNextToken() )
1642                     nSkip = -1;
1643                 else
1644                 {
1645                     int bSwgControl = sal_True, bFirstToken = sal_True;
1646                     nToken = GetNextToken();
1647                     do {
1648                         switch( nToken )
1649                         {
1650                         case RTF_BRDBOX:
1651                             aAttr.SetDistance( sal_uInt16(nTokenValue) );
1652                             break;
1653 
1654                         case RTF_BRDRT:
1655                         case RTF_BRDRB:
1656                         case RTF_BRDRR:
1657                         case RTF_BRDRL:
1658                             nBorderTyp = nToken;
1659                             bFirstToken = sal_False;
1660                             if( RTF_BRDLINE_COL != GetNextToken() )
1661                             {
1662                                 bSwgControl = sal_False;
1663                                 break;
1664                             }
1665                             aBrd.SetColor( GetColor( sal_uInt16(nTokenValue) ));
1666 
1667                             if( RTF_BRDLINE_IN != GetNextToken() )
1668                             {
1669                                 bSwgControl = sal_False;
1670                                 break;
1671                             }
1672                             aBrd.SetInWidth( sal_uInt16(nTokenValue));
1673 
1674                             if( RTF_BRDLINE_OUT != GetNextToken() )
1675                             {
1676                                 bSwgControl = sal_False;
1677                                 break;
1678                             }
1679                             aBrd.SetOutWidth( sal_uInt16(nTokenValue));
1680 
1681                             if( RTF_BRDLINE_DIST != GetNextToken() )
1682                             {
1683                                 bSwgControl = sal_False;
1684                                 break;
1685                             }
1686                             aBrd.SetDistance( sal_uInt16(nTokenValue));
1687                             SetBorderLine( nBorderTyp, aAttr, aBrd );
1688                             break;
1689 
1690                         default:
1691                             bSwgControl = sal_False;
1692                             break;
1693                         }
1694 
1695                         if( bSwgControl )
1696                         {
1697                             nToken = GetNextToken();
1698                             bFirstToken = sal_False;
1699                         }
1700                     } while( bSwgControl );
1701 
1702                     // Ende der Swg-Gruppe
1703                     // -> lese noch die schliessende Klammer
1704                     if( BRACERIGHT == nToken )
1705                         ;
1706                     else if( !bFirstToken )
1707                     {
1708                         // es ist ein Parser-Fehler, springe zum
1709                         // Ende der Gruppe
1710                         SkipGroup();
1711                         // schliessende BRACERIGHT ueberspringen
1712                         GetNextToken();
1713                     }
1714                     else
1715                         nSkip = -2;
1716                 }
1717 
1718                 if( nSkip )
1719                 {
1720                     SkipToken( nSkip );     // Ignore wieder zurueck
1721                     bWeiter = sal_False;
1722                 }
1723             }
1724             break;
1725 
1726         default:
1727             bWeiter = (nToken & ~(0xff| RTF_SWGDEFS)) == RTF_BRDRDEF;
1728         }
1729         if( bWeiter )
1730             nToken = GetNextToken();
1731     } while( bWeiter );
1732     rSet.Put( aAttr );
1733     SkipToken( -1 );
1734 }
1735 
1736 inline sal_uInt32 CalcShading( sal_uInt32 nColor, sal_uInt32 nFillColor, sal_uInt8 nShading )
1737 {
1738     nColor = (nColor * nShading) / 100;
1739     nFillColor = (nFillColor * ( 100 - nShading )) / 100;
1740     return nColor + nFillColor;
1741 }
1742 
1743 void SvxRTFParser::ReadBackgroundAttr( int nToken, SfxItemSet& rSet,
1744                                         int bTableDef )
1745 {
1746     // dann lese doch mal das BoderAttribut ein
1747     int bWeiter = sal_True;
1748     sal_uInt16 nColor = USHRT_MAX, nFillColor = USHRT_MAX;
1749     sal_uInt8 nFillValue = 0;
1750 
1751     sal_uInt16 nWh = ( nToken & ~0xff ) == RTF_CHRFMT
1752                     ? PLAINID->nBgColor
1753                     : PARDID->nBrush;
1754 
1755     do {
1756         switch( nToken )
1757         {
1758         case RTF_CLCBPAT:
1759         case RTF_CHCBPAT:
1760         case RTF_CBPAT:
1761             nFillColor = sal_uInt16( nTokenValue );
1762             break;
1763 
1764         case RTF_CLCFPAT:
1765         case RTF_CHCFPAT:
1766         case RTF_CFPAT:
1767             nColor = sal_uInt16( nTokenValue );
1768             break;
1769 
1770         case RTF_CLSHDNG:
1771         case RTF_CHSHDNG:
1772         case RTF_SHADING:
1773             nFillValue = (sal_uInt8)( nTokenValue / 100 );
1774             break;
1775 
1776         case RTF_CLBGDKHOR:
1777         case RTF_CHBGDKHORIZ:
1778         case RTF_BGDKHORIZ:
1779         case RTF_CLBGDKVERT:
1780         case RTF_CHBGDKVERT:
1781         case RTF_BGDKVERT:
1782         case RTF_CLBGDKBDIAG:
1783         case RTF_CHBGDKBDIAG:
1784         case RTF_BGDKBDIAG:
1785         case RTF_CLBGDKFDIAG:
1786         case RTF_CHBGDKFDIAG:
1787         case RTF_BGDKFDIAG:
1788         case RTF_CLBGDKCROSS:
1789         case RTF_CHBGDKCROSS:
1790         case RTF_BGDKCROSS:
1791         case RTF_CLBGDKDCROSS:
1792         case RTF_CHBGDKDCROSS:
1793         case RTF_BGDKDCROSS:
1794             // dark -> 60%
1795             nFillValue = 60;
1796             break;
1797 
1798         case RTF_CLBGHORIZ:
1799         case RTF_CHBGHORIZ:
1800         case RTF_BGHORIZ:
1801         case RTF_CLBGVERT:
1802         case RTF_CHBGVERT:
1803         case RTF_BGVERT:
1804         case RTF_CLBGBDIAG:
1805         case RTF_CHBGBDIAG:
1806         case RTF_BGBDIAG:
1807         case RTF_CLBGFDIAG:
1808         case RTF_CHBGFDIAG:
1809         case RTF_BGFDIAG:
1810         case RTF_CLBGCROSS:
1811         case RTF_CHBGCROSS:
1812         case RTF_BGCROSS:
1813         case RTF_CLBGDCROSS:
1814         case RTF_CHBGDCROSS:
1815         case RTF_BGDCROSS:
1816             // light -> 20%
1817             nFillValue = 20;
1818             break;
1819 
1820         default:
1821             if( bTableDef )
1822                 bWeiter = (nToken & ~(0xff | RTF_TABLEDEF) ) == RTF_SHADINGDEF;
1823             else
1824                 bWeiter = (nToken & ~0xff) == RTF_SHADINGDEF;
1825         }
1826         if( bWeiter )
1827             nToken = GetNextToken();
1828     } while( bWeiter );
1829 
1830     Color aCol( COL_WHITE ), aFCol;
1831     if( !nFillValue )
1832     {
1833         // es wurde nur eine von beiden Farben angegeben oder kein BrushTyp
1834         if( USHRT_MAX != nFillColor )
1835         {
1836             nFillValue = 100;
1837             aCol = GetColor( nFillColor );
1838         }
1839         else if( USHRT_MAX != nColor )
1840             aFCol = GetColor( nColor );
1841     }
1842     else
1843     {
1844         if( USHRT_MAX != nColor )
1845             aCol = GetColor( nColor );
1846         else
1847             aCol = Color( COL_BLACK );
1848 
1849         if( USHRT_MAX != nFillColor )
1850             aFCol = GetColor( nFillColor );
1851         else
1852             aFCol = Color( COL_WHITE );
1853     }
1854 
1855     Color aColor;
1856     if( 0 == nFillValue || 100 == nFillValue )
1857         aColor = aCol;
1858     else
1859         aColor = Color(
1860             (sal_uInt8)CalcShading( aCol.GetRed(), aFCol.GetRed(), nFillValue ),
1861             (sal_uInt8)CalcShading( aCol.GetGreen(), aFCol.GetGreen(), nFillValue ),
1862             (sal_uInt8)CalcShading( aCol.GetBlue(), aFCol.GetBlue(), nFillValue ) );
1863 
1864     rSet.Put( SvxBrushItem( aColor, nWh ) );
1865     SkipToken( -1 );
1866 }
1867 
1868 
1869 // pard / plain abarbeiten
1870 void SvxRTFParser::RTFPardPlain( int bPard, SfxItemSet** ppSet )
1871 {
1872     if( !bNewGroup && !aAttrStack.empty() ) // not at the beginning of a new group
1873     {
1874         SvxRTFItemStackType* pAkt = aAttrStack.back();
1875 
1876         int nLastToken = GetStackPtr(-1)->nTokenId;
1877         int bNewStkEntry = sal_True;
1878         if( RTF_PARD != nLastToken &&
1879             RTF_PLAIN != nLastToken &&
1880             BRACELEFT != nLastToken )
1881         {
1882             if( pAkt->aAttrSet.Count() || pAkt->pChildList || pAkt->nStyleNo )
1883             {
1884                 // eine neue Gruppe aufmachen
1885                 SvxRTFItemStackType* pNew = new SvxRTFItemStackType( *pAkt, *pInsPos, sal_True );
1886                 pNew->SetRTFDefaults( GetRTFDefaults() );
1887 
1888                 // alle bis hierher gueltigen Attribute "setzen"
1889                 AttrGroupEnd();
1890                 pAkt = aAttrStack.empty() ? 0 : aAttrStack.back();  // can be changed after AttrGroupEnd!
1891                 pNew->aAttrSet.SetParent( pAkt ? &pAkt->aAttrSet : 0 );
1892                 aAttrStack.push_back( pNew );
1893                 pAkt = pNew;
1894             }
1895             else
1896             {
1897                 // diesen Eintrag als neuen weiterbenutzen
1898                 pAkt->SetStartPos( *pInsPos );
1899                 bNewStkEntry = sal_False;
1900             }
1901         }
1902 
1903         // jetzt noch alle auf default zuruecksetzen
1904         if( bNewStkEntry &&
1905             ( pAkt->aAttrSet.GetParent() || pAkt->aAttrSet.Count() ))
1906         {
1907             const SfxPoolItem *pItem, *pDef;
1908             const sal_uInt16* pPtr;
1909             sal_uInt16 nCnt;
1910             const SfxItemSet* pDfltSet = &GetRTFDefaults();
1911             if( bPard )
1912             {
1913                 pAkt->nStyleNo = 0;
1914                 pPtr = aPardMap.GetData();
1915                 nCnt = aPardMap.Count();
1916             }
1917             else
1918             {
1919                 pPtr = aPlainMap.GetData();
1920                 nCnt = aPlainMap.Count();
1921             }
1922 
1923             for( sal_uInt16 n = 0; n < nCnt; ++n, ++pPtr )
1924             {
1925                 // Item gesetzt und unterschiedlich -> das Pooldefault setzen
1926                 //JP 06.04.98: bei Items die nur SlotItems sind, darf nicht
1927                 //              auf das Default zugefriffen werden. Diese
1928                 //              werden gecleart
1929                 if( !*pPtr )
1930                     ;
1931                 else if( SFX_WHICH_MAX < *pPtr )
1932                     pAkt->aAttrSet.ClearItem( *pPtr );
1933                 else if( IsChkStyleAttr() )
1934                     pAkt->aAttrSet.Put( pDfltSet->Get( *pPtr ) );
1935                 else if( !pAkt->aAttrSet.GetParent() )
1936                 {
1937                     if( SFX_ITEM_SET ==
1938                         pDfltSet->GetItemState( *pPtr, sal_False, &pDef ))
1939                         pAkt->aAttrSet.Put( *pDef );
1940                     else
1941                         pAkt->aAttrSet.ClearItem( *pPtr );
1942                 }
1943                 else if( SFX_ITEM_SET == pAkt->aAttrSet.GetParent()->
1944                             GetItemState( *pPtr, sal_True, &pItem ) &&
1945                         *( pDef = &pDfltSet->Get( *pPtr )) != *pItem )
1946                     pAkt->aAttrSet.Put( *pDef );
1947                 else
1948                 {
1949                     if( SFX_ITEM_SET ==
1950                         pDfltSet->GetItemState( *pPtr, sal_False, &pDef ))
1951                         pAkt->aAttrSet.Put( *pDef );
1952                     else
1953                         pAkt->aAttrSet.ClearItem( *pPtr );
1954                 }
1955             }
1956         }
1957         else if( bPard )
1958             pAkt->nStyleNo = 0;     // Style-Nummer zuruecksetzen
1959 
1960         *ppSet = &pAkt->aAttrSet;
1961 
1962         if (!bPard)
1963         {
1964             //Once we have a default font, then any text without a font specifier is
1965             //in the default font, and thus has the default font charset, otherwise
1966             //we can fall back to the ansicpg set codeset
1967             if (nDfltFont != -1)
1968             {
1969                 const Font& rSVFont = GetFont(sal_uInt16(nDfltFont));
1970                 SetEncoding(rSVFont.GetCharSet());
1971             }
1972             else
1973                 SetEncoding(GetCodeSet());
1974         }
1975     }
1976 }
1977 
1978 void SvxRTFParser::SetDefault( int nToken, int nValue )
1979 {
1980     if( !bNewDoc )
1981         return;
1982 
1983     SfxItemSet aTmp( *pAttrPool, aWhichMap.GetData() );
1984     sal_Bool bOldFlag = bIsLeftToRightDef;
1985     bIsLeftToRightDef = sal_True;
1986     switch( nToken )
1987     {
1988     case RTF_ADEFF: bIsLeftToRightDef = sal_False;  // no break!
1989     case RTF_DEFF:
1990         {
1991             if( -1 == nValue )
1992                 nValue = 0;
1993             const Font& rSVFont = GetFont( sal_uInt16(nValue) );
1994             SvxFontItem aTmpItem(
1995                                 rSVFont.GetFamily(), rSVFont.GetName(),
1996                                 rSVFont.GetStyleName(), rSVFont.GetPitch(),
1997                                 rSVFont.GetCharSet(), SID_ATTR_CHAR_FONT );
1998             SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
1999         }
2000         break;
2001 
2002     case RTF_ADEFLANG:  bIsLeftToRightDef = sal_False;  // no break!
2003     case RTF_DEFLANG:
2004         // default Language merken
2005         if( -1 != nValue )
2006         {
2007             SvxLanguageItem aTmpItem( (const LanguageType)nValue,
2008                                         SID_ATTR_CHAR_LANGUAGE );
2009             SetScriptAttr( NOTDEF_CHARTYPE, aTmp, aTmpItem );
2010         }
2011         break;
2012 
2013     case RTF_DEFTAB:
2014         if( PARDID->nTabStop )
2015         {
2016             // RTF definiert 720 twips als default
2017             bIsSetDfltTab = sal_True;
2018             if( -1 == nValue || !nValue )
2019                 nValue = 720;
2020 
2021             // wer keine Twips haben moechte ...
2022             if( IsCalcValue() )
2023             {
2024                 nTokenValue = nValue;
2025                 CalcValue();
2026                 nValue = nTokenValue;
2027             }
2028 #if 1
2029             /*
2030             cmc:
2031              This stuff looks a little hairy indeed, this should be totally
2032              unnecessary where default tabstops are understood. Just make one
2033              tabstop and stick the value in there, the first one is all that
2034              matters.
2035 
2036              e.g.
2037 
2038             SvxTabStopItem aNewTab(1, sal_uInt16(nValue), SVX_TAB_ADJUST_DEFAULT,
2039                 PARDID->nTabStop);
2040             ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
2041 
2042 
2043              It must exist as a foul hack to support somebody that does not
2044              have a true concept of default tabstops by making a tabsetting
2045              result from the default tabstop, creating a lot of them all at
2046              the default locations to give the effect of the first real
2047              default tabstop being in use just in case the receiving
2048              application doesn't do that for itself.
2049              */
2050 #endif
2051 
2052             // Verhaeltnis der def. TabWidth / Tabs errechnen und
2053             // enstsprechend die neue Anzahl errechnen.
2054 /*-----------------14.12.94 19:32-------------------
2055  ?? wie kommt man auf die 13 ??
2056 --------------------------------------------------*/
2057             sal_uInt16 nAnzTabs = (SVX_TAB_DEFDIST * 13 ) / sal_uInt16(nValue);
2058             /*
2059              cmc, make sure we have at least one, or all hell breaks loose in
2060              everybodies exporters, #i8247#
2061             */
2062             if (nAnzTabs < 1)
2063                 nAnzTabs = 1;
2064 
2065             // wir wollen Defaulttabs
2066             SvxTabStopItem aNewTab( nAnzTabs, sal_uInt16(nValue),
2067                                 SVX_TAB_ADJUST_DEFAULT, PARDID->nTabStop );
2068             while( nAnzTabs )
2069                 ((SvxTabStop&)aNewTab[ --nAnzTabs ]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
2070 
2071             pAttrPool->SetPoolDefaultItem( aNewTab );
2072         }
2073         break;
2074     }
2075     bIsLeftToRightDef = bOldFlag;
2076 
2077     if( aTmp.Count() )
2078     {
2079         SfxItemIter aIter( aTmp );
2080         const SfxPoolItem* pItem = aIter.GetCurItem();
2081         while( sal_True )
2082         {
2083             pAttrPool->SetPoolDefaultItem( *pItem );
2084             if( aIter.IsAtEnd() )
2085                 break;
2086             pItem = aIter.NextItem();
2087         }
2088     }
2089 }
2090 
2091 // default: keine Umrechnung, alles bei Twips lassen.
2092 void SvxRTFParser::CalcValue()
2093 {
2094 }
2095 
2096     // fuer Tokens, die im ReadAttr nicht ausgewertet werden
2097 void SvxRTFParser::UnknownAttrToken( int, SfxItemSet* )
2098 {
2099 }
2100 
2101 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
2102