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 std::optional
<sal_uInt16
> pNormal
;
81 std::optional
<sal_uInt16
> pCJK
;
82 std::optional
<sal_uInt16
> pCTL
;
83 switch( rItem
.Which() )
85 case SID_ATTR_CHAR_FONT
:
86 pNormal
= aPlainMap
[SID_ATTR_CHAR_FONT
];
87 pCJK
= aPlainMap
[SID_ATTR_CHAR_CJK_FONT
];
88 pCTL
= aPlainMap
[SID_ATTR_CHAR_CTL_FONT
];
91 case SID_ATTR_CHAR_FONTHEIGHT
:
92 pNormal
= aPlainMap
[SID_ATTR_CHAR_FONTHEIGHT
];
93 pCJK
= aPlainMap
[SID_ATTR_CHAR_CJK_FONTHEIGHT
];
94 pCTL
= aPlainMap
[SID_ATTR_CHAR_CTL_FONTHEIGHT
];
97 case SID_ATTR_CHAR_POSTURE
:
98 pNormal
= aPlainMap
[SID_ATTR_CHAR_POSTURE
];
99 pCJK
= aPlainMap
[SID_ATTR_CHAR_CJK_POSTURE
];
100 pCTL
= aPlainMap
[SID_ATTR_CHAR_CTL_POSTURE
];
103 case SID_ATTR_CHAR_WEIGHT
:
104 pNormal
= aPlainMap
[SID_ATTR_CHAR_WEIGHT
];
105 pCJK
= aPlainMap
[SID_ATTR_CHAR_CJK_WEIGHT
];
106 pCTL
= aPlainMap
[SID_ATTR_CHAR_CTL_WEIGHT
];
109 case SID_ATTR_CHAR_LANGUAGE
:
110 pNormal
= aPlainMap
[SID_ATTR_CHAR_LANGUAGE
];
111 pCJK
= aPlainMap
[SID_ATTR_CHAR_CJK_LANGUAGE
];
112 pCTL
= aPlainMap
[SID_ATTR_CHAR_CTL_LANGUAGE
];
116 // it exist no WhichId - don't set this item
124 if( DOUBLEBYTE_CHARTYPE
== eType
)
126 if( bIsLeftToRightDef
&& pCJK
)
128 rItem
.SetWhich( *pCJK
);
132 else if( !bIsLeftToRightDef
)
136 rItem
.SetWhich( *pCTL
);
142 if( LOW_CHARTYPE
== eType
)
146 rItem
.SetWhich( *pNormal
);
150 else if( HIGH_CHARTYPE
== eType
)
154 rItem
.SetWhich( *pCTL
);
162 rItem
.SetWhich( *pCJK
);
167 rItem
.SetWhich( *pCTL
);
172 rItem
.SetWhich( *pNormal
);
180 void SvxRTFParser::ReadAttr( int nToken
, SfxItemSet
* pSet
)
182 DBG_ASSERT( pSet
, "A SfxItemSet has to be provided as argument!" );
183 bool bFirstToken
= true;
184 bool bContinue
= true;
185 FontLineStyle eUnderline
;
186 FontLineStyle eOverline
;
187 FontEmphasisMark eEmphasis
;
188 RTF_CharTypeDef eCharType
= NOTDEF_CHARTYPE
;
189 SvxParaVertAlignItem::Align nFontAlign
;
191 bool bChkStkPos
= !bNewGroup
&& !aAttrStack
.empty();
193 while( bContinue
&& IsParserWorking() ) // as long as known Attribute are recognized
198 RTFPardPlain( true, &pSet
);
202 RTFPardPlain( false, &pSet
);
206 do { // middle checked loop
210 SvxRTFItemStackType
* pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get();
211 if( !pCurrent
|| (pCurrent
->mxStartNodeIdx
->GetIdx() == mxInsertPosition
->GetNodeIdx() &&
212 pCurrent
->nSttCnt
== mxInsertPosition
->GetCntIdx() ))
215 int nLastToken
= GetStackPtr(-1)->nTokenId
;
216 if( RTF_PARD
== nLastToken
|| RTF_PLAIN
== nLastToken
)
219 if (pCurrent
->aAttrSet
.Count() || !pCurrent
->maChildList
.empty() ||
223 auto xNew(std::make_unique
<SvxRTFItemStackType
>(*pCurrent
, *mxInsertPosition
, true));
224 xNew
->SetRTFDefaults( GetRTFDefaults() );
226 // "Set" all valid attributes up until this point
228 pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get(); // can be changed after AttrGroupEnd!
229 xNew
->aAttrSet
.SetParent( pCurrent
? &pCurrent
->aAttrSet
: nullptr );
231 aAttrStack
.push_back( std::move(xNew
) );
232 pCurrent
= aAttrStack
.back().get();
235 // continue to use this entry as a new one
236 pCurrent
->SetStartPos( *mxInsertPosition
);
238 pSet
= &pCurrent
->aAttrSet
;
249 UnknownAttrToken( nToken
);
253 if( bIsInReadStyleTab
)
261 sal_uInt16 nStyleNo
= -1 == nTokenValue
? 0 : sal_uInt16(nTokenValue
);
262 // set StyleNo to the current style on the AttrStack
263 SvxRTFItemStackType
* pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get();
267 pCurrent
->nStyleNo
= nStyleNo
;
272 if (const TypedWhichId
<SvxFormatSplitItem
> wid
= aPardMap
[SID_ATTR_PARA_SPLIT
])
274 pSet
->Put(SvxFormatSplitItem(false, wid
));
279 if (const TypedWhichId
<SvxFormatKeepItem
> wid
= aPardMap
[SID_ATTR_PARA_KEEP
])
281 pSet
->Put(SvxFormatKeepItem(true, wid
));
286 if (const TypedWhichId
<SfxInt16Item
> wid
= aPardMap
[SID_ATTR_PARA_OUTLLEVEL
])
288 pSet
->Put(SfxInt16Item(wid
, static_cast<sal_uInt16
>(nTokenValue
)));
293 if (const TypedWhichId
<SvxAdjustItem
> wid
= aPardMap
[SID_ATTR_PARA_ADJUST
])
295 pSet
->Put(SvxAdjustItem(SvxAdjust::Left
, wid
));
299 if (const TypedWhichId
<SvxAdjustItem
> wid
= aPardMap
[SID_ATTR_PARA_ADJUST
])
301 pSet
->Put(SvxAdjustItem(SvxAdjust::Right
, wid
));
305 if (const TypedWhichId
<SvxAdjustItem
> wid
= aPardMap
[SID_ATTR_PARA_ADJUST
])
307 pSet
->Put(SvxAdjustItem(SvxAdjust::Block
, wid
));
311 if (const TypedWhichId
<SvxAdjustItem
> wid
= aPardMap
[SID_ATTR_PARA_ADJUST
])
313 pSet
->Put(SvxAdjustItem(SvxAdjust::Center
, wid
));
318 if (const TypedWhichId
<SvxLRSpaceItem
> wid
= aPardMap
[SID_ATTR_LRSPACE
])
320 SvxLRSpaceItem
aLR(pSet
->Get(wid
));
322 if( -1 != nTokenValue
)
326 nSz
= sal_uInt16(nTokenValue
);
328 aLR
.SetTextFirstLineOffset( nSz
);
335 if (const TypedWhichId
<SvxLRSpaceItem
> wid
= aPardMap
[SID_ATTR_LRSPACE
])
337 SvxLRSpaceItem
aLR(pSet
->Get(wid
));
339 if( 0 < nTokenValue
)
343 nSz
= sal_uInt16(nTokenValue
);
345 aLR
.SetTextLeft( nSz
);
352 if (const TypedWhichId
<SvxLRSpaceItem
> wid
= aPardMap
[SID_ATTR_LRSPACE
])
354 SvxLRSpaceItem
aLR(pSet
->Get(wid
));
356 if( 0 < nTokenValue
)
360 nSz
= sal_uInt16(nTokenValue
);
368 if (const TypedWhichId
<SvxULSpaceItem
> wid
= aPardMap
[SID_ATTR_ULSPACE
])
370 SvxULSpaceItem
aUL(pSet
->Get(wid
));
372 if( 0 < nTokenValue
)
376 nSz
= sal_uInt16(nTokenValue
);
384 if (const TypedWhichId
<SvxULSpaceItem
> wid
= aPardMap
[SID_ATTR_ULSPACE
])
386 SvxULSpaceItem
aUL(pSet
->Get(wid
));
388 if( 0 < nTokenValue
)
392 nSz
= sal_uInt16(nTokenValue
);
400 if (const TypedWhichId
<SvxLineSpacingItem
> wid
= aPardMap
[SID_ATTR_PARA_LINESPACE
];
401 wid
&& 1 == nTokenValue
)
403 // then switches to multi-line!
404 SvxLineSpacingItem
aLSpace(pSet
->Get(wid
, false));
406 // how much do you get from the line height value?
408 // Proportional-Size:
409 // Ie, the ratio is (n / 240) twips
415 nTokenValue
= short( 100 * aLSpace
.GetLineHeight() / nTokenValue
);
417 aLSpace
.SetPropLineSpace( static_cast<sal_uInt16
>(nTokenValue
) );
418 aLSpace
.SetLineSpaceRule( SvxLineSpaceRule::Auto
);
420 pSet
->Put( aLSpace
);
425 if (const TypedWhichId
<SvxLineSpacingItem
> wid
= aPardMap
[SID_ATTR_PARA_LINESPACE
])
427 // Calculate the ratio between the default font and the
428 // specified size. The distance consists of the line height
429 // (100%) and the space above the line (20%).
430 SvxLineSpacingItem
aLSpace(0, wid
);
432 nTokenValue
= !bTokenHasValue
? 0 : nTokenValue
;
433 if (1000 == nTokenValue
)
436 SvxLineSpaceRule eLnSpc
;
439 eLnSpc
= SvxLineSpaceRule::Fix
;
440 nTokenValue
= -nTokenValue
;
442 else if (nTokenValue
== 0)
444 //if \sl0 is used, the line spacing is automatically
446 eLnSpc
= SvxLineSpaceRule::Auto
;
449 eLnSpc
= SvxLineSpaceRule::Min
;
454 if (eLnSpc
!= SvxLineSpaceRule::Auto
)
455 aLSpace
.SetLineHeight( static_cast<sal_uInt16
>(nTokenValue
) );
457 aLSpace
.SetLineSpaceRule(eLnSpc
);
463 if (const TypedWhichId
<SvxForbiddenRuleItem
> wid
= aPardMap
[SID_ATTR_PARA_FORBIDDEN_RULES
])
465 pSet
->Put(SvxForbiddenRuleItem(false, wid
));
469 if (const TypedWhichId
<SvxHangingPunctuationItem
> wid
= aPardMap
[SID_ATTR_PARA_HANGPUNCTUATION
])
471 pSet
->Put(SvxHangingPunctuationItem(false, wid
));
476 if (const TypedWhichId
<SvxScriptSpaceItem
> wid
= aPardMap
[SID_ATTR_PARA_SCRIPTSPACE
])
478 pSet
->Put(SvxScriptSpaceItem(true, wid
));
483 case RTF_FAAUTO
: nFontAlign
= SvxParaVertAlignItem::Align::Automatic
;
484 goto SET_FONTALIGNMENT
;
485 case RTF_FAHANG
: nFontAlign
= SvxParaVertAlignItem::Align::Top
;
486 goto SET_FONTALIGNMENT
;
487 case RTF_FAVAR
: nFontAlign
= SvxParaVertAlignItem::Align::Bottom
;
488 goto SET_FONTALIGNMENT
;
489 case RTF_FACENTER
: nFontAlign
= SvxParaVertAlignItem::Align::Center
;
490 goto SET_FONTALIGNMENT
;
491 case RTF_FAROMAN
: nFontAlign
= SvxParaVertAlignItem::Align::Baseline
;
492 goto SET_FONTALIGNMENT
;
494 if (const TypedWhichId
<SvxParaVertAlignItem
> wid
= aPardMap
[SID_PARA_VERTALIGN
])
496 pSet
->Put(SvxParaVertAlignItem(nFontAlign
, wid
));
502 if( IsAttrSttPos() ) // not in the text flow?
505 SvxWeightItem
aTmpItem(
506 nTokenValue
? WEIGHT_BOLD
: WEIGHT_NORMAL
,
507 SID_ATTR_CHAR_WEIGHT
);
508 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
514 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_CASEMAP
];
515 wid
&& IsAttrSttPos()) // not in the text flow?
519 eCaseMap
= SvxCaseMap::NotMapped
;
520 else if( RTF_CAPS
== nToken
)
521 eCaseMap
= SvxCaseMap::Uppercase
;
523 eCaseMap
= SvxCaseMap::SmallCaps
;
525 pSet
->Put(SvxCaseMapItem(eCaseMap
, wid
));
531 if (const sal_uInt16 nEsc
= aPlainMap
[SID_ATTR_CHAR_ESCAPEMENT
])
533 if( -1 == nTokenValue
)
534 nTokenValue
= 6; //RTF default \dn value in half-points
537 const SvxEscapementItem
& rOld
=
538 static_cast<const SvxEscapementItem
&>(pSet
->Get( nEsc
,false));
541 if( DFLT_ESC_AUTO_SUPER
== rOld
.GetEsc() )
543 nEs
= DFLT_ESC_AUTO_SUB
;
544 nProp
= rOld
.GetProportionalHeight();
548 nEs
= (nToken
== RTF_SUB
) ? DFLT_ESC_AUTO_SUB
: -nTokenValue
;
549 nProp
= (nToken
== RTF_SUB
) ? DFLT_ESC_PROP
: 100;
551 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
556 if (const sal_uInt16 nEsc
= aPlainMap
[SID_ATTR_CHAR_ESCAPEMENT
])
558 pSet
->Put( SvxEscapementItem( nEsc
));
563 if (TypedWhichId
<SvxKerningItem
> wid
= aPlainMap
[SID_ATTR_CHAR_KERNING
])
565 if( -1 == nTokenValue
)
571 pSet
->Put(SvxKerningItem(static_cast<short>(nTokenValue
), wid
));
576 if (const TypedWhichId
<SvxAutoKernItem
> wid
= aPlainMap
[SID_ATTR_CHAR_AUTOKERN
])
578 if( -1 == nTokenValue
)
584 pSet
->Put(SvxAutoKernItem(0 != nTokenValue
, wid
));
589 if (TypedWhichId
<SvxKerningItem
> wid
= aPlainMap
[SID_ATTR_CHAR_KERNING
])
591 if( -1 == nTokenValue
)
595 pSet
->Put(SvxKerningItem(static_cast<short>(nTokenValue
), wid
));
602 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nTokenValue
) );
603 SvxFontItem
aTmpItem( rSVFont
.GetFamilyType(),
604 rSVFont
.GetFamilyName(), rSVFont
.GetStyleName(),
605 rSVFont
.GetPitch(), rSVFont
.GetCharSet(),
606 SID_ATTR_CHAR_FONT
);
607 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
608 if( RTF_F
== nToken
)
610 SetEncoding( rSVFont
.GetCharSet() );
619 if( -1 == nTokenValue
)
624 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
625 // the conversion takes now place in EditRTFParser since for other reasons
626 // the wrong MapUnit might still be use there
627 // if( IsCalcValue() )
629 SvxFontHeightItem
aTmpItem(
630 static_cast<sal_uInt16
>(nTokenValue
), 100,
631 SID_ATTR_CHAR_FONTHEIGHT
);
632 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
638 if( IsAttrSttPos() ) // not in the text flow?
640 SvxPostureItem
aTmpItem(
641 nTokenValue
? ITALIC_NORMAL
: ITALIC_NONE
,
642 SID_ATTR_CHAR_POSTURE
);
643 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
648 if (const TypedWhichId
<SvxContourItem
> wid
= aPlainMap
[SID_ATTR_CHAR_CONTOUR
];
649 wid
&& IsAttrSttPos()) // not in the text flow?
651 pSet
->Put(SvxContourItem(nTokenValue
!= 0, wid
));
656 if (const TypedWhichId
<SvxShadowedItem
> wid
= aPlainMap
[SID_ATTR_CHAR_SHADOWED
];
657 wid
&& IsAttrSttPos()) // not in the text flow?
659 pSet
->Put(SvxShadowedItem(nTokenValue
!= 0, wid
));
664 if (const TypedWhichId
<SvxCrossedOutItem
> wid
= aPlainMap
[SID_ATTR_CHAR_STRIKEOUT
];
665 wid
&& IsAttrSttPos()) // not in the text flow?
667 pSet
->Put( SvxCrossedOutItem(
668 nTokenValue
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
,
674 if (const TypedWhichId
<SvxCrossedOutItem
> wid
= aPlainMap
[SID_ATTR_CHAR_STRIKEOUT
]) // not in the text flow?
676 pSet
->Put( SvxCrossedOutItem(
677 nTokenValue
? STRIKEOUT_DOUBLE
: STRIKEOUT_NONE
,
683 if( !IsAttrSttPos() )
685 eUnderline
= nTokenValue
? LINESTYLE_SINGLE
: LINESTYLE_NONE
;
686 goto ATTR_SETUNDERLINE
;
689 eUnderline
= LINESTYLE_DOTTED
;
690 goto ATTR_SETUNDERLINE
;
692 eUnderline
= LINESTYLE_DASH
;
693 goto ATTR_SETUNDERLINE
;
695 eUnderline
= LINESTYLE_DASHDOT
;
696 goto ATTR_SETUNDERLINE
;
698 eUnderline
= LINESTYLE_DASHDOTDOT
;
699 goto ATTR_SETUNDERLINE
;
701 eUnderline
= LINESTYLE_DOUBLE
;
702 goto ATTR_SETUNDERLINE
;
704 eUnderline
= LINESTYLE_NONE
;
705 goto ATTR_SETUNDERLINE
;
707 eUnderline
= LINESTYLE_BOLD
;
708 goto ATTR_SETUNDERLINE
;
710 eUnderline
= LINESTYLE_WAVE
;
711 goto ATTR_SETUNDERLINE
;
713 eUnderline
= LINESTYLE_BOLDDOTTED
;
714 goto ATTR_SETUNDERLINE
;
716 eUnderline
= LINESTYLE_BOLDDASH
;
717 goto ATTR_SETUNDERLINE
;
719 eUnderline
= LINESTYLE_LONGDASH
;
720 goto ATTR_SETUNDERLINE
;
722 eUnderline
= LINESTYLE_BOLDLONGDASH
;
723 goto ATTR_SETUNDERLINE
;
725 eUnderline
= LINESTYLE_BOLDDASHDOT
;
726 goto ATTR_SETUNDERLINE
;
728 eUnderline
= LINESTYLE_BOLDDASHDOTDOT
;
729 goto ATTR_SETUNDERLINE
;
731 eUnderline
= LINESTYLE_BOLDWAVE
;
732 goto ATTR_SETUNDERLINE
;
734 eUnderline
= LINESTYLE_DOUBLEWAVE
;
735 goto ATTR_SETUNDERLINE
;
738 eUnderline
= LINESTYLE_SINGLE
;
740 if (const TypedWhichId
<SvxWordLineModeItem
> wid
= aPlainMap
[SID_ATTR_CHAR_WORDLINEMODE
])
742 pSet
->Put(SvxWordLineModeItem(true, wid
));
744 goto ATTR_SETUNDERLINE
;
747 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_UNDERLINE
])
749 pSet
->Put(SvxUnderlineItem(eUnderline
, wid
));
754 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_UNDERLINE
])
756 std::unique_ptr
<SvxUnderlineItem
> aUL(std::make_unique
<SvxUnderlineItem
>(LINESTYLE_SINGLE
, wid
));
757 const SfxPoolItem
* pItem(nullptr);
759 if (SfxItemState::SET
== pSet
->GetItemState(wid
, false, &pItem
))
762 if( LINESTYLE_NONE
== static_cast<const SvxUnderlineItem
*>(pItem
)->GetLineStyle() )
765 aUL
.reset(static_cast<SvxUnderlineItem
*>(pItem
->Clone()));
769 aUL
.reset(static_cast<SvxUnderlineItem
*>(pSet
->Get(wid
, false).Clone()));
772 if(LINESTYLE_NONE
== aUL
->GetLineStyle())
774 aUL
->SetLineStyle(LINESTYLE_SINGLE
);
777 aUL
->SetColor(GetColor(sal_uInt16(nTokenValue
)));
779 pSet
->Put(std::move(aUL
));
784 if( !IsAttrSttPos() )
786 eOverline
= nTokenValue
? LINESTYLE_SINGLE
: LINESTYLE_NONE
;
787 goto ATTR_SETOVERLINE
;
790 eOverline
= LINESTYLE_DOTTED
;
791 goto ATTR_SETOVERLINE
;
793 eOverline
= LINESTYLE_DASH
;
794 goto ATTR_SETOVERLINE
;
796 eOverline
= LINESTYLE_DASHDOT
;
797 goto ATTR_SETOVERLINE
;
799 eOverline
= LINESTYLE_DASHDOTDOT
;
800 goto ATTR_SETOVERLINE
;
802 eOverline
= LINESTYLE_DOUBLE
;
803 goto ATTR_SETOVERLINE
;
805 eOverline
= LINESTYLE_NONE
;
806 goto ATTR_SETOVERLINE
;
808 eOverline
= LINESTYLE_BOLD
;
809 goto ATTR_SETOVERLINE
;
811 eOverline
= LINESTYLE_WAVE
;
812 goto ATTR_SETOVERLINE
;
814 eOverline
= LINESTYLE_BOLDDOTTED
;
815 goto ATTR_SETOVERLINE
;
817 eOverline
= LINESTYLE_BOLDDASH
;
818 goto ATTR_SETOVERLINE
;
820 eOverline
= LINESTYLE_LONGDASH
;
821 goto ATTR_SETOVERLINE
;
823 eOverline
= LINESTYLE_BOLDLONGDASH
;
824 goto ATTR_SETOVERLINE
;
826 eOverline
= LINESTYLE_BOLDDASHDOT
;
827 goto ATTR_SETOVERLINE
;
829 eOverline
= LINESTYLE_BOLDDASHDOTDOT
;
830 goto ATTR_SETOVERLINE
;
832 eOverline
= LINESTYLE_BOLDWAVE
;
833 goto ATTR_SETOVERLINE
;
835 eOverline
= LINESTYLE_DOUBLEWAVE
;
836 goto ATTR_SETOVERLINE
;
839 eOverline
= LINESTYLE_SINGLE
;
841 if (const TypedWhichId
<SvxWordLineModeItem
> wid
= aPlainMap
[SID_ATTR_CHAR_WORDLINEMODE
])
843 pSet
->Put(SvxWordLineModeItem(true, wid
));
845 goto ATTR_SETOVERLINE
;
848 if (const TypedWhichId
<SvxOverlineItem
> wid
= aPlainMap
[SID_ATTR_CHAR_OVERLINE
])
850 pSet
->Put(SvxOverlineItem(eOverline
, wid
));
855 if (const TypedWhichId
<SvxOverlineItem
> wid
= aPlainMap
[SID_ATTR_CHAR_OVERLINE
])
857 std::unique_ptr
<SvxOverlineItem
> aOL(std::make_unique
<SvxOverlineItem
>(LINESTYLE_SINGLE
, wid
));
858 const SfxPoolItem
* pItem(nullptr);
860 if (SfxItemState::SET
== pSet
->GetItemState(wid
, false, &pItem
))
863 if( LINESTYLE_NONE
== static_cast<const SvxOverlineItem
*>(pItem
)->GetLineStyle() )
866 aOL
.reset(static_cast<SvxOverlineItem
*>(pItem
->Clone()));
870 aOL
.reset(pSet
->Get(wid
, false).Clone());
873 if(LINESTYLE_NONE
== aOL
->GetLineStyle())
875 aOL
->SetLineStyle(LINESTYLE_SINGLE
);
878 aOL
->SetColor(GetColor(sal_uInt16(nTokenValue
)));
880 pSet
->Put(std::move(aOL
));
886 if (const sal_uInt16 nEsc
= aPlainMap
[SID_ATTR_CHAR_ESCAPEMENT
])
888 if( -1 == nTokenValue
)
889 nTokenValue
= 6; //RTF default \up value in half-points
892 const SvxEscapementItem
& rOld
=
893 static_cast<const SvxEscapementItem
&>(pSet
->Get( nEsc
,false));
896 if( DFLT_ESC_AUTO_SUB
== rOld
.GetEsc() )
898 nEs
= DFLT_ESC_AUTO_SUPER
;
899 nProp
= rOld
.GetProportionalHeight();
903 nEs
= (nToken
== RTF_SUPER
) ? DFLT_ESC_AUTO_SUPER
: nTokenValue
;
904 nProp
= (nToken
== RTF_SUPER
) ? DFLT_ESC_PROP
: 100;
906 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
911 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_COLOR
])
913 pSet
->Put(SvxColorItem(GetColor(sal_uInt16(nTokenValue
)), wid
));
916 //#i12501# While cb is clearly documented in the rtf spec, word
917 //doesn't accept it at all
920 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_BRUSH_CHAR
])
922 pSet
->Put(SvxBrushItem(GetColor(sal_uInt16(nTokenValue
)), wid
));
928 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_LANGUAGE
])
930 pSet
->Put(SvxLanguageItem(LanguageType(nTokenValue
), wid
));
935 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_CJK_LANGUAGE
])
937 pSet
->Put(SvxLanguageItem(LanguageType(nTokenValue
), wid
));
942 SvxLanguageItem
aTmpItem( LanguageType(nTokenValue
),
943 SID_ATTR_CHAR_LANGUAGE
);
944 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
949 bIsLeftToRightDef
= false;
952 bIsLeftToRightDef
= true;
955 if (const TypedWhichId
<SvxFrameDirectionItem
> wid
= aPardMap
[SID_ATTR_FRAMEDIRECTION
])
957 pSet
->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_RL_TB
, wid
));
961 if (const TypedWhichId
<SvxFrameDirectionItem
> wid
= aPardMap
[SID_ATTR_FRAMEDIRECTION
])
963 pSet
->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
, wid
));
966 case RTF_LOCH
: eCharType
= LOW_CHARTYPE
; break;
967 case RTF_HICH
: eCharType
= HIGH_CHARTYPE
; break;
968 case RTF_DBCH
: eCharType
= DOUBLEBYTE_CHARTYPE
; break;
972 eEmphasis
= FontEmphasisMark::NONE
;
973 goto ATTR_SETEMPHASIS
;
975 eEmphasis
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
976 goto ATTR_SETEMPHASIS
;
979 eEmphasis
= (FontEmphasisMark::Accent
| FontEmphasisMark::PosAbove
);
981 if (const TypedWhichId
<SvxEmphasisMarkItem
> wid
= aPlainMap
[SID_ATTR_CHAR_EMPHASISMARK
])
983 pSet
->Put(SvxEmphasisMarkItem(eEmphasis
, wid
));
988 if (const TypedWhichId
<SvxTwoLinesItem
> wid
= aPlainMap
[SID_ATTR_CHAR_TWO_LINES
])
990 sal_Unicode cStt
, cEnd
;
991 switch ( nTokenValue
)
993 case 1: cStt
= '('; cEnd
= ')'; break;
994 case 2: cStt
= '['; cEnd
= ']'; break;
995 case 3: cStt
= '<'; cEnd
= '>'; break;
996 case 4: cStt
= '{'; cEnd
= '}'; break;
997 default: cStt
= 0; cEnd
= 0; break;
1000 pSet
->Put(SvxTwoLinesItem(true, cStt
, cEnd
, wid
));
1004 case RTF_CHARSCALEX
:
1005 if (const TypedWhichId
<SvxCharScaleWidthItem
> wid
= aPlainMap
[SID_ATTR_CHAR_SCALEWIDTH
])
1008 if (nTokenValue
< 1 || nTokenValue
> 600)
1010 pSet
->Put(SvxCharScaleWidthItem(sal_uInt16(nTokenValue
), wid
));
1015 if (const TypedWhichId
<SvxCharRotateItem
> wid
= aPlainMap
[SID_ATTR_CHAR_ROTATED
])
1017 // RTF knows only 90deg
1018 pSet
->Put(SvxCharRotateItem(900_deg10
, 1 == nTokenValue
, wid
));
1023 if (const TypedWhichId
<SvxCharReliefItem
> wid
= aPlainMap
[SID_ATTR_CHAR_RELIEF
])
1025 pSet
->Put(SvxCharReliefItem(FontRelief::Embossed
, wid
));
1029 if (const TypedWhichId
<SvxCharReliefItem
> wid
= aPlainMap
[SID_ATTR_CHAR_RELIEF
])
1031 pSet
->Put(SvxCharReliefItem(FontRelief::Engraved
, wid
));
1035 if (const TypedWhichId
<SvxCharHiddenItem
> wid
= aPlainMap
[SID_ATTR_CHAR_HIDDEN
])
1037 pSet
->Put(SvxCharHiddenItem(nTokenValue
!= 0, wid
));
1041 case RTF_CHBGDKVERT
:
1042 case RTF_CHBGDKHORIZ
:
1045 case RTF_CHBGDKFDIAG
:
1046 case RTF_CHBGDCROSS
:
1049 case RTF_CHBGDKDCROSS
:
1050 case RTF_CHBGDKCROSS
:
1051 case RTF_CHBGDKBDIAG
:
1055 if (aPlainMap
[SID_ATTR_BRUSH_CHAR
])
1056 ReadBackgroundAttr( nToken
, *pSet
);
1061 // tests on Swg internal tokens
1062 bool bHandled
= false;
1064 if( RTF_IGNOREFLAG
!= GetNextToken())
1066 else if( (nToken
= GetNextToken() ) & RTF_SWGDEFS
)
1074 UnknownAttrToken( nToken
);
1075 // overwrite the closing parenthesis
1078 case RTF_SWG_ESCPROP
:
1080 // Store percentage change!
1081 sal_uInt8 nProp
= sal_uInt8( nTokenValue
/ 100 );
1083 if( 1 == ( nTokenValue
% 100 ))
1084 // Recognize own auto-flags!
1085 nEsc
= DFLT_ESC_AUTO_SUPER
;
1087 if (const sal_uInt16 wid
= aPlainMap
[SID_ATTR_CHAR_ESCAPEMENT
])
1088 pSet
->Put(SvxEscapementItem(nEsc
, nProp
, wid
));
1094 SvxHyphenZoneItem
aHypenZone(
1095 (nTokenValue
& 1) != 0,
1096 aPardMap
[SID_ATTR_PARA_HYPHENZONE
]);
1097 aHypenZone
.SetPageEnd((nTokenValue
& 2) != 0);
1099 if( aPardMap
[SID_ATTR_PARA_HYPHENZONE
] &&
1100 RTF_HYPHLEAD
== GetNextToken() &&
1101 RTF_HYPHTRAIL
== GetNextToken() &&
1102 RTF_HYPHMAX
== GetNextToken() )
1104 aHypenZone
.GetMinLead() =
1105 sal_uInt8(GetStackPtr( -2 )->nTokenValue
);
1106 aHypenZone
.GetMinTrail() =
1107 sal_uInt8(GetStackPtr( -1 )->nTokenValue
);
1108 aHypenZone
.GetMaxHyphens() =
1109 sal_uInt8(nTokenValue
);
1111 pSet
->Put( aHypenZone
);
1114 SkipGroup(); // at the end of the group
1118 // We expect these to be preceded by a RTF_HYPHEN and
1119 // so normally are handled by the RTF_HYPHEN case, but
1120 // if they appear 'bare' in a document then safely skip
1131 do { // middle check loop
1132 SvxShadowLocation eSL
= SvxShadowLocation( nTokenValue
);
1133 if( RTF_SHDW_DIST
!= GetNextToken() )
1135 sal_uInt16 nDist
= sal_uInt16( nTokenValue
);
1137 if( RTF_SHDW_STYLE
!= GetNextToken() )
1140 if( RTF_SHDW_COL
!= GetNextToken() )
1142 sal_uInt16 nCol
= sal_uInt16( nTokenValue
);
1144 if( RTF_SHDW_FCOL
!= GetNextToken() )
1147 Color aColor
= GetColor( nCol
);
1149 if (const TypedWhichId
<SvxShadowItem
> wid
= aPardMap
[SID_ATTR_BORDER_SHADOW
])
1150 pSet
->Put(SvxShadowItem(wid
, &aColor
, nDist
, eSL
));
1156 SkipGroup(); // at the end of the group
1162 if( (nToken
& ~(0xff | RTF_SWGDEFS
)) == RTF_TABSTOPDEF
)
1164 nToken
= SkipToken( -2 );
1165 ReadTabAttr( nToken
, *pSet
);
1168 cmc: #i76140, he who consumed the { must consume the }
1169 We rewound to a state of { being the current
1170 token so it is our responsibility to consume the }
1171 token if we consumed the {. We will not have consumed
1172 the { if it belonged to our caller, i.e. if the { we
1173 are handling is the "firsttoken" passed to us then
1174 the *caller* must consume it, not us. Otherwise *we*
1177 if (nToken
== BRACELEFT
&& !bFirstToken
)
1179 nToken
= GetNextToken();
1180 SAL_WARN_IF( nToken
!= BRACERIGHT
,
1182 "} did not follow { as expected");
1185 else if( (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
)
1187 nToken
= SkipToken( -2 );
1188 ReadBorderAttr( nToken
, *pSet
);
1190 else // so no more attribute
1197 cmc: #i4727# / #i12713# Who owns this closing bracket?
1198 If we read the opening one, we must read this one, if
1199 other is counting the brackets so as to push/pop off
1200 the correct environment then we will have pushed a new
1201 environment for the start { of this, but will not see
1202 the } and so is out of sync for the rest of the
1205 if (bHandled
&& !bFirstToken
)
1212 if( nSkip
) // all completely unknown
1215 --nSkip
; // BRACELEFT: is the next token
1222 if( (nToken
& ~0xff ) == RTF_TABSTOPDEF
)
1223 ReadTabAttr( nToken
, *pSet
);
1224 else if( (nToken
& ~0xff ) == RTF_BRDRDEF
)
1225 ReadBorderAttr( nToken
, *pSet
);
1226 else if( (nToken
& ~0xff ) == RTF_SHADINGDEF
)
1227 ReadBackgroundAttr( nToken
, *pSet
);
1230 // unknown token, so token "returned in Parser"
1239 nToken
= GetNextToken();
1241 bFirstToken
= false;
1245 void SvxRTFParser::ReadTabAttr( int nToken
, SfxItemSet
& rSet
)
1247 bool bMethodOwnsToken
= false; // #i52542# patch from cmc.
1248 // then read all the TabStops
1249 SvxTabStop aTabStop
;
1250 SvxTabStopItem
aAttr(0, 0, SvxTabAdjust::Default
, aPardMap
[SID_ATTR_TABSTOP
]);
1251 bool bContinue
= true;
1255 case RTF_TB
: // BarTab ???
1260 aTabStop
.GetTabPos() = nTokenValue
;
1261 aAttr
.Insert( aTabStop
);
1262 aTabStop
= SvxTabStop(); // all values default
1267 aTabStop
.GetAdjustment() = SvxTabAdjust::Left
;
1270 aTabStop
.GetAdjustment() = SvxTabAdjust::Right
;
1273 aTabStop
.GetAdjustment() = SvxTabAdjust::Center
;
1276 aTabStop
.GetAdjustment() = SvxTabAdjust::Decimal
;
1279 case RTF_TLDOT
: aTabStop
.GetFill() = '.'; break;
1280 case RTF_TLHYPH
: aTabStop
.GetFill() = ' '; break;
1281 case RTF_TLUL
: aTabStop
.GetFill() = '_'; break;
1282 case RTF_TLTH
: aTabStop
.GetFill() = '-'; break;
1283 case RTF_TLEQ
: aTabStop
.GetFill() = '='; break;
1287 // Swg - control BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1289 if( RTF_IGNOREFLAG
!= GetNextToken() )
1291 else if( RTF_TLSWG
!= ( nToken
= GetNextToken() ))
1295 aTabStop
.GetDecimal() = sal_uInt8(nTokenValue
& 0xff);
1296 aTabStop
.GetFill() = sal_uInt8((nTokenValue
>> 8) & 0xff);
1297 // overwrite the closing parenthesis
1298 if (bMethodOwnsToken
)
1303 SkipToken( nSkip
); // Ignore back again
1314 nToken
= GetNextToken();
1315 bMethodOwnsToken
= true;
1317 } while( bContinue
);
1319 // Fill with defaults is still missing!
1324 static void SetBorderLine( int nBorderTyp
, SvxBoxItem
& rItem
,
1325 const SvxBorderLine
& rBorder
)
1327 switch( nBorderTyp
)
1329 case RTF_BOX
: // run through all levels
1331 rItem
.SetLine( &rBorder
, SvxBoxItemLine::TOP
);
1332 if( RTF_BOX
!= nBorderTyp
)
1336 rItem
.SetLine( &rBorder
, SvxBoxItemLine::BOTTOM
);
1337 if( RTF_BOX
!= nBorderTyp
)
1341 rItem
.SetLine( &rBorder
, SvxBoxItemLine::LEFT
);
1342 if( RTF_BOX
!= nBorderTyp
)
1346 rItem
.SetLine( &rBorder
, SvxBoxItemLine::RIGHT
);
1347 if( RTF_BOX
!= nBorderTyp
)
1352 void SvxRTFParser::ReadBorderAttr( int nToken
, SfxItemSet
& rSet
,
1355 // then read the border attribute
1356 std::unique_ptr
<SvxBoxItem
> aAttr(std::make_unique
<SvxBoxItem
>(aPardMap
[SID_ATTR_BORDER_OUTER
]));
1357 const SfxPoolItem
* pItem(nullptr);
1359 if (SfxItemState::SET
== rSet
.GetItemState(aPardMap
[SID_ATTR_BORDER_OUTER
], false, &pItem
))
1361 aAttr
.reset(static_cast<SvxBoxItem
*>(pItem
->Clone()));
1364 SvxBorderLine
aBrd( nullptr, SvxBorderLineWidth::Hairline
);
1365 bool bContinue
= true;
1368 tools::Long nWidth
= 1;
1369 bool bDoubleWidth
= false;
1379 nBorderTyp
= nToken
;
1382 case RTF_CLBRDRT
: // Cell top border
1386 if (nBorderTyp
!= 0)
1387 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1388 nBorderTyp
= RTF_BRDRT
;
1392 case RTF_CLBRDRB
: // Cell bottom border
1396 if (nBorderTyp
!= 0)
1397 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1398 nBorderTyp
= RTF_BRDRB
;
1402 case RTF_CLBRDRL
: // Cell left border
1406 if (nBorderTyp
!= 0)
1407 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1408 nBorderTyp
= RTF_BRDRL
;
1412 case RTF_CLBRDRR
: // Cell right border
1416 if (nBorderTyp
!= 0)
1417 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1418 nBorderTyp
= RTF_BRDRR
;
1423 case RTF_BRDRDOT
: // dotted border
1424 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DOTTED
);
1426 case RTF_BRDRDASH
: // dashed border
1427 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DASHED
);
1429 case RTF_BRDRHAIR
: // hairline border
1431 aBrd
.SetBorderLineStyle( SvxBorderLineStyle::SOLID
);
1432 aBrd
.SetWidth( SvxBorderLineWidth::Hairline
);
1435 case RTF_BRDRDB
: // Double border
1436 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE
);
1438 case RTF_BRDRINSET
: // inset border
1439 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::INSET
);
1441 case RTF_BRDROUTSET
: // outset border
1442 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::OUTSET
);
1444 case RTF_BRDRTNTHSG
: // ThinThick Small gap
1445 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_SMALLGAP
);
1447 case RTF_BRDRTNTHMG
: // ThinThick Medium gap
1448 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_MEDIUMGAP
);
1450 case RTF_BRDRTNTHLG
: // ThinThick Large gap
1451 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_LARGEGAP
);
1453 case RTF_BRDRTHTNSG
: // ThickThin Small gap
1454 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_SMALLGAP
);
1456 case RTF_BRDRTHTNMG
: // ThickThin Medium gap
1457 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
);
1459 case RTF_BRDRTHTNLG
: // ThickThin Large gap
1460 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_LARGEGAP
);
1462 case RTF_BRDREMBOSS
: // Embossed border
1463 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::EMBOSSED
);
1465 case RTF_BRDRENGRAVE
: // Engraved border
1466 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::ENGRAVED
);
1469 case RTF_BRDRS
: // single thickness border
1470 bDoubleWidth
= false;
1472 case RTF_BRDRTH
: // double thickness border width*2
1473 bDoubleWidth
= true;
1475 case RTF_BRDRW
: // border width <255
1476 nWidth
= nTokenValue
;
1479 case RTF_BRDRCF
: // Border color
1480 aBrd
.SetColor( GetColor( sal_uInt16(nTokenValue
) ) );
1483 case RTF_BRDRSH
: // Shadowed border
1484 rSet
.Put( SvxShadowItem( aPardMap
[SID_ATTR_BORDER_SHADOW
], nullptr, 60 /*3pt*/,
1485 SvxShadowLocation::BottomRight
) );
1488 case RTF_BRSP
: // Spacing to content in twip
1490 switch( nBorderTyp
)
1493 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::BOTTOM
);
1497 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::TOP
);
1501 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::LEFT
);
1505 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::RIGHT
);
1509 aAttr
->SetAllDistances( static_cast<sal_uInt16
>(nTokenValue
) );
1515 case RTF_BRDRBTW
: // Border formatting group
1516 case RTF_BRDRBAR
: // Border outside
1517 // TODO unhandled ATM
1521 bContinue
= (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
;
1524 nToken
= GetNextToken();
1525 } while( bContinue
);
1527 // Finally compute the border width
1528 if ( bDoubleWidth
) nWidth
*= 2;
1529 aBrd
.SetWidth( nWidth
);
1531 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1533 rSet
.Put( std::move(aAttr
) );
1537 static sal_uInt32
CalcShading( sal_uInt32 nColor
, sal_uInt32 nFillColor
, sal_uInt8 nShading
)
1539 nColor
= (nColor
* nShading
) / 100;
1540 nFillColor
= (nFillColor
* ( 100 - nShading
)) / 100;
1541 return nColor
+ nFillColor
;
1544 void SvxRTFParser::ReadBackgroundAttr( int nToken
, SfxItemSet
& rSet
,
1547 // then read the border attribute
1548 bool bContinue
= true;
1549 sal_uInt16 nColor
= USHRT_MAX
, nFillColor
= USHRT_MAX
;
1550 sal_uInt8 nFillValue
= 0;
1552 sal_uInt16 nWh
= ( nToken
& ~0xff ) == RTF_CHRFMT
1553 ? aPlainMap
[SID_ATTR_BRUSH_CHAR
]
1554 : aPardMap
[SID_ATTR_BRUSH
];
1562 nFillColor
= sal_uInt16( nTokenValue
);
1568 nColor
= sal_uInt16( nTokenValue
);
1574 nFillValue
= static_cast<sal_uInt8
>( nTokenValue
/ 100 );
1578 case RTF_CHBGDKHORIZ
:
1580 case RTF_CLBGDKVERT
:
1581 case RTF_CHBGDKVERT
:
1583 case RTF_CLBGDKBDIAG
:
1584 case RTF_CHBGDKBDIAG
:
1586 case RTF_CLBGDKFDIAG
:
1587 case RTF_CHBGDKFDIAG
:
1589 case RTF_CLBGDKCROSS
:
1590 case RTF_CHBGDKCROSS
:
1592 case RTF_CLBGDKDCROSS
:
1593 case RTF_CHBGDKDCROSS
:
1594 case RTF_BGDKDCROSS
:
1614 case RTF_CLBGDCROSS
:
1615 case RTF_CHBGDCROSS
:
1623 bContinue
= (nToken
& ~(0xff | RTF_TABLEDEF
) ) == RTF_SHADINGDEF
;
1625 bContinue
= (nToken
& ~0xff) == RTF_SHADINGDEF
;
1628 nToken
= GetNextToken();
1629 } while( bContinue
);
1631 Color
aCol( COL_WHITE
), aFCol
;
1634 // there was only one of two colors specified or no BrushType
1635 if( USHRT_MAX
!= nFillColor
)
1638 aCol
= GetColor( nFillColor
);
1640 else if( USHRT_MAX
!= nColor
)
1641 aFCol
= GetColor( nColor
);
1645 if( USHRT_MAX
!= nColor
)
1646 aCol
= GetColor( nColor
);
1650 if( USHRT_MAX
!= nFillColor
)
1651 aFCol
= GetColor( nFillColor
);
1657 if( 0 == nFillValue
|| 100 == nFillValue
)
1661 static_cast<sal_uInt8
>(CalcShading( aCol
.GetRed(), aFCol
.GetRed(), nFillValue
)),
1662 static_cast<sal_uInt8
>(CalcShading( aCol
.GetGreen(), aFCol
.GetGreen(), nFillValue
)),
1663 static_cast<sal_uInt8
>(CalcShading( aCol
.GetBlue(), aFCol
.GetBlue(), nFillValue
)) );
1665 rSet
.Put( SvxBrushItem( aColor
, nWh
) );
1670 // pard / plain handling
1671 void SvxRTFParser::RTFPardPlain( bool const bPard
, SfxItemSet
** ppSet
)
1673 if( bNewGroup
|| aAttrStack
.empty() ) // not at the beginning of a new group
1676 SvxRTFItemStackType
* pCurrent
= aAttrStack
.back().get();
1678 int nLastToken
= GetStackPtr(-1)->nTokenId
;
1679 bool bNewStkEntry
= true;
1680 if( RTF_PARD
!= nLastToken
&&
1681 RTF_PLAIN
!= nLastToken
&&
1682 BRACELEFT
!= nLastToken
)
1684 if (pCurrent
->aAttrSet
.Count() || !pCurrent
->maChildList
.empty() || pCurrent
->nStyleNo
)
1687 auto xNew(std::make_unique
<SvxRTFItemStackType
>(*pCurrent
, *mxInsertPosition
, true));
1688 xNew
->SetRTFDefaults( GetRTFDefaults() );
1690 // Set all until here valid attributes
1692 pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get(); // can be changed after AttrGroupEnd!
1693 xNew
->aAttrSet
.SetParent( pCurrent
? &pCurrent
->aAttrSet
: nullptr );
1694 aAttrStack
.push_back( std::move(xNew
) );
1695 pCurrent
= aAttrStack
.back().get();
1699 // continue to use this entry as new
1700 pCurrent
->SetStartPos( *mxInsertPosition
);
1701 bNewStkEntry
= false;
1705 // now reset all to default
1707 ( pCurrent
->aAttrSet
.GetParent() || pCurrent
->aAttrSet
.Count() ))
1709 const SfxPoolItem
*pItem
, *pDef
;
1710 std::map
<sal_uInt16
, sal_uInt16
>::const_iterator aIt
;
1711 std::map
<sal_uInt16
, sal_uInt16
>::const_iterator aEnd
;
1712 const SfxItemSet
* pDfltSet
= &GetRTFDefaults();
1715 pCurrent
->nStyleNo
= 0;
1716 aIt
= aPardMap
.data
.begin();
1717 aEnd
= aPardMap
.data
.end();
1721 aIt
= aPlainMap
.data
.begin();
1722 aEnd
= aPlainMap
.data
.end();
1725 for (; aIt
!= aEnd
; ++aIt
)
1727 const sal_uInt16 wid
= aIt
->second
;
1728 // Item set and different -> Set the Default Pool
1731 else if (SfxItemPool::IsSlot(wid
))
1732 pCurrent
->aAttrSet
.ClearItem(wid
);
1733 else if( IsChkStyleAttr() )
1734 pCurrent
->aAttrSet
.Put(pDfltSet
->Get(wid
));
1735 else if( !pCurrent
->aAttrSet
.GetParent() )
1737 if (SfxItemState::SET
== pDfltSet
->GetItemState(wid
, false, &pDef
))
1738 pCurrent
->aAttrSet
.Put( *pDef
);
1740 pCurrent
->aAttrSet
.ClearItem(wid
);
1742 else if( SfxItemState::SET
== pCurrent
->aAttrSet
.GetParent()->
1743 GetItemState(wid
, true, &pItem
) &&
1744 *( pDef
= &pDfltSet
->Get(wid
)) != *pItem
)
1745 pCurrent
->aAttrSet
.Put( *pDef
);
1748 if (SfxItemState::SET
== pDfltSet
->GetItemState(wid
, false, &pDef
))
1749 pCurrent
->aAttrSet
.Put( *pDef
);
1751 pCurrent
->aAttrSet
.ClearItem(wid
);
1756 pCurrent
->nStyleNo
= 0; // reset Style number
1758 *ppSet
= &pCurrent
->aAttrSet
;
1763 //Once we have a default font, then any text without a font specifier is
1764 //in the default font, and thus has the default font charset, otherwise
1765 //we can fall back to the ansicpg set codeset
1766 if (nDfltFont
!= -1)
1768 const vcl::Font
& rSVFont
= GetFont(sal_uInt16(nDfltFont
));
1769 SetEncoding(rSVFont
.GetCharSet());
1772 SetEncoding(GetCodeSet());
1775 void SvxRTFParser::SetDefault( int nToken
, int nValue
)
1780 SfxItemSet
aTmp(*pAttrPool
, aWhichMap
);
1781 bool bOldFlag
= bIsLeftToRightDef
;
1782 bIsLeftToRightDef
= true;
1786 bIsLeftToRightDef
= false;
1792 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nValue
) );
1793 SvxFontItem
aTmpItem(
1794 rSVFont
.GetFamilyType(), rSVFont
.GetFamilyName(),
1795 rSVFont
.GetStyleName(), rSVFont
.GetPitch(),
1796 rSVFont
.GetCharSet(), SID_ATTR_CHAR_FONT
);
1797 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1802 bIsLeftToRightDef
= false;
1805 // store default Language
1808 SvxLanguageItem
aTmpItem( LanguageType(nValue
), SID_ATTR_CHAR_LANGUAGE
);
1809 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1814 if (const sal_uInt16 wid
= aPardMap
[SID_ATTR_TABSTOP
])
1816 // RTF defines 720 twips as default
1817 bIsSetDfltTab
= true;
1818 if( -1 == nValue
|| !nValue
)
1821 // who would like to have no twips ...
1824 nTokenValue
= nValue
;
1826 nValue
= nTokenValue
;
1829 // Calculate the ratio of default TabWidth / Tabs and
1830 // calculate the corresponding new number.
1831 // ?? how did one come up with 13 ??
1832 sal_uInt16 nTabCount
= (SVX_TAB_DEFDIST
* 13 ) / sal_uInt16(nValue
);
1834 cmc, make sure we have at least one, or all hell breaks loose in
1835 everybody exporters, #i8247#
1840 // we want Defaulttabs
1841 SvxTabStopItem
aNewTab(nTabCount
, sal_uInt16(nValue
), SvxTabAdjust::Default
, wid
);
1843 const_cast<SvxTabStop
&>(aNewTab
[ --nTabCount
]).GetAdjustment() = SvxTabAdjust::Default
;
1845 pAttrPool
->SetPoolDefaultItem( aNewTab
);
1849 bIsLeftToRightDef
= bOldFlag
;
1853 SfxItemIter
aIter( aTmp
);
1854 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1857 pAttrPool
->SetPoolDefaultItem( *pItem
);
1858 pItem
= aIter
.NextItem();
1863 // default: no conversion, leaving everything in twips.
1864 void SvxRTFParser::CalcValue()
1868 // for tokens that are not evaluated in ReadAttr
1869 void SvxRTFParser::UnknownAttrToken( int )
1873 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */