xref: /aoo41x/main/editeng/source/rtf/rtfitem.cxx (revision cdf0e10c)
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