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/fontitem.hxx>
22 #include <editeng/postitem.hxx>
23 #include <editeng/wghtitem.hxx>
24 #include <editeng/fhgtitem.hxx>
25 #include <editeng/udlnitem.hxx>
26 #include <editeng/crossedoutitem.hxx>
27 #include <editeng/shdditem.hxx>
28 #include <editeng/autokernitem.hxx>
29 #include <editeng/wrlmitem.hxx>
30 #include <editeng/contouritem.hxx>
31 #include <editeng/colritem.hxx>
32 #include <editeng/kernitem.hxx>
33 #include <editeng/cmapitem.hxx>
34 #include <editeng/escapementitem.hxx>
35 #include <editeng/langitem.hxx>
36 #include <editeng/emphasismarkitem.hxx>
37 #include <editeng/twolinesitem.hxx>
38 #include <editeng/lrspitem.hxx>
39 #include <editeng/ulspitem.hxx>
40 #include <editeng/shaditem.hxx>
41 #include <editeng/borderline.hxx>
42 #include <editeng/boxitem.hxx>
43 #include <editeng/keepitem.hxx>
44 #include <editeng/brushitem.hxx>
45 #include <editeng/lspcitem.hxx>
46 #include <editeng/adjustitem.hxx>
47 #include <editeng/tstpitem.hxx>
48 #include <editeng/spltitem.hxx>
49 #include <editeng/hyphenzoneitem.hxx>
50 #include <editeng/charscaleitem.hxx>
51 #include <editeng/charrotateitem.hxx>
52 #include <editeng/charreliefitem.hxx>
53 #include <editeng/paravertalignitem.hxx>
54 #include <editeng/forbiddenruleitem.hxx>
55 #include <editeng/hngpnctitem.hxx>
56 #include <editeng/scriptspaceitem.hxx>
57 #include <editeng/frmdiritem.hxx>
58 #include <editeng/charhiddenitem.hxx>
60 #include <svtools/rtftoken.h>
61 #include <svl/itempool.hxx>
62 #include <svl/itemiter.hxx>
63 #include <sal/log.hxx>
64 #include <vcl/font.hxx>
66 #include <editeng/svxrtf.hxx>
67 #include <editeng/editids.hrc>
72 #define BRACERIGHT '}'
74 using namespace ::com::sun::star
;
75 using namespace editeng
;
77 void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType
, SfxItemSet
& rSet
,
80 const sal_uInt16
*pNormal
= nullptr, *pCJK
= nullptr, *pCTL
= nullptr;
81 switch( rItem
.Which() )
83 case SID_ATTR_CHAR_FONT
:
84 pNormal
= &aPlainMap
.nFont
;
85 pCJK
= &aPlainMap
.nCJKFont
;
86 pCTL
= &aPlainMap
.nCTLFont
;
89 case SID_ATTR_CHAR_FONTHEIGHT
:
90 pNormal
= &aPlainMap
.nFontHeight
;
91 pCJK
= &aPlainMap
.nCJKFontHeight
;
92 pCTL
= &aPlainMap
.nCTLFontHeight
;
95 case SID_ATTR_CHAR_POSTURE
:
96 pNormal
= &aPlainMap
.nPosture
;
97 pCJK
= &aPlainMap
.nCJKPosture
;
98 pCTL
= &aPlainMap
.nCTLPosture
;
101 case SID_ATTR_CHAR_WEIGHT
:
102 pNormal
= &aPlainMap
.nWeight
;
103 pCJK
= &aPlainMap
.nCJKWeight
;
104 pCTL
= &aPlainMap
.nCTLWeight
;
107 case SID_ATTR_CHAR_LANGUAGE
:
108 pNormal
= &aPlainMap
.nLanguage
;
109 pCJK
= &aPlainMap
.nCJKLanguage
;
110 pCTL
= &aPlainMap
.nCTLLanguage
;
114 // it exist no WhichId - don't set this item
122 if( DOUBLEBYTE_CHARTYPE
== eType
)
124 if( bIsLeftToRightDef
&& pCJK
)
126 rItem
.SetWhich( *pCJK
);
130 else if( !bIsLeftToRightDef
)
134 rItem
.SetWhich( *pCTL
);
140 if( LOW_CHARTYPE
== eType
)
144 rItem
.SetWhich( *pNormal
);
148 else if( HIGH_CHARTYPE
== eType
)
152 rItem
.SetWhich( *pCTL
);
160 rItem
.SetWhich( *pCJK
);
165 rItem
.SetWhich( *pCTL
);
170 rItem
.SetWhich( *pNormal
);
178 void SvxRTFParser::ReadAttr( int nToken
, SfxItemSet
* pSet
)
180 DBG_ASSERT( pSet
, "A SfxItemSet has to be provided as argument!" );
181 bool bFirstToken
= true;
182 bool bContinue
= true;
183 FontLineStyle eUnderline
;
184 FontLineStyle eOverline
;
185 FontEmphasisMark eEmphasis
;
186 RTF_CharTypeDef eCharType
= NOTDEF_CHARTYPE
;
187 SvxParaVertAlignItem::Align nFontAlign
;
189 bool bChkStkPos
= !bNewGroup
&& !aAttrStack
.empty();
191 while( bContinue
&& IsParserWorking() ) // as long as known Attribute are recognized
196 RTFPardPlain( true, &pSet
);
200 RTFPardPlain( false, &pSet
);
204 do { // middle checked loop
208 SvxRTFItemStackType
* pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get();
209 if( !pCurrent
|| (pCurrent
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
210 pCurrent
->nSttCnt
== pInsPos
->GetCntIdx() ))
213 int nLastToken
= GetStackPtr(-1)->nTokenId
;
214 if( RTF_PARD
== nLastToken
|| RTF_PLAIN
== nLastToken
)
217 if (pCurrent
->aAttrSet
.Count() || pCurrent
->m_pChildList
||
221 std::unique_ptr
<SvxRTFItemStackType
> pNew(new SvxRTFItemStackType(
222 *pCurrent
, *pInsPos
, true ));
223 pNew
->SetRTFDefaults( GetRTFDefaults() );
225 // "Set" all valid attributes up until this point
227 pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get(); // can be changed after AttrGroupEnd!
228 pNew
->aAttrSet
.SetParent( pCurrent
? &pCurrent
->aAttrSet
: nullptr );
230 aAttrStack
.push_back( std::move(pNew
) );
231 pCurrent
= aAttrStack
.back().get();
234 // continue to use this entry as a new one
235 pCurrent
->SetStartPos( *pInsPos
);
237 pSet
= &pCurrent
->aAttrSet
;
248 UnknownAttrToken( nToken
);
252 if( bIsInReadStyleTab
)
260 sal_uInt16 nStyleNo
= -1 == nTokenValue
? 0 : sal_uInt16(nTokenValue
);
261 // set StyleNo to the current style on the AttrStack
262 SvxRTFItemStackType
* pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get();
266 pCurrent
->nStyleNo
= nStyleNo
;
271 if( aPardMap
.nSplit
)
273 pSet
->Put( SvxFormatSplitItem( false, aPardMap
.nSplit
));
280 pSet
->Put( SvxFormatKeepItem( true, aPardMap
.nKeep
));
285 if( aPardMap
.nOutlineLvl
)
287 pSet
->Put( SfxInt16Item( aPardMap
.nOutlineLvl
,
288 static_cast<sal_uInt16
>(nTokenValue
) ));
293 if( aPardMap
.nAdjust
)
295 pSet
->Put( SvxAdjustItem( SvxAdjust::Left
, aPardMap
.nAdjust
));
299 if( aPardMap
.nAdjust
)
301 pSet
->Put( SvxAdjustItem( SvxAdjust::Right
, aPardMap
.nAdjust
));
305 if( aPardMap
.nAdjust
)
307 pSet
->Put( SvxAdjustItem( SvxAdjust::Block
, aPardMap
.nAdjust
));
311 if( aPardMap
.nAdjust
)
313 pSet
->Put( SvxAdjustItem( SvxAdjust::Center
, aPardMap
.nAdjust
));
318 if( aPardMap
.nLRSpace
)
321 static_cast<const SvxLRSpaceItem
&>(pSet
->Get(aPardMap
.nLRSpace
)));
323 if( -1 != nTokenValue
)
327 nSz
= sal_uInt16(nTokenValue
);
329 aLR
.SetTextFirstLineOffset( nSz
);
336 if( aPardMap
.nLRSpace
)
339 static_cast<const SvxLRSpaceItem
&>(pSet
->Get(aPardMap
.nLRSpace
)));
341 if( 0 < nTokenValue
)
345 nSz
= sal_uInt16(nTokenValue
);
347 aLR
.SetTextLeft( nSz
);
354 if( aPardMap
.nLRSpace
)
357 static_cast<const SvxLRSpaceItem
&>(pSet
->Get(aPardMap
.nLRSpace
)));
359 if( 0 < nTokenValue
)
363 nSz
= sal_uInt16(nTokenValue
);
371 if( aPardMap
.nULSpace
)
374 static_cast<const SvxULSpaceItem
&>(pSet
->Get(aPardMap
.nULSpace
)));
376 if( 0 < nTokenValue
)
380 nSz
= sal_uInt16(nTokenValue
);
388 if( aPardMap
.nULSpace
)
391 static_cast<const SvxULSpaceItem
&>(pSet
->Get(aPardMap
.nULSpace
)));
393 if( 0 < nTokenValue
)
397 nSz
= sal_uInt16(nTokenValue
);
405 if( aPardMap
.nLinespacing
&& 1 == nTokenValue
)
407 // then switches to multi-line!
408 SvxLineSpacingItem
aLSpace(
409 static_cast<const SvxLineSpacingItem
&>(pSet
->Get( aPardMap
.nLinespacing
,false)));
411 // how much do you get from the line height value?
413 // Proportional-Size:
414 // Ie, the ratio is (n / 240) twips
420 nTokenValue
= short( 100 * aLSpace
.GetLineHeight() / nTokenValue
);
422 aLSpace
.SetPropLineSpace( static_cast<sal_uInt16
>(nTokenValue
) );
423 aLSpace
.SetLineSpaceRule( SvxLineSpaceRule::Auto
);
425 pSet
->Put( aLSpace
);
430 if( aPardMap
.nLinespacing
)
432 // Calculate the ratio between the default font and the
433 // specified size. The distance consists of the line height
434 // (100%) and the space above the line (20%).
435 SvxLineSpacingItem
aLSpace(0, aPardMap
.nLinespacing
);
437 nTokenValue
= !bTokenHasValue
? 0 : nTokenValue
;
438 if (1000 == nTokenValue
)
441 SvxLineSpaceRule eLnSpc
;
444 eLnSpc
= SvxLineSpaceRule::Fix
;
445 nTokenValue
= -nTokenValue
;
447 else if (nTokenValue
== 0)
449 //if \sl0 is used, the line spacing is automatically
451 eLnSpc
= SvxLineSpaceRule::Auto
;
454 eLnSpc
= SvxLineSpaceRule::Min
;
459 if (eLnSpc
!= SvxLineSpaceRule::Auto
)
460 aLSpace
.SetLineHeight( static_cast<sal_uInt16
>(nTokenValue
) );
462 aLSpace
.SetLineSpaceRule(eLnSpc
);
468 if( aPardMap
.nForbRule
)
470 pSet
->Put( SvxForbiddenRuleItem( false,
471 aPardMap
.nForbRule
));
475 if( aPardMap
.nHangPunct
)
477 pSet
->Put( SvxHangingPunctuationItem( false,
478 aPardMap
.nHangPunct
));
483 if( aPardMap
.nScriptSpace
)
485 pSet
->Put( SvxScriptSpaceItem( true,
486 aPardMap
.nScriptSpace
));
491 case RTF_FAAUTO
: nFontAlign
= SvxParaVertAlignItem::Align::Automatic
;
492 goto SET_FONTALIGNMENT
;
493 case RTF_FAHANG
: nFontAlign
= SvxParaVertAlignItem::Align::Top
;
494 goto SET_FONTALIGNMENT
;
495 case RTF_FAVAR
: nFontAlign
= SvxParaVertAlignItem::Align::Bottom
;
496 goto SET_FONTALIGNMENT
;
497 case RTF_FACENTER
: nFontAlign
= SvxParaVertAlignItem::Align::Center
;
498 goto SET_FONTALIGNMENT
;
499 case RTF_FAROMAN
: nFontAlign
= SvxParaVertAlignItem::Align::Baseline
;
500 goto SET_FONTALIGNMENT
;
502 if( aPardMap
.nFontAlign
)
504 pSet
->Put( SvxParaVertAlignItem( nFontAlign
,
505 aPardMap
.nFontAlign
));
511 if( IsAttrSttPos() ) // not in the text flow?
514 SvxWeightItem
aTmpItem(
515 nTokenValue
? WEIGHT_BOLD
: WEIGHT_NORMAL
,
516 SID_ATTR_CHAR_WEIGHT
);
517 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
523 if( aPlainMap
.nCaseMap
&&
524 IsAttrSttPos() ) // not in the text flow?
528 eCaseMap
= SvxCaseMap::NotMapped
;
529 else if( RTF_CAPS
== nToken
)
530 eCaseMap
= SvxCaseMap::Uppercase
;
532 eCaseMap
= SvxCaseMap::SmallCaps
;
534 pSet
->Put( SvxCaseMapItem( eCaseMap
, aPlainMap
.nCaseMap
));
540 if( aPlainMap
.nEscapement
)
542 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
543 if( -1 == nTokenValue
)
544 nTokenValue
= 6; //RTF default \dn value in half-points
547 const SvxEscapementItem
& rOld
=
548 static_cast<const SvxEscapementItem
&>(pSet
->Get( nEsc
,false));
551 if( DFLT_ESC_AUTO_SUPER
== rOld
.GetEsc() )
553 nEs
= DFLT_ESC_AUTO_SUB
;
554 nProp
= rOld
.GetProportionalHeight();
558 nEs
= (nToken
== RTF_SUB
) ? DFLT_ESC_AUTO_SUB
: -nTokenValue
;
559 nProp
= (nToken
== RTF_SUB
) ? DFLT_ESC_PROP
: 100;
561 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
566 if( aPlainMap
.nEscapement
)
568 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
569 pSet
->Put( SvxEscapementItem( nEsc
));
574 if( aPlainMap
.nKering
)
576 if( -1 == nTokenValue
)
582 pSet
->Put( SvxKerningItem( static_cast<short>(nTokenValue
), aPlainMap
.nKering
));
587 if( aPlainMap
.nAutoKerning
)
589 if( -1 == nTokenValue
)
595 pSet
->Put( SvxAutoKernItem( 0 != nTokenValue
,
596 aPlainMap
.nAutoKerning
));
601 if( aPlainMap
.nKering
)
603 if( -1 == nTokenValue
)
607 pSet
->Put( SvxKerningItem( static_cast<short>(nTokenValue
), aPlainMap
.nKering
));
614 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nTokenValue
) );
615 SvxFontItem
aTmpItem( rSVFont
.GetFamilyType(),
616 rSVFont
.GetFamilyName(), rSVFont
.GetStyleName(),
617 rSVFont
.GetPitch(), rSVFont
.GetCharSet(),
618 SID_ATTR_CHAR_FONT
);
619 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
620 if( RTF_F
== nToken
)
622 SetEncoding( rSVFont
.GetCharSet() );
631 if( -1 == nTokenValue
)
636 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
637 // the conversion takes now place in EditRTFParser since for other reasons
638 // the wrong MapUnit might still be use there
639 // if( IsCalcValue() )
641 SvxFontHeightItem
aTmpItem(
642 static_cast<sal_uInt16
>(nTokenValue
), 100,
643 SID_ATTR_CHAR_FONTHEIGHT
);
644 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
650 if( IsAttrSttPos() ) // not in the text flow?
652 SvxPostureItem
aTmpItem(
653 nTokenValue
? ITALIC_NORMAL
: ITALIC_NONE
,
654 SID_ATTR_CHAR_POSTURE
);
655 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
660 if( aPlainMap
.nContour
&&
661 IsAttrSttPos() ) // not in the text flow?
663 pSet
->Put( SvxContourItem(nTokenValue
!= 0,
664 aPlainMap
.nContour
));
669 if( aPlainMap
.nShadowed
&&
670 IsAttrSttPos() ) // not in the text flow?
672 pSet
->Put( SvxShadowedItem(nTokenValue
!= 0,
673 aPlainMap
.nShadowed
));
678 if( aPlainMap
.nCrossedOut
&&
679 IsAttrSttPos() ) // not in the text flow?
681 pSet
->Put( SvxCrossedOutItem(
682 nTokenValue
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
,
683 aPlainMap
.nCrossedOut
));
688 if( aPlainMap
.nCrossedOut
) // not in the text flow?
690 pSet
->Put( SvxCrossedOutItem(
691 nTokenValue
? STRIKEOUT_DOUBLE
: STRIKEOUT_NONE
,
692 aPlainMap
.nCrossedOut
));
697 if( !IsAttrSttPos() )
699 eUnderline
= nTokenValue
? LINESTYLE_SINGLE
: LINESTYLE_NONE
;
700 goto ATTR_SETUNDERLINE
;
703 eUnderline
= LINESTYLE_DOTTED
;
704 goto ATTR_SETUNDERLINE
;
706 eUnderline
= LINESTYLE_DASH
;
707 goto ATTR_SETUNDERLINE
;
709 eUnderline
= LINESTYLE_DASHDOT
;
710 goto ATTR_SETUNDERLINE
;
712 eUnderline
= LINESTYLE_DASHDOTDOT
;
713 goto ATTR_SETUNDERLINE
;
715 eUnderline
= LINESTYLE_DOUBLE
;
716 goto ATTR_SETUNDERLINE
;
718 eUnderline
= LINESTYLE_NONE
;
719 goto ATTR_SETUNDERLINE
;
721 eUnderline
= LINESTYLE_BOLD
;
722 goto ATTR_SETUNDERLINE
;
724 eUnderline
= LINESTYLE_WAVE
;
725 goto ATTR_SETUNDERLINE
;
727 eUnderline
= LINESTYLE_BOLDDOTTED
;
728 goto ATTR_SETUNDERLINE
;
730 eUnderline
= LINESTYLE_BOLDDASH
;
731 goto ATTR_SETUNDERLINE
;
733 eUnderline
= LINESTYLE_LONGDASH
;
734 goto ATTR_SETUNDERLINE
;
736 eUnderline
= LINESTYLE_BOLDLONGDASH
;
737 goto ATTR_SETUNDERLINE
;
739 eUnderline
= LINESTYLE_BOLDDASHDOT
;
740 goto ATTR_SETUNDERLINE
;
742 eUnderline
= LINESTYLE_BOLDDASHDOTDOT
;
743 goto ATTR_SETUNDERLINE
;
745 eUnderline
= LINESTYLE_BOLDWAVE
;
746 goto ATTR_SETUNDERLINE
;
748 eUnderline
= LINESTYLE_DOUBLEWAVE
;
749 goto ATTR_SETUNDERLINE
;
752 eUnderline
= LINESTYLE_SINGLE
;
754 if( aPlainMap
.nWordlineMode
)
756 pSet
->Put( SvxWordLineModeItem( true, aPlainMap
.nWordlineMode
));
758 goto ATTR_SETUNDERLINE
;
761 if( aPlainMap
.nUnderline
)
763 pSet
->Put( SvxUnderlineItem( eUnderline
, aPlainMap
.nUnderline
));
768 if( aPlainMap
.nUnderline
)
770 std::unique_ptr
<SvxUnderlineItem
> aUL(std::make_unique
<SvxUnderlineItem
>(LINESTYLE_SINGLE
, aPlainMap
.nUnderline
));
771 const SfxPoolItem
* pItem(nullptr);
773 if( SfxItemState::SET
== pSet
->GetItemState(aPlainMap
.nUnderline
, false, &pItem
) )
776 if( LINESTYLE_NONE
== static_cast<const SvxUnderlineItem
*>(pItem
)->GetLineStyle() )
779 aUL
.reset(static_cast<SvxUnderlineItem
*>(pItem
->Clone()));
783 aUL
.reset(static_cast<SvxUnderlineItem
*>(pSet
->Get( aPlainMap
.nUnderline
, false).Clone()));
786 if(LINESTYLE_NONE
== aUL
->GetLineStyle())
788 aUL
->SetLineStyle(LINESTYLE_SINGLE
);
791 aUL
->SetColor(GetColor(sal_uInt16(nTokenValue
)));
798 if( !IsAttrSttPos() )
800 eOverline
= nTokenValue
? LINESTYLE_SINGLE
: LINESTYLE_NONE
;
801 goto ATTR_SETOVERLINE
;
804 eOverline
= LINESTYLE_DOTTED
;
805 goto ATTR_SETOVERLINE
;
807 eOverline
= LINESTYLE_DASH
;
808 goto ATTR_SETOVERLINE
;
810 eOverline
= LINESTYLE_DASHDOT
;
811 goto ATTR_SETOVERLINE
;
813 eOverline
= LINESTYLE_DASHDOTDOT
;
814 goto ATTR_SETOVERLINE
;
816 eOverline
= LINESTYLE_DOUBLE
;
817 goto ATTR_SETOVERLINE
;
819 eOverline
= LINESTYLE_NONE
;
820 goto ATTR_SETOVERLINE
;
822 eOverline
= LINESTYLE_BOLD
;
823 goto ATTR_SETOVERLINE
;
825 eOverline
= LINESTYLE_WAVE
;
826 goto ATTR_SETOVERLINE
;
828 eOverline
= LINESTYLE_BOLDDOTTED
;
829 goto ATTR_SETOVERLINE
;
831 eOverline
= LINESTYLE_BOLDDASH
;
832 goto ATTR_SETOVERLINE
;
834 eOverline
= LINESTYLE_LONGDASH
;
835 goto ATTR_SETOVERLINE
;
837 eOverline
= LINESTYLE_BOLDLONGDASH
;
838 goto ATTR_SETOVERLINE
;
840 eOverline
= LINESTYLE_BOLDDASHDOT
;
841 goto ATTR_SETOVERLINE
;
843 eOverline
= LINESTYLE_BOLDDASHDOTDOT
;
844 goto ATTR_SETOVERLINE
;
846 eOverline
= LINESTYLE_BOLDWAVE
;
847 goto ATTR_SETOVERLINE
;
849 eOverline
= LINESTYLE_DOUBLEWAVE
;
850 goto ATTR_SETOVERLINE
;
853 eOverline
= LINESTYLE_SINGLE
;
855 if( aPlainMap
.nWordlineMode
)
857 pSet
->Put( SvxWordLineModeItem( true, aPlainMap
.nWordlineMode
));
859 goto ATTR_SETOVERLINE
;
862 if( aPlainMap
.nUnderline
)
864 pSet
->Put( SvxOverlineItem( eOverline
, aPlainMap
.nOverline
));
869 if( aPlainMap
.nOverline
)
871 std::unique_ptr
<SvxOverlineItem
> aOL(std::make_unique
<SvxOverlineItem
>(LINESTYLE_SINGLE
, aPlainMap
.nOverline
));
872 const SfxPoolItem
* pItem(nullptr);
874 if( SfxItemState::SET
== pSet
->GetItemState(aPlainMap
.nOverline
, false, &pItem
) )
877 if( LINESTYLE_NONE
== static_cast<const SvxOverlineItem
*>(pItem
)->GetLineStyle() )
880 aOL
.reset(static_cast<SvxOverlineItem
*>(pItem
->Clone()));
884 aOL
.reset(static_cast<SvxOverlineItem
*>(pSet
->Get( aPlainMap
.nOverline
, false).Clone()));
887 if(LINESTYLE_NONE
== aOL
->GetLineStyle())
889 aOL
->SetLineStyle(LINESTYLE_SINGLE
);
892 aOL
->SetColor(GetColor(sal_uInt16(nTokenValue
)));
900 if( aPlainMap
.nEscapement
)
902 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
903 if( -1 == nTokenValue
)
904 nTokenValue
= 6; //RTF default \up value in half-points
907 const SvxEscapementItem
& rOld
=
908 static_cast<const SvxEscapementItem
&>(pSet
->Get( nEsc
,false));
911 if( DFLT_ESC_AUTO_SUB
== rOld
.GetEsc() )
913 nEs
= DFLT_ESC_AUTO_SUPER
;
914 nProp
= rOld
.GetProportionalHeight();
918 nEs
= (nToken
== RTF_SUPER
) ? DFLT_ESC_AUTO_SUPER
: nTokenValue
;
919 nProp
= (nToken
== RTF_SUPER
) ? DFLT_ESC_PROP
: 100;
921 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
926 if( aPlainMap
.nColor
)
928 pSet
->Put( SvxColorItem( GetColor( sal_uInt16(nTokenValue
) ),
932 //#i12501# While cb is clearly documented in the rtf spec, word
933 //doesn't accept it at all
936 if( aPlainMap
.nBgColor
)
938 pSet
->Put( SvxBrushItem( GetColor( sal_uInt16(nTokenValue
) ),
939 aPlainMap
.nBgColor
));
945 if( aPlainMap
.nLanguage
)
947 pSet
->Put( SvxLanguageItem( LanguageType(nTokenValue
),
948 aPlainMap
.nLanguage
));
953 if( aPlainMap
.nCJKLanguage
)
955 pSet
->Put( SvxLanguageItem( LanguageType(nTokenValue
),
956 aPlainMap
.nCJKLanguage
));
961 SvxLanguageItem
aTmpItem( LanguageType(nTokenValue
),
962 SID_ATTR_CHAR_LANGUAGE
);
963 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
968 bIsLeftToRightDef
= false;
971 bIsLeftToRightDef
= true;
974 if (aPardMap
.nDirection
)
976 pSet
->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_RL_TB
,
977 aPardMap
.nDirection
));
981 if (aPardMap
.nDirection
)
983 pSet
->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
,
984 aPardMap
.nDirection
));
987 case RTF_LOCH
: eCharType
= LOW_CHARTYPE
; break;
988 case RTF_HICH
: eCharType
= HIGH_CHARTYPE
; break;
989 case RTF_DBCH
: eCharType
= DOUBLEBYTE_CHARTYPE
; break;
993 eEmphasis
= FontEmphasisMark::NONE
;
994 goto ATTR_SETEMPHASIS
;
996 eEmphasis
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
997 goto ATTR_SETEMPHASIS
;
1000 eEmphasis
= (FontEmphasisMark::Accent
| FontEmphasisMark::PosAbove
);
1002 if( aPlainMap
.nEmphasis
)
1004 pSet
->Put( SvxEmphasisMarkItem( eEmphasis
,
1005 aPlainMap
.nEmphasis
));
1010 if( aPlainMap
.nTwoLines
)
1012 sal_Unicode cStt
, cEnd
;
1013 switch ( nTokenValue
)
1015 case 1: cStt
= '('; cEnd
= ')'; break;
1016 case 2: cStt
= '['; cEnd
= ']'; break;
1017 case 3: cStt
= '<'; cEnd
= '>'; break;
1018 case 4: cStt
= '{'; cEnd
= '}'; break;
1019 default: cStt
= 0; cEnd
= 0; break;
1022 pSet
->Put( SvxTwoLinesItem( true, cStt
, cEnd
,
1023 aPlainMap
.nTwoLines
));
1027 case RTF_CHARSCALEX
:
1028 if (aPlainMap
.nCharScaleX
)
1031 if (nTokenValue
< 1 || nTokenValue
> 600)
1033 pSet
->Put( SvxCharScaleWidthItem( sal_uInt16(nTokenValue
),
1034 aPlainMap
.nCharScaleX
));
1039 if( aPlainMap
.nHorzVert
)
1041 // RTF knows only 90deg
1042 pSet
->Put( SvxCharRotateItem( Degree10(900), 1 == nTokenValue
,
1043 aPlainMap
.nHorzVert
));
1048 if (aPlainMap
.nRelief
)
1050 pSet
->Put(SvxCharReliefItem(FontRelief::Embossed
,
1051 aPlainMap
.nRelief
));
1055 if (aPlainMap
.nRelief
)
1057 pSet
->Put(SvxCharReliefItem(FontRelief::Engraved
,
1058 aPlainMap
.nRelief
));
1062 if (aPlainMap
.nHidden
)
1064 pSet
->Put(SvxCharHiddenItem(nTokenValue
!= 0,
1065 aPlainMap
.nHidden
));
1069 case RTF_CHBGDKVERT
:
1070 case RTF_CHBGDKHORIZ
:
1073 case RTF_CHBGDKFDIAG
:
1074 case RTF_CHBGDCROSS
:
1077 case RTF_CHBGDKDCROSS
:
1078 case RTF_CHBGDKCROSS
:
1079 case RTF_CHBGDKBDIAG
:
1083 if( aPlainMap
.nBgColor
)
1084 ReadBackgroundAttr( nToken
, *pSet
);
1089 // tests on Swg internal tokens
1090 bool bHandled
= false;
1092 if( RTF_IGNOREFLAG
!= GetNextToken())
1094 else if( (nToken
= GetNextToken() ) & RTF_SWGDEFS
)
1102 UnknownAttrToken( nToken
);
1103 // overwrite the closing parenthesis
1106 case RTF_SWG_ESCPROP
:
1108 // Store percentage change!
1109 sal_uInt8 nProp
= sal_uInt8( nTokenValue
/ 100 );
1111 if( 1 == ( nTokenValue
% 100 ))
1112 // Recognize own auto-flags!
1113 nEsc
= DFLT_ESC_AUTO_SUPER
;
1115 if( aPlainMap
.nEscapement
)
1116 pSet
->Put( SvxEscapementItem( nEsc
, nProp
,
1117 aPlainMap
.nEscapement
));
1123 SvxHyphenZoneItem
aHypenZone(
1124 (nTokenValue
& 1) != 0,
1125 aPardMap
.nHyphenzone
);
1126 aHypenZone
.SetPageEnd((nTokenValue
& 2) != 0);
1128 if( aPardMap
.nHyphenzone
&&
1129 RTF_HYPHLEAD
== GetNextToken() &&
1130 RTF_HYPHTRAIL
== GetNextToken() &&
1131 RTF_HYPHMAX
== GetNextToken() )
1133 aHypenZone
.GetMinLead() =
1134 sal_uInt8(GetStackPtr( -2 )->nTokenValue
);
1135 aHypenZone
.GetMinTrail() =
1136 sal_uInt8(GetStackPtr( -1 )->nTokenValue
);
1137 aHypenZone
.GetMaxHyphens() =
1138 sal_uInt8(nTokenValue
);
1140 pSet
->Put( aHypenZone
);
1143 SkipGroup(); // at the end of the group
1150 do { // middle check loop
1151 SvxShadowLocation eSL
= SvxShadowLocation( nTokenValue
);
1152 if( RTF_SHDW_DIST
!= GetNextToken() )
1154 sal_uInt16 nDist
= sal_uInt16( nTokenValue
);
1156 if( RTF_SHDW_STYLE
!= GetNextToken() )
1159 if( RTF_SHDW_COL
!= GetNextToken() )
1161 sal_uInt16 nCol
= sal_uInt16( nTokenValue
);
1163 if( RTF_SHDW_FCOL
!= GetNextToken() )
1166 Color aColor
= GetColor( nCol
);
1168 if( aPardMap
.nShadow
)
1169 pSet
->Put( SvxShadowItem( aPardMap
.nShadow
,
1170 &aColor
, nDist
, eSL
) );
1176 SkipGroup(); // at the end of the group
1182 if( (nToken
& ~(0xff | RTF_SWGDEFS
)) == RTF_TABSTOPDEF
)
1184 nToken
= SkipToken( -2 );
1185 ReadTabAttr( nToken
, *pSet
);
1188 cmc: #i76140, he who consumed the { must consume the }
1189 We rewound to a state of { being the current
1190 token so it is our responsibility to consume the }
1191 token if we consumed the {. We will not have consumed
1192 the { if it belonged to our caller, i.e. if the { we
1193 are handling is the "firsttoken" passed to us then
1194 the *caller* must consume it, not us. Otherwise *we*
1197 if (nToken
== BRACELEFT
&& !bFirstToken
)
1199 nToken
= GetNextToken();
1200 SAL_WARN_IF( nToken
!= BRACERIGHT
,
1202 "} did not follow { as expected");
1205 else if( (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
)
1207 nToken
= SkipToken( -2 );
1208 ReadBorderAttr( nToken
, *pSet
);
1210 else // so no more attribute
1217 cmc: #i4727# / #i12713# Who owns this closing bracket?
1218 If we read the opening one, we must read this one, if
1219 other is counting the brackets so as to push/pop off
1220 the correct environment then we will have pushed a new
1221 environment for the start { of this, but will not see
1222 the } and so is out of sync for the rest of the
1225 if (bHandled
&& !bFirstToken
)
1232 if( nSkip
) // all completely unknown
1235 --nSkip
; // BRACELEFT: is the next token
1242 if( (nToken
& ~0xff ) == RTF_TABSTOPDEF
)
1243 ReadTabAttr( nToken
, *pSet
);
1244 else if( (nToken
& ~0xff ) == RTF_BRDRDEF
)
1245 ReadBorderAttr( nToken
, *pSet
);
1246 else if( (nToken
& ~0xff ) == RTF_SHADINGDEF
)
1247 ReadBackgroundAttr( nToken
, *pSet
);
1250 // unknown token, so token "returned in Parser"
1259 nToken
= GetNextToken();
1261 bFirstToken
= false;
1265 void SvxRTFParser::ReadTabAttr( int nToken
, SfxItemSet
& rSet
)
1267 bool bMethodOwnsToken
= false; // #i52542# patch from cmc.
1268 // then read all the TabStops
1269 SvxTabStop aTabStop
;
1270 SvxTabStopItem
aAttr( 0, 0, SvxTabAdjust::Default
, aPardMap
.nTabStop
);
1271 bool bContinue
= true;
1275 case RTF_TB
: // BarTab ???
1280 aTabStop
.GetTabPos() = nTokenValue
;
1281 aAttr
.Insert( aTabStop
);
1282 aTabStop
= SvxTabStop(); // all values default
1287 aTabStop
.GetAdjustment() = SvxTabAdjust::Left
;
1290 aTabStop
.GetAdjustment() = SvxTabAdjust::Right
;
1293 aTabStop
.GetAdjustment() = SvxTabAdjust::Center
;
1296 aTabStop
.GetAdjustment() = SvxTabAdjust::Decimal
;
1299 case RTF_TLDOT
: aTabStop
.GetFill() = '.'; break;
1300 case RTF_TLHYPH
: aTabStop
.GetFill() = ' '; break;
1301 case RTF_TLUL
: aTabStop
.GetFill() = '_'; break;
1302 case RTF_TLTH
: aTabStop
.GetFill() = '-'; break;
1303 case RTF_TLEQ
: aTabStop
.GetFill() = '='; break;
1307 // Swg - control BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1309 if( RTF_IGNOREFLAG
!= GetNextToken() )
1311 else if( RTF_TLSWG
!= ( nToken
= GetNextToken() ))
1315 aTabStop
.GetDecimal() = sal_uInt8(nTokenValue
& 0xff);
1316 aTabStop
.GetFill() = sal_uInt8((nTokenValue
>> 8) & 0xff);
1317 // overwrite the closing parenthesis
1318 if (bMethodOwnsToken
)
1323 SkipToken( nSkip
); // Ignore back again
1334 nToken
= GetNextToken();
1335 bMethodOwnsToken
= true;
1337 } while( bContinue
);
1339 // Fill with defaults is still missing!
1344 static void SetBorderLine( int nBorderTyp
, SvxBoxItem
& rItem
,
1345 const SvxBorderLine
& rBorder
)
1347 switch( nBorderTyp
)
1349 case RTF_BOX
: // run through all levels
1351 rItem
.SetLine( &rBorder
, SvxBoxItemLine::TOP
);
1352 if( RTF_BOX
!= nBorderTyp
)
1356 rItem
.SetLine( &rBorder
, SvxBoxItemLine::BOTTOM
);
1357 if( RTF_BOX
!= nBorderTyp
)
1361 rItem
.SetLine( &rBorder
, SvxBoxItemLine::LEFT
);
1362 if( RTF_BOX
!= nBorderTyp
)
1366 rItem
.SetLine( &rBorder
, SvxBoxItemLine::RIGHT
);
1367 if( RTF_BOX
!= nBorderTyp
)
1372 void SvxRTFParser::ReadBorderAttr( int nToken
, SfxItemSet
& rSet
,
1375 // then read the border attribute
1376 std::unique_ptr
<SvxBoxItem
> aAttr(std::make_unique
<SvxBoxItem
>(aPardMap
.nBox
));
1377 const SfxPoolItem
* pItem(nullptr);
1379 if( SfxItemState::SET
== rSet
.GetItemState( aPardMap
.nBox
, false, &pItem
) )
1381 aAttr
.reset(static_cast<SvxBoxItem
*>(pItem
->Clone()));
1384 SvxBorderLine
aBrd( nullptr, DEF_LINE_WIDTH_0
); // Simple plain line
1385 bool bContinue
= true;
1388 tools::Long nWidth
= 1;
1389 bool bDoubleWidth
= false;
1399 nBorderTyp
= nToken
;
1402 case RTF_CLBRDRT
: // Cell top border
1406 if (nBorderTyp
!= 0)
1407 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1408 nBorderTyp
= RTF_BRDRT
;
1412 case RTF_CLBRDRB
: // Cell bottom border
1416 if (nBorderTyp
!= 0)
1417 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1418 nBorderTyp
= RTF_BRDRB
;
1422 case RTF_CLBRDRL
: // Cell left border
1426 if (nBorderTyp
!= 0)
1427 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1428 nBorderTyp
= RTF_BRDRL
;
1432 case RTF_CLBRDRR
: // Cell right border
1436 if (nBorderTyp
!= 0)
1437 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1438 nBorderTyp
= RTF_BRDRR
;
1443 case RTF_BRDRDOT
: // dotted border
1444 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DOTTED
);
1446 case RTF_BRDRDASH
: // dashed border
1447 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DASHED
);
1449 case RTF_BRDRHAIR
: // hairline border
1451 aBrd
.SetBorderLineStyle( SvxBorderLineStyle::SOLID
);
1452 aBrd
.SetWidth( DEF_LINE_WIDTH_0
);
1455 case RTF_BRDRDB
: // Double border
1456 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE
);
1458 case RTF_BRDRINSET
: // inset border
1459 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::INSET
);
1461 case RTF_BRDROUTSET
: // outset border
1462 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::OUTSET
);
1464 case RTF_BRDRTNTHSG
: // ThinThick Small gap
1465 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_SMALLGAP
);
1467 case RTF_BRDRTNTHMG
: // ThinThick Medium gap
1468 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_MEDIUMGAP
);
1470 case RTF_BRDRTNTHLG
: // ThinThick Large gap
1471 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_LARGEGAP
);
1473 case RTF_BRDRTHTNSG
: // ThickThin Small gap
1474 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_SMALLGAP
);
1476 case RTF_BRDRTHTNMG
: // ThickThin Medium gap
1477 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
);
1479 case RTF_BRDRTHTNLG
: // ThickThin Large gap
1480 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_LARGEGAP
);
1482 case RTF_BRDREMBOSS
: // Embossed border
1483 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::EMBOSSED
);
1485 case RTF_BRDRENGRAVE
: // Engraved border
1486 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::ENGRAVED
);
1489 case RTF_BRDRS
: // single thickness border
1490 bDoubleWidth
= false;
1492 case RTF_BRDRTH
: // double thickness border width*2
1493 bDoubleWidth
= true;
1495 case RTF_BRDRW
: // border width <255
1496 nWidth
= nTokenValue
;
1499 case RTF_BRDRCF
: // Border color
1500 aBrd
.SetColor( GetColor( sal_uInt16(nTokenValue
) ) );
1503 case RTF_BRDRSH
: // Shadowed border
1504 rSet
.Put( SvxShadowItem( aPardMap
.nShadow
, nullptr, 60 /*3pt*/,
1505 SvxShadowLocation::BottomRight
) );
1508 case RTF_BRSP
: // Spacing to content in twip
1510 switch( nBorderTyp
)
1513 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::BOTTOM
);
1517 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::TOP
);
1521 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::LEFT
);
1525 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::RIGHT
);
1529 aAttr
->SetAllDistances( static_cast<sal_uInt16
>(nTokenValue
) );
1535 case RTF_BRDRBTW
: // Border formatting group
1536 case RTF_BRDRBAR
: // Border outside
1537 // TODO unhandled ATM
1541 bContinue
= (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
;
1544 nToken
= GetNextToken();
1545 } while( bContinue
);
1547 // Finally compute the border width
1548 if ( bDoubleWidth
) nWidth
*= 2;
1549 aBrd
.SetWidth( nWidth
);
1551 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1557 static sal_uInt32
CalcShading( sal_uInt32 nColor
, sal_uInt32 nFillColor
, sal_uInt8 nShading
)
1559 nColor
= (nColor
* nShading
) / 100;
1560 nFillColor
= (nFillColor
* ( 100 - nShading
)) / 100;
1561 return nColor
+ nFillColor
;
1564 void SvxRTFParser::ReadBackgroundAttr( int nToken
, SfxItemSet
& rSet
,
1567 // then read the border attribute
1568 bool bContinue
= true;
1569 sal_uInt16 nColor
= USHRT_MAX
, nFillColor
= USHRT_MAX
;
1570 sal_uInt8 nFillValue
= 0;
1572 sal_uInt16 nWh
= ( nToken
& ~0xff ) == RTF_CHRFMT
1573 ? aPlainMap
.nBgColor
1582 nFillColor
= sal_uInt16( nTokenValue
);
1588 nColor
= sal_uInt16( nTokenValue
);
1594 nFillValue
= static_cast<sal_uInt8
>( nTokenValue
/ 100 );
1598 case RTF_CHBGDKHORIZ
:
1600 case RTF_CLBGDKVERT
:
1601 case RTF_CHBGDKVERT
:
1603 case RTF_CLBGDKBDIAG
:
1604 case RTF_CHBGDKBDIAG
:
1606 case RTF_CLBGDKFDIAG
:
1607 case RTF_CHBGDKFDIAG
:
1609 case RTF_CLBGDKCROSS
:
1610 case RTF_CHBGDKCROSS
:
1612 case RTF_CLBGDKDCROSS
:
1613 case RTF_CHBGDKDCROSS
:
1614 case RTF_BGDKDCROSS
:
1634 case RTF_CLBGDCROSS
:
1635 case RTF_CHBGDCROSS
:
1643 bContinue
= (nToken
& ~(0xff | RTF_TABLEDEF
) ) == RTF_SHADINGDEF
;
1645 bContinue
= (nToken
& ~0xff) == RTF_SHADINGDEF
;
1648 nToken
= GetNextToken();
1649 } while( bContinue
);
1651 Color
aCol( COL_WHITE
), aFCol
;
1654 // there was only one of two colors specified or no BrushType
1655 if( USHRT_MAX
!= nFillColor
)
1658 aCol
= GetColor( nFillColor
);
1660 else if( USHRT_MAX
!= nColor
)
1661 aFCol
= GetColor( nColor
);
1665 if( USHRT_MAX
!= nColor
)
1666 aCol
= GetColor( nColor
);
1670 if( USHRT_MAX
!= nFillColor
)
1671 aFCol
= GetColor( nFillColor
);
1677 if( 0 == nFillValue
|| 100 == nFillValue
)
1681 static_cast<sal_uInt8
>(CalcShading( aCol
.GetRed(), aFCol
.GetRed(), nFillValue
)),
1682 static_cast<sal_uInt8
>(CalcShading( aCol
.GetGreen(), aFCol
.GetGreen(), nFillValue
)),
1683 static_cast<sal_uInt8
>(CalcShading( aCol
.GetBlue(), aFCol
.GetBlue(), nFillValue
)) );
1685 rSet
.Put( SvxBrushItem( aColor
, nWh
) );
1690 // pard / plain handling
1691 void SvxRTFParser::RTFPardPlain( bool const bPard
, SfxItemSet
** ppSet
)
1693 if( bNewGroup
|| aAttrStack
.empty() ) // not at the beginning of a new group
1696 SvxRTFItemStackType
* pCurrent
= aAttrStack
.back().get();
1698 int nLastToken
= GetStackPtr(-1)->nTokenId
;
1699 bool bNewStkEntry
= true;
1700 if( RTF_PARD
!= nLastToken
&&
1701 RTF_PLAIN
!= nLastToken
&&
1702 BRACELEFT
!= nLastToken
)
1704 if (pCurrent
->aAttrSet
.Count() || pCurrent
->m_pChildList
|| pCurrent
->nStyleNo
)
1707 std::unique_ptr
<SvxRTFItemStackType
> pNew(new SvxRTFItemStackType( *pCurrent
, *pInsPos
, true ));
1708 pNew
->SetRTFDefaults( GetRTFDefaults() );
1710 // Set all until here valid attributes
1712 pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get(); // can be changed after AttrGroupEnd!
1713 pNew
->aAttrSet
.SetParent( pCurrent
? &pCurrent
->aAttrSet
: nullptr );
1714 aAttrStack
.push_back( std::move(pNew
) );
1715 pCurrent
= aAttrStack
.back().get();
1719 // continue to use this entry as new
1720 pCurrent
->SetStartPos( *pInsPos
);
1721 bNewStkEntry
= false;
1725 // now reset all to default
1727 ( pCurrent
->aAttrSet
.GetParent() || pCurrent
->aAttrSet
.Count() ))
1729 const SfxPoolItem
*pItem
, *pDef
;
1730 const sal_uInt16
* pPtr
;
1732 const SfxItemSet
* pDfltSet
= &GetRTFDefaults();
1735 pCurrent
->nStyleNo
= 0;
1736 pPtr
= reinterpret_cast<sal_uInt16
*>(&aPardMap
);
1737 nCnt
= sizeof(aPardMap
) / sizeof(sal_uInt16
);
1741 pPtr
= reinterpret_cast<sal_uInt16
*>(&aPlainMap
);
1742 nCnt
= sizeof(aPlainMap
) / sizeof(sal_uInt16
);
1745 for( sal_uInt16 n
= 0; n
< nCnt
; ++n
, ++pPtr
)
1747 // Item set and different -> Set the Default Pool
1750 else if (SfxItemPool::IsSlot(*pPtr
))
1751 pCurrent
->aAttrSet
.ClearItem( *pPtr
);
1752 else if( IsChkStyleAttr() )
1753 pCurrent
->aAttrSet
.Put( pDfltSet
->Get( *pPtr
) );
1754 else if( !pCurrent
->aAttrSet
.GetParent() )
1756 if( SfxItemState::SET
==
1757 pDfltSet
->GetItemState( *pPtr
, false, &pDef
))
1758 pCurrent
->aAttrSet
.Put( *pDef
);
1760 pCurrent
->aAttrSet
.ClearItem( *pPtr
);
1762 else if( SfxItemState::SET
== pCurrent
->aAttrSet
.GetParent()->
1763 GetItemState( *pPtr
, true, &pItem
) &&
1764 *( pDef
= &pDfltSet
->Get( *pPtr
)) != *pItem
)
1765 pCurrent
->aAttrSet
.Put( *pDef
);
1768 if( SfxItemState::SET
==
1769 pDfltSet
->GetItemState( *pPtr
, false, &pDef
))
1770 pCurrent
->aAttrSet
.Put( *pDef
);
1772 pCurrent
->aAttrSet
.ClearItem( *pPtr
);
1777 pCurrent
->nStyleNo
= 0; // reset Style number
1779 *ppSet
= &pCurrent
->aAttrSet
;
1784 //Once we have a default font, then any text without a font specifier is
1785 //in the default font, and thus has the default font charset, otherwise
1786 //we can fall back to the ansicpg set codeset
1787 if (nDfltFont
!= -1)
1789 const vcl::Font
& rSVFont
= GetFont(sal_uInt16(nDfltFont
));
1790 SetEncoding(rSVFont
.GetCharSet());
1793 SetEncoding(GetCodeSet());
1796 void SvxRTFParser::SetDefault( int nToken
, int nValue
)
1801 SfxItemSet
aTmp( *pAttrPool
, aWhichMap
.data() );
1802 bool bOldFlag
= bIsLeftToRightDef
;
1803 bIsLeftToRightDef
= true;
1807 bIsLeftToRightDef
= false;
1813 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nValue
) );
1814 SvxFontItem
aTmpItem(
1815 rSVFont
.GetFamilyType(), rSVFont
.GetFamilyName(),
1816 rSVFont
.GetStyleName(), rSVFont
.GetPitch(),
1817 rSVFont
.GetCharSet(), SID_ATTR_CHAR_FONT
);
1818 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1823 bIsLeftToRightDef
= false;
1826 // store default Language
1829 SvxLanguageItem
aTmpItem( LanguageType(nValue
), SID_ATTR_CHAR_LANGUAGE
);
1830 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1835 if( aPardMap
.nTabStop
)
1837 // RTF defines 720 twips as default
1838 bIsSetDfltTab
= true;
1839 if( -1 == nValue
|| !nValue
)
1842 // who would like to have no twips ...
1845 nTokenValue
= nValue
;
1847 nValue
= nTokenValue
;
1850 // Calculate the ratio of default TabWidth / Tabs and
1851 // calculate the corresponding new number.
1852 // ?? how did one come up with 13 ??
1853 sal_uInt16 nTabCount
= (SVX_TAB_DEFDIST
* 13 ) / sal_uInt16(nValue
);
1855 cmc, make sure we have at least one, or all hell breaks loose in
1856 everybody exporters, #i8247#
1861 // we want Defaulttabs
1862 SvxTabStopItem
aNewTab( nTabCount
, sal_uInt16(nValue
),
1863 SvxTabAdjust::Default
, aPardMap
.nTabStop
);
1865 const_cast<SvxTabStop
&>(aNewTab
[ --nTabCount
]).GetAdjustment() = SvxTabAdjust::Default
;
1867 pAttrPool
->SetPoolDefaultItem( aNewTab
);
1871 bIsLeftToRightDef
= bOldFlag
;
1875 SfxItemIter
aIter( aTmp
);
1876 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1879 pAttrPool
->SetPoolDefaultItem( *pItem
);
1880 pItem
= aIter
.NextItem();
1885 // default: no conversion, leaving everything in twips.
1886 void SvxRTFParser::CalcValue()
1890 // for tokens that are not evaluated in ReadAttr
1891 void SvxRTFParser::UnknownAttrToken( int )
1895 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */