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