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