1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <editeng/flstitem.hxx>
22 #include <editeng/fontitem.hxx>
23 #include <editeng/postitem.hxx>
24 #include <editeng/wghtitem.hxx>
25 #include <editeng/fhgtitem.hxx>
26 #include <editeng/fwdtitem.hxx>
27 #include <editeng/udlnitem.hxx>
28 #include <editeng/crossedoutitem.hxx>
29 #include <editeng/shdditem.hxx>
30 #include <editeng/autokernitem.hxx>
31 #include <editeng/wrlmitem.hxx>
32 #include <editeng/contouritem.hxx>
33 #include <editeng/prszitem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/charsetcoloritem.hxx>
36 #include <editeng/kernitem.hxx>
37 #include <editeng/cmapitem.hxx>
38 #include <editeng/escapementitem.hxx>
39 #include <editeng/langitem.hxx>
40 #include <editeng/nlbkitem.hxx>
41 #include <editeng/nhypitem.hxx>
42 #include <editeng/lcolitem.hxx>
43 #include <editeng/blinkitem.hxx>
44 #include <editeng/emphasismarkitem.hxx>
45 #include <editeng/twolinesitem.hxx>
46 #include <editeng/pbinitem.hxx>
47 #include <editeng/sizeitem.hxx>
48 #include <editeng/lrspitem.hxx>
49 #include <editeng/ulspitem.hxx>
50 #include <editeng/prntitem.hxx>
51 #include <editeng/opaqitem.hxx>
52 #include <editeng/protitem.hxx>
53 #include <editeng/shaditem.hxx>
54 #include <editeng/boxitem.hxx>
55 #include <editeng/formatbreakitem.hxx>
56 #include <editeng/keepitem.hxx>
57 #include <editeng/lineitem.hxx>
58 #include <editeng/brushitem.hxx>
59 #include <editeng/lspcitem.hxx>
60 #include <editeng/adjustitem.hxx>
61 #include <editeng/orphitem.hxx>
62 #include <editeng/widwitem.hxx>
63 #include <editeng/tstpitem.hxx>
64 #include <editeng/pmdlitem.hxx>
65 #include <editeng/spltitem.hxx>
66 #include <editeng/hyphenzoneitem.hxx>
67 #include <editeng/charscaleitem.hxx>
68 #include <editeng/charrotateitem.hxx>
69 #include <editeng/charreliefitem.hxx>
70 #include <editeng/paravertalignitem.hxx>
71 #include <editeng/forbiddenruleitem.hxx>
72 #include <editeng/hngpnctitem.hxx>
73 #include <editeng/scriptspaceitem.hxx>
74 #include <editeng/frmdiritem.hxx>
75 #include <editeng/charhiddenitem.hxx>
77 #include <svtools/rtftoken.h>
78 #include <svl/itempool.hxx>
79 #include <svl/itemiter.hxx>
81 #include <editeng/svxrtf.hxx>
82 #include <editeng/editids.hrc>
85 #define BRACERIGHT '}'
87 using namespace ::com::sun::star
;
88 using namespace editeng
;
90 // Some helper functions
92 inline const SvxEscapementItem
& GetEscapement(const SfxItemSet
& rSet
,sal_uInt16 nId
,bool bInP
=true)
93 { return static_cast<const SvxEscapementItem
&>(rSet
.Get( nId
,bInP
)); }
94 inline const SvxLineSpacingItem
& GetLineSpacing(const SfxItemSet
& rSet
,sal_uInt16 nId
,bool bInP
=true)
95 { return static_cast<const SvxLineSpacingItem
&>(rSet
.Get( nId
,bInP
)); }
97 inline const SvxLRSpaceItem
& GetLRSpace(const SfxItemSet
& rSet
,sal_uInt16 nId
,bool bInP
=true)
98 { return static_cast<const SvxLRSpaceItem
&>(rSet
.Get( nId
,bInP
)); }
99 inline const SvxULSpaceItem
& GetULSpace(const SfxItemSet
& rSet
,sal_uInt16 nId
,bool bInP
=true)
100 { return static_cast<const SvxULSpaceItem
&>(rSet
.Get( nId
,bInP
)); }
102 void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType
, SfxItemSet
& rSet
,
105 const sal_uInt16
*pNormal
= 0, *pCJK
= 0, *pCTL
= 0;
106 switch( rItem
.Which() )
108 case SID_ATTR_CHAR_FONT
:
109 pNormal
= &aPlainMap
.nFont
;
110 pCJK
= &aPlainMap
.nCJKFont
;
111 pCTL
= &aPlainMap
.nCTLFont
;
114 case SID_ATTR_CHAR_FONTHEIGHT
:
115 pNormal
= &aPlainMap
.nFontHeight
;
116 pCJK
= &aPlainMap
.nCJKFontHeight
;
117 pCTL
= &aPlainMap
.nCTLFontHeight
;
120 case SID_ATTR_CHAR_POSTURE
:
121 pNormal
= &aPlainMap
.nPosture
;
122 pCJK
= &aPlainMap
.nCJKPosture
;
123 pCTL
= &aPlainMap
.nCTLPosture
;
126 case SID_ATTR_CHAR_WEIGHT
:
127 pNormal
= &aPlainMap
.nWeight
;
128 pCJK
= &aPlainMap
.nCJKWeight
;
129 pCTL
= &aPlainMap
.nCTLWeight
;
132 case SID_ATTR_CHAR_LANGUAGE
:
133 pNormal
= &aPlainMap
.nLanguage
;
134 pCJK
= &aPlainMap
.nCJKLanguage
;
135 pCTL
= &aPlainMap
.nCTLLanguage
;
139 // it exist no WhichId - don't set this item
147 if( DOUBLEBYTE_CHARTYPE
== eType
)
149 if( bIsLeftToRightDef
&& pCJK
)
151 rItem
.SetWhich( *pCJK
);
155 else if( !bIsLeftToRightDef
)
159 rItem
.SetWhich( *pCTL
);
165 if( LOW_CHARTYPE
== eType
)
169 rItem
.SetWhich( *pNormal
);
173 else if( HIGH_CHARTYPE
== eType
)
177 rItem
.SetWhich( *pCTL
);
185 rItem
.SetWhich( *pCJK
);
190 rItem
.SetWhich( *pCTL
);
195 rItem
.SetWhich( *pNormal
);
204 void SvxRTFParser::ReadAttr( int nToken
, SfxItemSet
* pSet
)
206 DBG_ASSERT( pSet
, "A SfxItemSet has to be provided as argument!" );
207 bool bFirstToken
= true;
208 bool bContinue
= true;
209 sal_uInt16 nStyleNo
= 0; // default
210 FontUnderline eUnderline
;
211 FontUnderline eOverline
;
212 FontEmphasisMark eEmphasis
;
213 bPardTokenRead
= false;
214 RTF_CharTypeDef eCharType
= NOTDEF_CHARTYPE
;
215 sal_uInt16 nFontAlign
;
217 bool bChkStkPos
= !bNewGroup
&& !aAttrStack
.empty();
219 while( bContinue
&& IsParserWorking() ) // as long as known Attribute are recognized
224 RTFPardPlain( true, &pSet
);
226 bPardTokenRead
= true;
230 RTFPardPlain( false, &pSet
);
234 do { // middle checked loop
238 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
239 if( !pAkt
|| (pAkt
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
240 pAkt
->nSttCnt
== pInsPos
->GetCntIdx() ))
243 int nLastToken
= GetStackPtr(-1)->nTokenId
;
244 if( RTF_PARD
== nLastToken
|| RTF_PLAIN
== nLastToken
)
247 if( pAkt
->aAttrSet
.Count() || pAkt
->pChildList
||
251 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType(
252 *pAkt
, *pInsPos
, true );
253 pNew
->SetRTFDefaults( GetRTFDefaults() );
255 // "Set" all valid attributes up until this point
257 pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back(); // can be changed after AttrGroupEnd!
258 pNew
->aAttrSet
.SetParent( pAkt
? &pAkt
->aAttrSet
: 0 );
260 aAttrStack
.push_back( pNew
);
264 // continue to use this entry as a new one
265 pAkt
->SetStartPos( *pInsPos
);
267 pSet
= &pAkt
->aAttrSet
;
278 UnknownAttrToken( nToken
, pSet
);
282 if( bIsInReadStyleTab
)
290 nStyleNo
= -1 == nTokenValue
? 0 : sal_uInt16(nTokenValue
);
291 /* setze am akt. auf dem AttrStack stehenden Style die
292 I sit on akt. which is on the immediate style AttrStack */
294 SvxRTFItemStackType
* pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back();
298 pAkt
->nStyleNo
= sal_uInt16( nStyleNo
);
304 if( aPardMap
.nSplit
)
306 pSet
->Put( SvxFormatSplitItem( false, aPardMap
.nSplit
));
313 pSet
->Put( SvxFormatKeepItem( true, aPardMap
.nKeep
));
318 if( aPardMap
.nOutlineLvl
)
320 pSet
->Put( SfxUInt16Item( aPardMap
.nOutlineLvl
,
321 (sal_uInt16
)nTokenValue
));
326 if( aPardMap
.nAdjust
)
328 pSet
->Put( SvxAdjustItem( SVX_ADJUST_LEFT
, aPardMap
.nAdjust
));
332 if( aPardMap
.nAdjust
)
334 pSet
->Put( SvxAdjustItem( SVX_ADJUST_RIGHT
, aPardMap
.nAdjust
));
338 if( aPardMap
.nAdjust
)
340 pSet
->Put( SvxAdjustItem( SVX_ADJUST_BLOCK
, aPardMap
.nAdjust
));
344 if( aPardMap
.nAdjust
)
346 pSet
->Put( SvxAdjustItem( SVX_ADJUST_CENTER
, aPardMap
.nAdjust
));
351 if( aPardMap
.nLRSpace
)
353 SvxLRSpaceItem
aLR( GetLRSpace(*pSet
, aPardMap
.nLRSpace
));
355 if( -1 != nTokenValue
)
359 nSz
= sal_uInt16(nTokenValue
);
361 aLR
.SetTextFirstLineOfst( nSz
);
368 if( aPardMap
.nLRSpace
)
370 SvxLRSpaceItem
aLR( GetLRSpace(*pSet
, aPardMap
.nLRSpace
));
372 if( 0 < nTokenValue
)
376 nSz
= sal_uInt16(nTokenValue
);
378 aLR
.SetTextLeft( nSz
);
385 if( aPardMap
.nLRSpace
)
387 SvxLRSpaceItem
aLR( GetLRSpace(*pSet
, aPardMap
.nLRSpace
));
389 if( 0 < nTokenValue
)
393 nSz
= sal_uInt16(nTokenValue
);
401 if( aPardMap
.nULSpace
)
403 SvxULSpaceItem
aUL( GetULSpace(*pSet
, aPardMap
.nULSpace
));
405 if( 0 < nTokenValue
)
409 nSz
= sal_uInt16(nTokenValue
);
417 if( aPardMap
.nULSpace
)
419 SvxULSpaceItem
aUL( GetULSpace(*pSet
, aPardMap
.nULSpace
));
421 if( 0 < nTokenValue
)
425 nSz
= sal_uInt16(nTokenValue
);
433 if( aPardMap
.nLinespacing
&& 1 == nTokenValue
)
435 // then switches to multi-line!
436 SvxLineSpacingItem
aLSpace( GetLineSpacing( *pSet
,
437 aPardMap
.nLinespacing
, false ));
439 // how much do you get from the line height value?
441 // Proportional-Size:
442 // Ie, the ratio is (n / 240) twips
448 nTokenValue
= short( 100L * aLSpace
.GetLineHeight()
449 / long( nTokenValue
) );
451 if( nTokenValue
> 200 ) // Data value for PropLnSp
452 nTokenValue
= 200; // is one BYTE !!!
454 aLSpace
.SetPropLineSpace( (const sal_uInt8
)nTokenValue
);
455 aLSpace
.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO
;
457 pSet
->Put( aLSpace
);
462 if( aPardMap
.nLinespacing
)
464 // Calculate the ratio between the default font and the
465 // specified size. The distance consists of the line height
466 // (100%) and the space above the line (20%).
467 SvxLineSpacingItem
aLSpace(0, aPardMap
.nLinespacing
);
469 nTokenValue
= !bTokenHasValue
? 0 : nTokenValue
;
470 if (1000 == nTokenValue
)
476 eLnSpc
= SVX_LINE_SPACE_FIX
;
477 nTokenValue
= -nTokenValue
;
479 else if (nTokenValue
== 0)
481 //if \sl0 is used, the line spacing is automatically
483 eLnSpc
= SVX_LINE_SPACE_AUTO
;
486 eLnSpc
= SVX_LINE_SPACE_MIN
;
491 if (eLnSpc
!= SVX_LINE_SPACE_AUTO
)
492 aLSpace
.SetLineHeight( (const sal_uInt16
)nTokenValue
);
494 aLSpace
.GetLineSpaceRule() = eLnSpc
;
500 if( aPardMap
.nForbRule
)
502 pSet
->Put( SvxForbiddenRuleItem( false,
503 aPardMap
.nForbRule
));
507 if( aPardMap
.nHangPunct
)
509 pSet
->Put( SvxHangingPunctuationItem( false,
510 aPardMap
.nHangPunct
));
515 if( aPardMap
.nScriptSpace
)
517 pSet
->Put( SvxScriptSpaceItem( true,
518 aPardMap
.nScriptSpace
));
523 case RTF_FAAUTO
: nFontAlign
= SvxParaVertAlignItem::AUTOMATIC
;
524 goto SET_FONTALIGNMENT
;
525 case RTF_FAHANG
: nFontAlign
= SvxParaVertAlignItem::TOP
;
526 goto SET_FONTALIGNMENT
;
527 case RTF_FAVAR
: nFontAlign
= SvxParaVertAlignItem::BOTTOM
;
528 goto SET_FONTALIGNMENT
;
529 case RTF_FACENTER
: nFontAlign
= SvxParaVertAlignItem::CENTER
;
530 goto SET_FONTALIGNMENT
;
531 case RTF_FAROMAN
: nFontAlign
= SvxParaVertAlignItem::BASELINE
;
532 goto SET_FONTALIGNMENT
;
534 if( aPardMap
.nFontAlign
)
536 pSet
->Put( SvxParaVertAlignItem( nFontAlign
,
537 aPardMap
.nFontAlign
));
543 if( IsAttrSttPos() ) // not in the text flow?
546 SvxWeightItem
aTmpItem(
547 nTokenValue
? WEIGHT_BOLD
: WEIGHT_NORMAL
,
548 SID_ATTR_CHAR_WEIGHT
);
549 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
555 if( aPlainMap
.nCaseMap
&&
556 IsAttrSttPos() ) // not in the text flow?
560 eCaseMap
= SVX_CASEMAP_NOT_MAPPED
;
561 else if( RTF_CAPS
== nToken
)
562 eCaseMap
= SVX_CASEMAP_VERSALIEN
;
564 eCaseMap
= SVX_CASEMAP_KAPITAELCHEN
;
566 pSet
->Put( SvxCaseMapItem( eCaseMap
, aPlainMap
.nCaseMap
));
572 if( aPlainMap
.nEscapement
)
574 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
575 if( -1 == nTokenValue
|| RTF_SUB
== nToken
)
579 const SvxEscapementItem
& rOld
= GetEscapement( *pSet
, nEsc
, false );
582 if( DFLT_ESC_AUTO_SUPER
== rOld
.GetEsc() )
584 nEs
= DFLT_ESC_AUTO_SUB
;
585 nProp
= rOld
.GetProp();
589 nEs
= (short)-nTokenValue
;
590 nProp
= (nToken
== RTF_SUB
) ? DFLT_ESC_PROP
: 100;
592 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
597 if( aPlainMap
.nEscapement
)
599 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
600 pSet
->Put( SvxEscapementItem( nEsc
));
605 if( aPlainMap
.nKering
)
607 if( -1 == nTokenValue
)
613 pSet
->Put( SvxKerningItem( (short)nTokenValue
, aPlainMap
.nKering
));
618 if( aPlainMap
.nAutoKerning
)
620 if( -1 == nTokenValue
)
626 pSet
->Put( SvxAutoKernItem( 0 != nTokenValue
,
627 aPlainMap
.nAutoKerning
));
632 if( aPlainMap
.nKering
)
634 if( -1 == nTokenValue
)
638 pSet
->Put( SvxKerningItem( (short)nTokenValue
, aPlainMap
.nKering
));
645 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nTokenValue
) );
646 SvxFontItem
aTmpItem( rSVFont
.GetFamily(),
647 rSVFont
.GetName(), rSVFont
.GetStyleName(),
648 rSVFont
.GetPitch(), rSVFont
.GetCharSet(),
649 SID_ATTR_CHAR_FONT
);
650 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
651 if( RTF_F
== nToken
)
653 SetEncoding( rSVFont
.GetCharSet() );
662 if( -1 == nTokenValue
)
667 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
668 // the converiosn takes now place in EditRTFParser since for other reasons
669 // the wrong MapUnit might still be use there
670 // if( IsCalcValue() )
672 SvxFontHeightItem
aTmpItem(
673 (const sal_uInt16
)nTokenValue
, 100,
674 SID_ATTR_CHAR_FONTHEIGHT
);
675 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
681 if( IsAttrSttPos() ) // not in the text flow?
683 SvxPostureItem
aTmpItem(
684 nTokenValue
? ITALIC_NORMAL
: ITALIC_NONE
,
685 SID_ATTR_CHAR_POSTURE
);
686 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
691 if( aPlainMap
.nContour
&&
692 IsAttrSttPos() ) // not in the text flow?
694 pSet
->Put( SvxContourItem(nTokenValue
!= 0,
695 aPlainMap
.nContour
));
700 if( aPlainMap
.nShadowed
&&
701 IsAttrSttPos() ) // not in the text flow?
703 pSet
->Put( SvxShadowedItem(nTokenValue
!= 0,
704 aPlainMap
.nShadowed
));
709 if( aPlainMap
.nCrossedOut
&&
710 IsAttrSttPos() ) // not in the text flow?
712 pSet
->Put( SvxCrossedOutItem(
713 nTokenValue
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
,
714 aPlainMap
.nCrossedOut
));
719 if( aPlainMap
.nCrossedOut
) // not in the text flow?
721 pSet
->Put( SvxCrossedOutItem(
722 nTokenValue
? STRIKEOUT_DOUBLE
: STRIKEOUT_NONE
,
723 aPlainMap
.nCrossedOut
));
728 if( !IsAttrSttPos() )
730 eUnderline
= nTokenValue
? UNDERLINE_SINGLE
: UNDERLINE_NONE
;
731 goto ATTR_SETUNDERLINE
;
734 eUnderline
= UNDERLINE_DOTTED
;
735 goto ATTR_SETUNDERLINE
;
737 eUnderline
= UNDERLINE_DASH
;
738 goto ATTR_SETUNDERLINE
;
740 eUnderline
= UNDERLINE_DASHDOT
;
741 goto ATTR_SETUNDERLINE
;
743 eUnderline
= UNDERLINE_DASHDOTDOT
;
744 goto ATTR_SETUNDERLINE
;
746 eUnderline
= UNDERLINE_DOUBLE
;
747 goto ATTR_SETUNDERLINE
;
749 eUnderline
= UNDERLINE_NONE
;
750 goto ATTR_SETUNDERLINE
;
752 eUnderline
= UNDERLINE_BOLD
;
753 goto ATTR_SETUNDERLINE
;
755 eUnderline
= UNDERLINE_WAVE
;
756 goto ATTR_SETUNDERLINE
;
758 eUnderline
= UNDERLINE_BOLDDOTTED
;
759 goto ATTR_SETUNDERLINE
;
761 eUnderline
= UNDERLINE_BOLDDASH
;
762 goto ATTR_SETUNDERLINE
;
764 eUnderline
= UNDERLINE_LONGDASH
;
765 goto ATTR_SETUNDERLINE
;
767 eUnderline
= UNDERLINE_BOLDLONGDASH
;
768 goto ATTR_SETUNDERLINE
;
770 eUnderline
= UNDERLINE_BOLDDASHDOT
;
771 goto ATTR_SETUNDERLINE
;
773 eUnderline
= UNDERLINE_BOLDDASHDOTDOT
;
774 goto ATTR_SETUNDERLINE
;
776 eUnderline
= UNDERLINE_BOLDWAVE
;
777 goto ATTR_SETUNDERLINE
;
779 eUnderline
= UNDERLINE_DOUBLEWAVE
;
780 goto ATTR_SETUNDERLINE
;
783 eUnderline
= UNDERLINE_SINGLE
;
785 if( aPlainMap
.nWordlineMode
)
787 pSet
->Put( SvxWordLineModeItem( true, aPlainMap
.nWordlineMode
));
789 goto ATTR_SETUNDERLINE
;
792 if( aPlainMap
.nUnderline
)
794 pSet
->Put( SvxUnderlineItem( eUnderline
, aPlainMap
.nUnderline
));
799 if( aPlainMap
.nUnderline
)
801 SvxUnderlineItem
aUL( UNDERLINE_SINGLE
, aPlainMap
.nUnderline
);
802 const SfxPoolItem
* pItem
;
803 if( SfxItemState::SET
== pSet
->GetItemState(
804 aPlainMap
.nUnderline
, false, &pItem
) )
807 if( UNDERLINE_NONE
==
808 static_cast<const SvxUnderlineItem
*>(pItem
)->GetLineStyle() )
810 aUL
= *static_cast<const SvxUnderlineItem
*>(pItem
);
813 aUL
= static_cast<const SvxUnderlineItem
&>(pSet
->Get( aPlainMap
.nUnderline
, false ));
815 if( UNDERLINE_NONE
== aUL
.GetLineStyle() )
816 aUL
.SetLineStyle( UNDERLINE_SINGLE
);
817 aUL
.SetColor( GetColor( sal_uInt16(nTokenValue
) ));
823 if( !IsAttrSttPos() )
825 eOverline
= nTokenValue
? UNDERLINE_SINGLE
: UNDERLINE_NONE
;
826 goto ATTR_SETOVERLINE
;
829 eOverline
= UNDERLINE_DOTTED
;
830 goto ATTR_SETOVERLINE
;
832 eOverline
= UNDERLINE_DASH
;
833 goto ATTR_SETOVERLINE
;
835 eOverline
= UNDERLINE_DASHDOT
;
836 goto ATTR_SETOVERLINE
;
838 eOverline
= UNDERLINE_DASHDOTDOT
;
839 goto ATTR_SETOVERLINE
;
841 eOverline
= UNDERLINE_DOUBLE
;
842 goto ATTR_SETOVERLINE
;
844 eOverline
= UNDERLINE_NONE
;
845 goto ATTR_SETOVERLINE
;
847 eOverline
= UNDERLINE_BOLD
;
848 goto ATTR_SETOVERLINE
;
850 eOverline
= UNDERLINE_WAVE
;
851 goto ATTR_SETOVERLINE
;
853 eOverline
= UNDERLINE_BOLDDOTTED
;
854 goto ATTR_SETOVERLINE
;
856 eOverline
= UNDERLINE_BOLDDASH
;
857 goto ATTR_SETOVERLINE
;
859 eOverline
= UNDERLINE_LONGDASH
;
860 goto ATTR_SETOVERLINE
;
862 eOverline
= UNDERLINE_BOLDLONGDASH
;
863 goto ATTR_SETOVERLINE
;
865 eOverline
= UNDERLINE_BOLDDASHDOT
;
866 goto ATTR_SETOVERLINE
;
868 eOverline
= UNDERLINE_BOLDDASHDOTDOT
;
869 goto ATTR_SETOVERLINE
;
871 eOverline
= UNDERLINE_BOLDWAVE
;
872 goto ATTR_SETOVERLINE
;
874 eOverline
= UNDERLINE_DOUBLEWAVE
;
875 goto ATTR_SETOVERLINE
;
878 eOverline
= UNDERLINE_SINGLE
;
880 if( aPlainMap
.nWordlineMode
)
882 pSet
->Put( SvxWordLineModeItem( true, aPlainMap
.nWordlineMode
));
884 goto ATTR_SETOVERLINE
;
887 if( aPlainMap
.nUnderline
)
889 pSet
->Put( SvxOverlineItem( eOverline
, aPlainMap
.nOverline
));
894 if( aPlainMap
.nOverline
)
896 SvxOverlineItem
aOL( UNDERLINE_SINGLE
, aPlainMap
.nOverline
);
897 const SfxPoolItem
* pItem
;
898 if( SfxItemState::SET
== pSet
->GetItemState(
899 aPlainMap
.nOverline
, false, &pItem
) )
902 if( UNDERLINE_NONE
==
903 static_cast<const SvxOverlineItem
*>(pItem
)->GetLineStyle() )
905 aOL
= *static_cast<const SvxOverlineItem
*>(pItem
);
908 aOL
= static_cast<const SvxOverlineItem
&>(pSet
->Get( aPlainMap
.nOverline
, false ));
910 if( UNDERLINE_NONE
== aOL
.GetLineStyle() )
911 aOL
.SetLineStyle( UNDERLINE_SINGLE
);
912 aOL
.SetColor( GetColor( sal_uInt16(nTokenValue
) ));
919 if( aPlainMap
.nEscapement
)
921 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
922 if( -1 == nTokenValue
|| RTF_SUPER
== nToken
)
926 const SvxEscapementItem
& rOld
= GetEscapement( *pSet
, nEsc
, false );
929 if( DFLT_ESC_AUTO_SUB
== rOld
.GetEsc() )
931 nEs
= DFLT_ESC_AUTO_SUPER
;
932 nProp
= rOld
.GetProp();
936 nEs
= (short)nTokenValue
;
937 nProp
= (nToken
== RTF_SUPER
) ? DFLT_ESC_PROP
: 100;
939 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
944 if( aPlainMap
.nColor
)
946 pSet
->Put( SvxColorItem( GetColor( sal_uInt16(nTokenValue
) ),
950 //#i12501# While cb is clearly documented in the rtf spec, word
951 //doesn't accept it at all
954 if( aPlainMap
.nBgColor
)
956 pSet
->Put( SvxBrushItem( GetColor( sal_uInt16(nTokenValue
) ),
957 aPlainMap
.nBgColor
));
963 if( aPlainMap
.nLanguage
)
965 pSet
->Put( SvxLanguageItem( (LanguageType
)nTokenValue
,
966 aPlainMap
.nLanguage
));
971 if( aPlainMap
.nCJKLanguage
)
973 pSet
->Put( SvxLanguageItem( (LanguageType
)nTokenValue
,
974 aPlainMap
.nCJKLanguage
));
979 SvxLanguageItem
aTmpItem( (LanguageType
)nTokenValue
,
980 SID_ATTR_CHAR_LANGUAGE
);
981 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
986 bIsLeftToRightDef
= false;
989 bIsLeftToRightDef
= true;
992 if (aPardMap
.nDirection
)
994 pSet
->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP
,
995 aPardMap
.nDirection
));
999 if (aPardMap
.nDirection
)
1001 pSet
->Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP
,
1002 aPardMap
.nDirection
));
1005 case RTF_LOCH
: eCharType
= LOW_CHARTYPE
; break;
1006 case RTF_HICH
: eCharType
= HIGH_CHARTYPE
; break;
1007 case RTF_DBCH
: eCharType
= DOUBLEBYTE_CHARTYPE
; break;
1011 eEmphasis
= EMPHASISMARK_NONE
;
1012 goto ATTR_SETEMPHASIS
;
1014 eEmphasis
= EMPHASISMARK_DOTS_ABOVE
;
1015 goto ATTR_SETEMPHASIS
;
1018 eEmphasis
= EMPHASISMARK_SIDE_DOTS
;
1020 if( aPlainMap
.nEmphasis
)
1022 pSet
->Put( SvxEmphasisMarkItem( eEmphasis
,
1023 aPlainMap
.nEmphasis
));
1028 if( aPlainMap
.nTwoLines
)
1030 sal_Unicode cStt
, cEnd
;
1031 switch ( nTokenValue
)
1033 case 1: cStt
= '(', cEnd
= ')'; break;
1034 case 2: cStt
= '[', cEnd
= ']'; break;
1035 case 3: cStt
= '<', cEnd
= '>'; break;
1036 case 4: cStt
= '{', cEnd
= '}'; break;
1037 default: cStt
= 0, cEnd
= 0; break;
1040 pSet
->Put( SvxTwoLinesItem( true, cStt
, cEnd
,
1041 aPlainMap
.nTwoLines
));
1045 case RTF_CHARSCALEX
:
1046 if (aPlainMap
.nCharScaleX
)
1049 if (nTokenValue
< 1 || nTokenValue
> 600)
1051 pSet
->Put( SvxCharScaleWidthItem( sal_uInt16(nTokenValue
),
1052 aPlainMap
.nCharScaleX
));
1057 if( aPlainMap
.nHorzVert
)
1059 // RTF knows only 90deg
1060 pSet
->Put( SvxCharRotateItem( 900, 1 == nTokenValue
,
1061 aPlainMap
.nHorzVert
));
1066 if (aPlainMap
.nRelief
)
1068 pSet
->Put(SvxCharReliefItem(RELIEF_EMBOSSED
,
1069 aPlainMap
.nRelief
));
1073 if (aPlainMap
.nRelief
)
1075 pSet
->Put(SvxCharReliefItem(RELIEF_ENGRAVED
,
1076 aPlainMap
.nRelief
));
1080 if (aPlainMap
.nHidden
)
1082 pSet
->Put(SvxCharHiddenItem(nTokenValue
!= 0,
1083 aPlainMap
.nHidden
));
1087 case RTF_CHBGDKVERT
:
1088 case RTF_CHBGDKHORIZ
:
1091 case RTF_CHBGDKFDIAG
:
1092 case RTF_CHBGDCROSS
:
1095 case RTF_CHBGDKDCROSS
:
1096 case RTF_CHBGDKCROSS
:
1097 case RTF_CHBGDKBDIAG
:
1101 if( aPlainMap
.nBgColor
)
1102 ReadBackgroundAttr( nToken
, *pSet
);
1107 // tests on Swg internal tokens
1108 bool bHandled
= false;
1110 if( RTF_IGNOREFLAG
!= GetNextToken())
1112 else if( (nToken
= GetNextToken() ) & RTF_SWGDEFS
)
1120 UnknownAttrToken( nToken
, pSet
);
1121 // overwrite the closing parenthesis
1124 case RTF_SWG_ESCPROP
:
1126 // Store percentage change!
1127 sal_uInt8 nProp
= sal_uInt8( nTokenValue
/ 100 );
1129 if( 1 == ( nTokenValue
% 100 ))
1130 // Recognize own auto-flags!
1131 nEsc
= DFLT_ESC_AUTO_SUPER
;
1133 if( aPlainMap
.nEscapement
)
1134 pSet
->Put( SvxEscapementItem( nEsc
, nProp
,
1135 aPlainMap
.nEscapement
));
1141 SvxHyphenZoneItem
aHypenZone(
1142 (nTokenValue
& 1) != 0,
1143 aPardMap
.nHyphenzone
);
1144 aHypenZone
.SetPageEnd((nTokenValue
& 2) != 0);
1146 if( aPardMap
.nHyphenzone
&&
1147 RTF_HYPHLEAD
== GetNextToken() &&
1148 RTF_HYPHTRAIL
== GetNextToken() &&
1149 RTF_HYPHMAX
== GetNextToken() )
1151 aHypenZone
.GetMinLead() =
1152 sal_uInt8(GetStackPtr( -2 )->nTokenValue
);
1153 aHypenZone
.GetMinTrail() =
1154 sal_uInt8(GetStackPtr( -1 )->nTokenValue
);
1155 aHypenZone
.GetMaxHyphens() =
1156 sal_uInt8(nTokenValue
);
1158 pSet
->Put( aHypenZone
);
1161 SkipGroup(); // at the end of the group
1168 do { // middle check loop
1169 SvxShadowLocation eSL
= SvxShadowLocation( nTokenValue
);
1170 if( RTF_SHDW_DIST
!= GetNextToken() )
1172 sal_uInt16 nDist
= sal_uInt16( nTokenValue
);
1174 if( RTF_SHDW_STYLE
!= GetNextToken() )
1177 if( RTF_SHDW_COL
!= GetNextToken() )
1179 sal_uInt16 nCol
= sal_uInt16( nTokenValue
);
1181 if( RTF_SHDW_FCOL
!= GetNextToken() )
1184 Color aColor
= GetColor( nCol
);
1186 if( aPardMap
.nShadow
)
1187 pSet
->Put( SvxShadowItem( aPardMap
.nShadow
,
1188 &aColor
, nDist
, eSL
) );
1194 SkipGroup(); // at the end of the group
1200 if( (nToken
& ~(0xff | RTF_SWGDEFS
)) == RTF_TABSTOPDEF
)
1202 nToken
= SkipToken( -2 );
1203 ReadTabAttr( nToken
, *pSet
);
1206 cmc: #i76140, he who consumed the { must consume the }
1207 We rewound to a state of { being the current
1208 token so it is our responsibility to consume the }
1209 token if we consumed the {. We will not have consumed
1210 the { if it belonged to our caller, i.e. if the { we
1211 are handling is the "firsttoken" passed to us then
1212 the *caller* must consume it, not us. Otherwise *we*
1215 if (nToken
== BRACELEFT
&& !bFirstToken
)
1217 nToken
= GetNextToken();
1218 SAL_WARN_IF( nToken
!= BRACERIGHT
,
1220 "} did not follow { as expected");
1223 else if( (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
)
1225 nToken
= SkipToken( -2 );
1226 ReadBorderAttr( nToken
, *pSet
);
1228 else // so no more attribute
1235 cmc: #i4727# / #i12713# Who owns this closing bracket?
1236 If we read the opening one, we must read this one, if
1237 other is counting the brackets so as to push/pop off
1238 the correct environment then we will have pushed a new
1239 environment for the start { of this, but will not see
1240 the } and so is out of sync for the rest of the
1243 if (bHandled
&& !bFirstToken
)
1250 if( nSkip
) // all completely unknown
1253 --nSkip
; // BRACELEFT: is the next token
1260 if( (nToken
& ~0xff ) == RTF_TABSTOPDEF
)
1261 ReadTabAttr( nToken
, *pSet
);
1262 else if( (nToken
& ~0xff ) == RTF_BRDRDEF
)
1263 ReadBorderAttr( nToken
, *pSet
);
1264 else if( (nToken
& ~0xff ) == RTF_SHADINGDEF
)
1265 ReadBackgroundAttr( nToken
, *pSet
);
1268 // unknown token, so token "returned in Parser"
1277 nToken
= GetNextToken();
1279 bFirstToken
= false;
1283 void SvxRTFParser::ReadTabAttr( int nToken
, SfxItemSet
& rSet
)
1285 bool bMethodOwnsToken
= false; // #i52542# patch from cmc.
1286 // then read all the TabStops
1287 SvxTabStop aTabStop
;
1288 SvxTabStopItem
aAttr( 0, 0, SVX_TAB_ADJUST_DEFAULT
, aPardMap
.nTabStop
);
1289 bool bContinue
= true;
1293 case RTF_TB
: // BarTab ???
1298 aTabStop
.GetTabPos() = nTokenValue
;
1299 aAttr
.Insert( aTabStop
);
1300 aTabStop
= SvxTabStop(); // all values default
1305 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_LEFT
;
1308 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_RIGHT
;
1311 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_CENTER
;
1314 aTabStop
.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL
;
1317 case RTF_TLDOT
: aTabStop
.GetFill() = '.'; break;
1318 case RTF_TLHYPH
: aTabStop
.GetFill() = ' '; break;
1319 case RTF_TLUL
: aTabStop
.GetFill() = '_'; break;
1320 case RTF_TLTH
: aTabStop
.GetFill() = '-'; break;
1321 case RTF_TLEQ
: aTabStop
.GetFill() = '='; break;
1325 // Swg - control BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1327 if( RTF_IGNOREFLAG
!= GetNextToken() )
1329 else if( RTF_TLSWG
!= ( nToken
= GetNextToken() ))
1333 aTabStop
.GetDecimal() = sal_uInt8(nTokenValue
& 0xff);
1334 aTabStop
.GetFill() = sal_uInt8((nTokenValue
>> 8) & 0xff);
1335 // overwrite the closing parenthesis
1336 if (bMethodOwnsToken
)
1341 SkipToken( nSkip
); // Ignore back again
1352 nToken
= GetNextToken();
1353 bMethodOwnsToken
= true;
1355 } while( bContinue
);
1357 // Fill with defaults is still missing!
1362 static void SetBorderLine( int nBorderTyp
, SvxBoxItem
& rItem
,
1363 const SvxBorderLine
& rBorder
)
1365 switch( nBorderTyp
)
1367 case RTF_BOX
: // run through all levels
1369 rItem
.SetLine( &rBorder
, SvxBoxItemLine::TOP
);
1370 if( RTF_BOX
!= nBorderTyp
)
1374 rItem
.SetLine( &rBorder
, SvxBoxItemLine::BOTTOM
);
1375 if( RTF_BOX
!= nBorderTyp
)
1379 rItem
.SetLine( &rBorder
, SvxBoxItemLine::LEFT
);
1380 if( RTF_BOX
!= nBorderTyp
)
1384 rItem
.SetLine( &rBorder
, SvxBoxItemLine::RIGHT
);
1385 if( RTF_BOX
!= nBorderTyp
)
1390 void SvxRTFParser::ReadBorderAttr( int nToken
, SfxItemSet
& rSet
,
1393 // then read the border attribute
1394 SvxBoxItem
aAttr( aPardMap
.nBox
);
1395 const SfxPoolItem
* pItem
;
1396 if( SfxItemState::SET
== rSet
.GetItemState( aPardMap
.nBox
, false, &pItem
) )
1397 aAttr
= *static_cast<const SvxBoxItem
*>(pItem
);
1399 SvxBorderLine
aBrd( 0, DEF_LINE_WIDTH_0
); // Simple plain line
1400 bool bContinue
= true;
1404 bool bDoubleWidth
= false;
1414 nBorderTyp
= nToken
;
1417 case RTF_CLBRDRT
: // Cell top border
1421 if (nBorderTyp
!= 0)
1422 SetBorderLine( nBorderTyp
, aAttr
, aBrd
);
1423 nBorderTyp
= RTF_BRDRT
;
1427 case RTF_CLBRDRB
: // Cell bottom border
1431 if (nBorderTyp
!= 0)
1432 SetBorderLine( nBorderTyp
, aAttr
, aBrd
);
1433 nBorderTyp
= RTF_BRDRB
;
1437 case RTF_CLBRDRL
: // Cell left border
1441 if (nBorderTyp
!= 0)
1442 SetBorderLine( nBorderTyp
, aAttr
, aBrd
);
1443 nBorderTyp
= RTF_BRDRL
;
1447 case RTF_CLBRDRR
: // Cell right border
1451 if (nBorderTyp
!= 0)
1452 SetBorderLine( nBorderTyp
, aAttr
, aBrd
);
1453 nBorderTyp
= RTF_BRDRR
;
1458 case RTF_BRDRDOT
: // dotted border
1459 aBrd
.SetBorderLineStyle(table::BorderLineStyle::DOTTED
);
1461 case RTF_BRDRDASH
: // dashed border
1462 aBrd
.SetBorderLineStyle(table::BorderLineStyle::DASHED
);
1464 case RTF_BRDRHAIR
: // hairline border
1466 aBrd
.SetBorderLineStyle( table::BorderLineStyle::SOLID
);
1467 aBrd
.SetWidth( DEF_LINE_WIDTH_0
);
1470 case RTF_BRDRDB
: // Double border
1471 aBrd
.SetBorderLineStyle(table::BorderLineStyle::DOUBLE
);
1473 case RTF_BRDRINSET
: // inset border
1474 aBrd
.SetBorderLineStyle(table::BorderLineStyle::INSET
);
1476 case RTF_BRDROUTSET
: // outset border
1477 aBrd
.SetBorderLineStyle(table::BorderLineStyle::OUTSET
);
1479 case RTF_BRDRTNTHSG
: // ThinThick Small gap
1480 aBrd
.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_SMALLGAP
);
1482 case RTF_BRDRTNTHMG
: // ThinThick Medium gap
1483 aBrd
.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_MEDIUMGAP
);
1485 case RTF_BRDRTNTHLG
: // ThinThick Large gap
1486 aBrd
.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_LARGEGAP
);
1488 case RTF_BRDRTHTNSG
: // ThickThin Small gap
1489 aBrd
.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_SMALLGAP
);
1491 case RTF_BRDRTHTNMG
: // ThickThin Medium gap
1492 aBrd
.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_MEDIUMGAP
);
1494 case RTF_BRDRTHTNLG
: // ThickThin Large gap
1495 aBrd
.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_LARGEGAP
);
1497 case RTF_BRDREMBOSS
: // Embossed border
1498 aBrd
.SetBorderLineStyle(table::BorderLineStyle::EMBOSSED
);
1500 case RTF_BRDRENGRAVE
: // Engraved border
1501 aBrd
.SetBorderLineStyle(table::BorderLineStyle::ENGRAVED
);
1504 case RTF_BRDRS
: // single thickness border
1505 bDoubleWidth
= false;
1507 case RTF_BRDRTH
: // double thickness border width*2
1508 bDoubleWidth
= true;
1510 case RTF_BRDRW
: // border width <255
1511 nWidth
= nTokenValue
;
1514 case RTF_BRDRCF
: // Border color
1515 aBrd
.SetColor( GetColor( sal_uInt16(nTokenValue
) ) );
1518 case RTF_BRDRSH
: // Shadowed border
1519 rSet
.Put( SvxShadowItem( aPardMap
.nShadow
, (Color
*) 0, 60 /*3pt*/,
1520 SVX_SHADOW_BOTTOMRIGHT
) );
1523 case RTF_BRSP
: // Spacing to content in twip
1525 switch( nBorderTyp
)
1528 aAttr
.SetDistance( (sal_uInt16
)nTokenValue
, SvxBoxItemLine::BOTTOM
);
1532 aAttr
.SetDistance( (sal_uInt16
)nTokenValue
, SvxBoxItemLine::TOP
);
1536 aAttr
.SetDistance( (sal_uInt16
)nTokenValue
, SvxBoxItemLine::LEFT
);
1540 aAttr
.SetDistance( (sal_uInt16
)nTokenValue
, SvxBoxItemLine::RIGHT
);
1544 aAttr
.SetDistance( (sal_uInt16
)nTokenValue
);
1550 case RTF_BRDRBTW
: // Border formatting group
1551 case RTF_BRDRBAR
: // Border outside
1552 // TODO unhandled ATM
1556 bContinue
= (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
;
1559 nToken
= GetNextToken();
1560 } while( bContinue
);
1562 // Finally compute the border width
1563 if ( bDoubleWidth
) nWidth
*= 2;
1564 aBrd
.SetWidth( nWidth
);
1566 SetBorderLine( nBorderTyp
, aAttr
, aBrd
);
1572 inline sal_uInt32
CalcShading( sal_uInt32 nColor
, sal_uInt32 nFillColor
, sal_uInt8 nShading
)
1574 nColor
= (nColor
* nShading
) / 100;
1575 nFillColor
= (nFillColor
* ( 100 - nShading
)) / 100;
1576 return nColor
+ nFillColor
;
1579 void SvxRTFParser::ReadBackgroundAttr( int nToken
, SfxItemSet
& rSet
,
1582 // then read the border attribute
1583 bool bContinue
= true;
1584 sal_uInt16 nColor
= USHRT_MAX
, nFillColor
= USHRT_MAX
;
1585 sal_uInt8 nFillValue
= 0;
1587 sal_uInt16 nWh
= ( nToken
& ~0xff ) == RTF_CHRFMT
1588 ? aPlainMap
.nBgColor
1597 nFillColor
= sal_uInt16( nTokenValue
);
1603 nColor
= sal_uInt16( nTokenValue
);
1609 nFillValue
= (sal_uInt8
)( nTokenValue
/ 100 );
1613 case RTF_CHBGDKHORIZ
:
1615 case RTF_CLBGDKVERT
:
1616 case RTF_CHBGDKVERT
:
1618 case RTF_CLBGDKBDIAG
:
1619 case RTF_CHBGDKBDIAG
:
1621 case RTF_CLBGDKFDIAG
:
1622 case RTF_CHBGDKFDIAG
:
1624 case RTF_CLBGDKCROSS
:
1625 case RTF_CHBGDKCROSS
:
1627 case RTF_CLBGDKDCROSS
:
1628 case RTF_CHBGDKDCROSS
:
1629 case RTF_BGDKDCROSS
:
1649 case RTF_CLBGDCROSS
:
1650 case RTF_CHBGDCROSS
:
1658 bContinue
= (nToken
& ~(0xff | RTF_TABLEDEF
) ) == RTF_SHADINGDEF
;
1660 bContinue
= (nToken
& ~0xff) == RTF_SHADINGDEF
;
1663 nToken
= GetNextToken();
1664 } while( bContinue
);
1666 Color
aCol( COL_WHITE
), aFCol
;
1669 // there was only one of two colors specified or no BrushTyp
1670 if( USHRT_MAX
!= nFillColor
)
1673 aCol
= GetColor( nFillColor
);
1675 else if( USHRT_MAX
!= nColor
)
1676 aFCol
= GetColor( nColor
);
1680 if( USHRT_MAX
!= nColor
)
1681 aCol
= GetColor( nColor
);
1683 aCol
= Color( COL_BLACK
);
1685 if( USHRT_MAX
!= nFillColor
)
1686 aFCol
= GetColor( nFillColor
);
1688 aFCol
= Color( COL_WHITE
);
1692 if( 0 == nFillValue
|| 100 == nFillValue
)
1696 (sal_uInt8
)CalcShading( aCol
.GetRed(), aFCol
.GetRed(), nFillValue
),
1697 (sal_uInt8
)CalcShading( aCol
.GetGreen(), aFCol
.GetGreen(), nFillValue
),
1698 (sal_uInt8
)CalcShading( aCol
.GetBlue(), aFCol
.GetBlue(), nFillValue
) );
1700 rSet
.Put( SvxBrushItem( aColor
, nWh
) );
1705 // pard / plain handling
1706 void SvxRTFParser::RTFPardPlain( bool const bPard
, SfxItemSet
** ppSet
)
1708 if( !bNewGroup
&& !aAttrStack
.empty() ) // not at the beginning of a new group
1710 SvxRTFItemStackType
* pAkt
= aAttrStack
.back();
1712 int nLastToken
= GetStackPtr(-1)->nTokenId
;
1713 bool bNewStkEntry
= true;
1714 if( RTF_PARD
!= nLastToken
&&
1715 RTF_PLAIN
!= nLastToken
&&
1716 BRACELEFT
!= nLastToken
)
1718 if( pAkt
->aAttrSet
.Count() || pAkt
->pChildList
|| pAkt
->nStyleNo
)
1721 SvxRTFItemStackType
* pNew
= new SvxRTFItemStackType( *pAkt
, *pInsPos
, true );
1722 pNew
->SetRTFDefaults( GetRTFDefaults() );
1724 // Set all until here valid attributes
1726 pAkt
= aAttrStack
.empty() ? 0 : aAttrStack
.back(); // can be changed after AttrGroupEnd!
1727 pNew
->aAttrSet
.SetParent( pAkt
? &pAkt
->aAttrSet
: 0 );
1728 aAttrStack
.push_back( pNew
);
1733 // continue to use this entry as new
1734 pAkt
->SetStartPos( *pInsPos
);
1735 bNewStkEntry
= false;
1739 // now reset all to default
1741 ( pAkt
->aAttrSet
.GetParent() || pAkt
->aAttrSet
.Count() ))
1743 const SfxPoolItem
*pItem
, *pDef
;
1744 const sal_uInt16
* pPtr
;
1746 const SfxItemSet
* pDfltSet
= &GetRTFDefaults();
1750 pPtr
= reinterpret_cast<sal_uInt16
*>(&aPardMap
);
1751 nCnt
= sizeof(aPardMap
) / sizeof(sal_uInt16
);
1755 pPtr
= reinterpret_cast<sal_uInt16
*>(&aPlainMap
);
1756 nCnt
= sizeof(aPlainMap
) / sizeof(sal_uInt16
);
1759 for( sal_uInt16 n
= 0; n
< nCnt
; ++n
, ++pPtr
)
1761 // Item set and different -> Set the Default Pool
1764 else if( SFX_WHICH_MAX
< *pPtr
)
1765 pAkt
->aAttrSet
.ClearItem( *pPtr
);
1766 else if( IsChkStyleAttr() )
1767 pAkt
->aAttrSet
.Put( pDfltSet
->Get( *pPtr
) );
1768 else if( !pAkt
->aAttrSet
.GetParent() )
1770 if( SfxItemState::SET
==
1771 pDfltSet
->GetItemState( *pPtr
, false, &pDef
))
1772 pAkt
->aAttrSet
.Put( *pDef
);
1774 pAkt
->aAttrSet
.ClearItem( *pPtr
);
1776 else if( SfxItemState::SET
== pAkt
->aAttrSet
.GetParent()->
1777 GetItemState( *pPtr
, true, &pItem
) &&
1778 *( pDef
= &pDfltSet
->Get( *pPtr
)) != *pItem
)
1779 pAkt
->aAttrSet
.Put( *pDef
);
1782 if( SfxItemState::SET
==
1783 pDfltSet
->GetItemState( *pPtr
, false, &pDef
))
1784 pAkt
->aAttrSet
.Put( *pDef
);
1786 pAkt
->aAttrSet
.ClearItem( *pPtr
);
1791 pAkt
->nStyleNo
= 0; // reset Style number
1793 *ppSet
= &pAkt
->aAttrSet
;
1797 //Once we have a default font, then any text without a font specifier is
1798 //in the default font, and thus has the default font charset, otherwise
1799 //we can fall back to the ansicpg set codeset
1800 if (nDfltFont
!= -1)
1802 const vcl::Font
& rSVFont
= GetFont(sal_uInt16(nDfltFont
));
1803 SetEncoding(rSVFont
.GetCharSet());
1806 SetEncoding(GetCodeSet());
1811 void SvxRTFParser::SetDefault( int nToken
, int nValue
)
1816 SfxItemSet
aTmp( *pAttrPool
, &aWhichMap
[0] );
1817 bool bOldFlag
= bIsLeftToRightDef
;
1818 bIsLeftToRightDef
= true;
1821 case RTF_ADEFF
: bIsLeftToRightDef
= false; // no break!
1826 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nValue
) );
1827 SvxFontItem
aTmpItem(
1828 rSVFont
.GetFamily(), rSVFont
.GetName(),
1829 rSVFont
.GetStyleName(), rSVFont
.GetPitch(),
1830 rSVFont
.GetCharSet(), SID_ATTR_CHAR_FONT
);
1831 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1835 case RTF_ADEFLANG
: bIsLeftToRightDef
= false; // no break!
1837 // store default Language
1840 SvxLanguageItem
aTmpItem( (const LanguageType
)nValue
,
1841 SID_ATTR_CHAR_LANGUAGE
);
1842 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1847 if( aPardMap
.nTabStop
)
1849 // RTF defines 720 twips as default
1850 bIsSetDfltTab
= true;
1851 if( -1 == nValue
|| !nValue
)
1854 // who would like to have no twips ...
1857 nTokenValue
= nValue
;
1859 nValue
= nTokenValue
;
1862 // Calculate the ratio of default TabWidth / Tabs and
1863 // calculate the corresponding new number.
1864 // ?? how did one come up with 13 ??
1865 sal_uInt16 nTabCount
= (SVX_TAB_DEFDIST
* 13 ) / sal_uInt16(nValue
);
1867 cmc, make sure we have at least one, or all hell breaks loose in
1868 everybodies exporters, #i8247#
1873 // we want Defaulttabs
1874 SvxTabStopItem
aNewTab( nTabCount
, sal_uInt16(nValue
),
1875 SVX_TAB_ADJUST_DEFAULT
, aPardMap
.nTabStop
);
1877 ((SvxTabStop
&)aNewTab
[ --nTabCount
]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT
;
1879 pAttrPool
->SetPoolDefaultItem( aNewTab
);
1883 bIsLeftToRightDef
= bOldFlag
;
1887 SfxItemIter
aIter( aTmp
);
1888 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1891 pAttrPool
->SetPoolDefaultItem( *pItem
);
1892 if( aIter
.IsAtEnd() )
1894 pItem
= aIter
.NextItem();
1899 // default: no conversion, leaving everything in twips.
1900 void SvxRTFParser::CalcValue()
1904 // for tokens that are not evaluated in ReadAttr
1905 void SvxRTFParser::UnknownAttrToken( int, SfxItemSet
* )
1909 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */