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/udlnitem.hxx>
27 #include <editeng/crossedoutitem.hxx>
28 #include <editeng/shdditem.hxx>
29 #include <editeng/autokernitem.hxx>
30 #include <editeng/wrlmitem.hxx>
31 #include <editeng/contouritem.hxx>
32 #include <editeng/colritem.hxx>
33 #include <editeng/kernitem.hxx>
34 #include <editeng/cmapitem.hxx>
35 #include <editeng/escapementitem.hxx>
36 #include <editeng/langitem.hxx>
37 #include <editeng/nhypitem.hxx>
38 #include <editeng/blinkitem.hxx>
39 #include <editeng/emphasismarkitem.hxx>
40 #include <editeng/twolinesitem.hxx>
41 #include <editeng/pbinitem.hxx>
42 #include <editeng/sizeitem.hxx>
43 #include <editeng/lrspitem.hxx>
44 #include <editeng/ulspitem.hxx>
45 #include <editeng/prntitem.hxx>
46 #include <editeng/opaqitem.hxx>
47 #include <editeng/protitem.hxx>
48 #include <editeng/shaditem.hxx>
49 #include <editeng/borderline.hxx>
50 #include <editeng/boxitem.hxx>
51 #include <editeng/formatbreakitem.hxx>
52 #include <editeng/keepitem.hxx>
53 #include <editeng/lineitem.hxx>
54 #include <editeng/brushitem.hxx>
55 #include <editeng/lspcitem.hxx>
56 #include <editeng/adjustitem.hxx>
57 #include <editeng/orphitem.hxx>
58 #include <editeng/widwitem.hxx>
59 #include <editeng/tstpitem.hxx>
60 #include <editeng/pmdlitem.hxx>
61 #include <editeng/spltitem.hxx>
62 #include <editeng/hyphenzoneitem.hxx>
63 #include <editeng/charscaleitem.hxx>
64 #include <editeng/charrotateitem.hxx>
65 #include <editeng/charreliefitem.hxx>
66 #include <editeng/paravertalignitem.hxx>
67 #include <editeng/forbiddenruleitem.hxx>
68 #include <editeng/hngpnctitem.hxx>
69 #include <editeng/scriptspaceitem.hxx>
70 #include <editeng/frmdiritem.hxx>
71 #include <editeng/charhiddenitem.hxx>
73 #include <svtools/rtftoken.h>
74 #include <svl/itempool.hxx>
75 #include <svl/itemiter.hxx>
76 #include <sal/log.hxx>
77 #include <vcl/font.hxx>
79 #include <editeng/svxrtf.hxx>
80 #include <editeng/editids.hrc>
83 #define BRACERIGHT '}'
85 using namespace ::com::sun::star
;
86 using namespace editeng
;
88 void SvxRTFParser::SetScriptAttr( RTF_CharTypeDef eType
, SfxItemSet
& rSet
,
91 const sal_uInt16
*pNormal
= nullptr, *pCJK
= nullptr, *pCTL
= nullptr;
92 switch( rItem
.Which() )
94 case SID_ATTR_CHAR_FONT
:
95 pNormal
= &aPlainMap
.nFont
;
96 pCJK
= &aPlainMap
.nCJKFont
;
97 pCTL
= &aPlainMap
.nCTLFont
;
100 case SID_ATTR_CHAR_FONTHEIGHT
:
101 pNormal
= &aPlainMap
.nFontHeight
;
102 pCJK
= &aPlainMap
.nCJKFontHeight
;
103 pCTL
= &aPlainMap
.nCTLFontHeight
;
106 case SID_ATTR_CHAR_POSTURE
:
107 pNormal
= &aPlainMap
.nPosture
;
108 pCJK
= &aPlainMap
.nCJKPosture
;
109 pCTL
= &aPlainMap
.nCTLPosture
;
112 case SID_ATTR_CHAR_WEIGHT
:
113 pNormal
= &aPlainMap
.nWeight
;
114 pCJK
= &aPlainMap
.nCJKWeight
;
115 pCTL
= &aPlainMap
.nCTLWeight
;
118 case SID_ATTR_CHAR_LANGUAGE
:
119 pNormal
= &aPlainMap
.nLanguage
;
120 pCJK
= &aPlainMap
.nCJKLanguage
;
121 pCTL
= &aPlainMap
.nCTLLanguage
;
125 // it exist no WhichId - don't set this item
133 if( DOUBLEBYTE_CHARTYPE
== eType
)
135 if( bIsLeftToRightDef
&& pCJK
)
137 rItem
.SetWhich( *pCJK
);
141 else if( !bIsLeftToRightDef
)
145 rItem
.SetWhich( *pCTL
);
151 if( LOW_CHARTYPE
== eType
)
155 rItem
.SetWhich( *pNormal
);
159 else if( HIGH_CHARTYPE
== eType
)
163 rItem
.SetWhich( *pCTL
);
171 rItem
.SetWhich( *pCJK
);
176 rItem
.SetWhich( *pCTL
);
181 rItem
.SetWhich( *pNormal
);
189 void SvxRTFParser::ReadAttr( int nToken
, SfxItemSet
* pSet
)
191 DBG_ASSERT( pSet
, "A SfxItemSet has to be provided as argument!" );
192 bool bFirstToken
= true;
193 bool bContinue
= true;
194 FontLineStyle eUnderline
;
195 FontLineStyle eOverline
;
196 FontEmphasisMark eEmphasis
;
197 RTF_CharTypeDef eCharType
= NOTDEF_CHARTYPE
;
198 SvxParaVertAlignItem::Align nFontAlign
;
200 bool bChkStkPos
= !bNewGroup
&& !aAttrStack
.empty();
202 while( bContinue
&& IsParserWorking() ) // as long as known Attribute are recognized
207 RTFPardPlain( true, &pSet
);
211 RTFPardPlain( false, &pSet
);
215 do { // middle checked loop
219 SvxRTFItemStackType
* pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get();
220 if( !pCurrent
|| (pCurrent
->pSttNd
->GetIdx() == pInsPos
->GetNodeIdx() &&
221 pCurrent
->nSttCnt
== pInsPos
->GetCntIdx() ))
224 int nLastToken
= GetStackPtr(-1)->nTokenId
;
225 if( RTF_PARD
== nLastToken
|| RTF_PLAIN
== nLastToken
)
228 if (pCurrent
->aAttrSet
.Count() || pCurrent
->m_pChildList
||
232 std::unique_ptr
<SvxRTFItemStackType
> pNew(new SvxRTFItemStackType(
233 *pCurrent
, *pInsPos
, true ));
234 pNew
->SetRTFDefaults( GetRTFDefaults() );
236 // "Set" all valid attributes up until this point
238 pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get(); // can be changed after AttrGroupEnd!
239 pNew
->aAttrSet
.SetParent( pCurrent
? &pCurrent
->aAttrSet
: nullptr );
241 aAttrStack
.push_back( std::move(pNew
) );
242 pCurrent
= aAttrStack
.back().get();
245 // continue to use this entry as a new one
246 pCurrent
->SetStartPos( *pInsPos
);
248 pSet
= &pCurrent
->aAttrSet
;
259 UnknownAttrToken( nToken
);
263 if( bIsInReadStyleTab
)
271 sal_uInt16 nStyleNo
= -1 == nTokenValue
? 0 : sal_uInt16(nTokenValue
);
272 // set StyleNo to the current style on the AttrStack
273 SvxRTFItemStackType
* pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get();
277 pCurrent
->nStyleNo
= nStyleNo
;
282 if( aPardMap
.nSplit
)
284 pSet
->Put( SvxFormatSplitItem( false, aPardMap
.nSplit
));
291 pSet
->Put( SvxFormatKeepItem( true, aPardMap
.nKeep
));
296 if( aPardMap
.nOutlineLvl
)
298 pSet
->Put( SfxInt16Item( aPardMap
.nOutlineLvl
,
299 static_cast<sal_uInt16
>(nTokenValue
) ));
304 if( aPardMap
.nAdjust
)
306 pSet
->Put( SvxAdjustItem( SvxAdjust::Left
, aPardMap
.nAdjust
));
310 if( aPardMap
.nAdjust
)
312 pSet
->Put( SvxAdjustItem( SvxAdjust::Right
, aPardMap
.nAdjust
));
316 if( aPardMap
.nAdjust
)
318 pSet
->Put( SvxAdjustItem( SvxAdjust::Block
, aPardMap
.nAdjust
));
322 if( aPardMap
.nAdjust
)
324 pSet
->Put( SvxAdjustItem( SvxAdjust::Center
, aPardMap
.nAdjust
));
329 if( aPardMap
.nLRSpace
)
332 static_cast<const SvxLRSpaceItem
&>(pSet
->Get(aPardMap
.nLRSpace
)));
334 if( -1 != nTokenValue
)
338 nSz
= sal_uInt16(nTokenValue
);
340 aLR
.SetTextFirstLineOfst( nSz
);
347 if( aPardMap
.nLRSpace
)
350 static_cast<const SvxLRSpaceItem
&>(pSet
->Get(aPardMap
.nLRSpace
)));
352 if( 0 < nTokenValue
)
356 nSz
= sal_uInt16(nTokenValue
);
358 aLR
.SetTextLeft( nSz
);
365 if( aPardMap
.nLRSpace
)
368 static_cast<const SvxLRSpaceItem
&>(pSet
->Get(aPardMap
.nLRSpace
)));
370 if( 0 < nTokenValue
)
374 nSz
= sal_uInt16(nTokenValue
);
382 if( aPardMap
.nULSpace
)
385 static_cast<const SvxULSpaceItem
&>(pSet
->Get(aPardMap
.nULSpace
)));
387 if( 0 < nTokenValue
)
391 nSz
= sal_uInt16(nTokenValue
);
399 if( aPardMap
.nULSpace
)
402 static_cast<const SvxULSpaceItem
&>(pSet
->Get(aPardMap
.nULSpace
)));
404 if( 0 < nTokenValue
)
408 nSz
= sal_uInt16(nTokenValue
);
416 if( aPardMap
.nLinespacing
&& 1 == nTokenValue
)
418 // then switches to multi-line!
419 SvxLineSpacingItem
aLSpace(
420 static_cast<const SvxLineSpacingItem
&>(pSet
->Get( aPardMap
.nLinespacing
,false)));
422 // how much do you get from the line height value?
424 // Proportional-Size:
425 // Ie, the ratio is (n / 240) twips
431 nTokenValue
= short( 100L * aLSpace
.GetLineHeight() / nTokenValue
);
433 aLSpace
.SetPropLineSpace( static_cast<sal_uInt16
>(nTokenValue
) );
434 aLSpace
.SetLineSpaceRule( SvxLineSpaceRule::Auto
);
436 pSet
->Put( aLSpace
);
441 if( aPardMap
.nLinespacing
)
443 // Calculate the ratio between the default font and the
444 // specified size. The distance consists of the line height
445 // (100%) and the space above the line (20%).
446 SvxLineSpacingItem
aLSpace(0, aPardMap
.nLinespacing
);
448 nTokenValue
= !bTokenHasValue
? 0 : nTokenValue
;
449 if (1000 == nTokenValue
)
452 SvxLineSpaceRule eLnSpc
;
455 eLnSpc
= SvxLineSpaceRule::Fix
;
456 nTokenValue
= -nTokenValue
;
458 else if (nTokenValue
== 0)
460 //if \sl0 is used, the line spacing is automatically
462 eLnSpc
= SvxLineSpaceRule::Auto
;
465 eLnSpc
= SvxLineSpaceRule::Min
;
470 if (eLnSpc
!= SvxLineSpaceRule::Auto
)
471 aLSpace
.SetLineHeight( static_cast<sal_uInt16
>(nTokenValue
) );
473 aLSpace
.SetLineSpaceRule(eLnSpc
);
479 if( aPardMap
.nForbRule
)
481 pSet
->Put( SvxForbiddenRuleItem( false,
482 aPardMap
.nForbRule
));
486 if( aPardMap
.nHangPunct
)
488 pSet
->Put( SvxHangingPunctuationItem( false,
489 aPardMap
.nHangPunct
));
494 if( aPardMap
.nScriptSpace
)
496 pSet
->Put( SvxScriptSpaceItem( true,
497 aPardMap
.nScriptSpace
));
502 case RTF_FAAUTO
: nFontAlign
= SvxParaVertAlignItem::Align::Automatic
;
503 goto SET_FONTALIGNMENT
;
504 case RTF_FAHANG
: nFontAlign
= SvxParaVertAlignItem::Align::Top
;
505 goto SET_FONTALIGNMENT
;
506 case RTF_FAVAR
: nFontAlign
= SvxParaVertAlignItem::Align::Bottom
;
507 goto SET_FONTALIGNMENT
;
508 case RTF_FACENTER
: nFontAlign
= SvxParaVertAlignItem::Align::Center
;
509 goto SET_FONTALIGNMENT
;
510 case RTF_FAROMAN
: nFontAlign
= SvxParaVertAlignItem::Align::Baseline
;
511 goto SET_FONTALIGNMENT
;
513 if( aPardMap
.nFontAlign
)
515 pSet
->Put( SvxParaVertAlignItem( nFontAlign
,
516 aPardMap
.nFontAlign
));
522 if( IsAttrSttPos() ) // not in the text flow?
525 SvxWeightItem
aTmpItem(
526 nTokenValue
? WEIGHT_BOLD
: WEIGHT_NORMAL
,
527 SID_ATTR_CHAR_WEIGHT
);
528 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
534 if( aPlainMap
.nCaseMap
&&
535 IsAttrSttPos() ) // not in the text flow?
539 eCaseMap
= SvxCaseMap::NotMapped
;
540 else if( RTF_CAPS
== nToken
)
541 eCaseMap
= SvxCaseMap::Uppercase
;
543 eCaseMap
= SvxCaseMap::SmallCaps
;
545 pSet
->Put( SvxCaseMapItem( eCaseMap
, aPlainMap
.nCaseMap
));
551 if( aPlainMap
.nEscapement
)
553 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
554 if( -1 == nTokenValue
|| RTF_SUB
== nToken
)
558 const SvxEscapementItem
& rOld
=
559 static_cast<const SvxEscapementItem
&>(pSet
->Get( nEsc
,false));
562 if( DFLT_ESC_AUTO_SUPER
== rOld
.GetEsc() )
564 nEs
= DFLT_ESC_AUTO_SUB
;
565 nProp
= rOld
.GetProportionalHeight();
569 nEs
= static_cast<short>(-nTokenValue
);
570 nProp
= (nToken
== RTF_SUB
) ? DFLT_ESC_PROP
: 100;
572 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
577 if( aPlainMap
.nEscapement
)
579 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
580 pSet
->Put( SvxEscapementItem( nEsc
));
585 if( aPlainMap
.nKering
)
587 if( -1 == nTokenValue
)
593 pSet
->Put( SvxKerningItem( static_cast<short>(nTokenValue
), aPlainMap
.nKering
));
598 if( aPlainMap
.nAutoKerning
)
600 if( -1 == nTokenValue
)
606 pSet
->Put( SvxAutoKernItem( 0 != nTokenValue
,
607 aPlainMap
.nAutoKerning
));
612 if( aPlainMap
.nKering
)
614 if( -1 == nTokenValue
)
618 pSet
->Put( SvxKerningItem( static_cast<short>(nTokenValue
), aPlainMap
.nKering
));
625 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nTokenValue
) );
626 SvxFontItem
aTmpItem( rSVFont
.GetFamilyType(),
627 rSVFont
.GetFamilyName(), rSVFont
.GetStyleName(),
628 rSVFont
.GetPitch(), rSVFont
.GetCharSet(),
629 SID_ATTR_CHAR_FONT
);
630 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
631 if( RTF_F
== nToken
)
633 SetEncoding( rSVFont
.GetCharSet() );
642 if( -1 == nTokenValue
)
647 // for the SwRTFParser 'IsCalcValue' will be false and for the EditRTFParser
648 // the conversion takes now place in EditRTFParser since for other reasons
649 // the wrong MapUnit might still be use there
650 // if( IsCalcValue() )
652 SvxFontHeightItem
aTmpItem(
653 static_cast<sal_uInt16
>(nTokenValue
), 100,
654 SID_ATTR_CHAR_FONTHEIGHT
);
655 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
661 if( IsAttrSttPos() ) // not in the text flow?
663 SvxPostureItem
aTmpItem(
664 nTokenValue
? ITALIC_NORMAL
: ITALIC_NONE
,
665 SID_ATTR_CHAR_POSTURE
);
666 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
671 if( aPlainMap
.nContour
&&
672 IsAttrSttPos() ) // not in the text flow?
674 pSet
->Put( SvxContourItem(nTokenValue
!= 0,
675 aPlainMap
.nContour
));
680 if( aPlainMap
.nShadowed
&&
681 IsAttrSttPos() ) // not in the text flow?
683 pSet
->Put( SvxShadowedItem(nTokenValue
!= 0,
684 aPlainMap
.nShadowed
));
689 if( aPlainMap
.nCrossedOut
&&
690 IsAttrSttPos() ) // not in the text flow?
692 pSet
->Put( SvxCrossedOutItem(
693 nTokenValue
? STRIKEOUT_SINGLE
: STRIKEOUT_NONE
,
694 aPlainMap
.nCrossedOut
));
699 if( aPlainMap
.nCrossedOut
) // not in the text flow?
701 pSet
->Put( SvxCrossedOutItem(
702 nTokenValue
? STRIKEOUT_DOUBLE
: STRIKEOUT_NONE
,
703 aPlainMap
.nCrossedOut
));
708 if( !IsAttrSttPos() )
710 eUnderline
= nTokenValue
? LINESTYLE_SINGLE
: LINESTYLE_NONE
;
711 goto ATTR_SETUNDERLINE
;
714 eUnderline
= LINESTYLE_DOTTED
;
715 goto ATTR_SETUNDERLINE
;
717 eUnderline
= LINESTYLE_DASH
;
718 goto ATTR_SETUNDERLINE
;
720 eUnderline
= LINESTYLE_DASHDOT
;
721 goto ATTR_SETUNDERLINE
;
723 eUnderline
= LINESTYLE_DASHDOTDOT
;
724 goto ATTR_SETUNDERLINE
;
726 eUnderline
= LINESTYLE_DOUBLE
;
727 goto ATTR_SETUNDERLINE
;
729 eUnderline
= LINESTYLE_NONE
;
730 goto ATTR_SETUNDERLINE
;
732 eUnderline
= LINESTYLE_BOLD
;
733 goto ATTR_SETUNDERLINE
;
735 eUnderline
= LINESTYLE_WAVE
;
736 goto ATTR_SETUNDERLINE
;
738 eUnderline
= LINESTYLE_BOLDDOTTED
;
739 goto ATTR_SETUNDERLINE
;
741 eUnderline
= LINESTYLE_BOLDDASH
;
742 goto ATTR_SETUNDERLINE
;
744 eUnderline
= LINESTYLE_LONGDASH
;
745 goto ATTR_SETUNDERLINE
;
747 eUnderline
= LINESTYLE_BOLDLONGDASH
;
748 goto ATTR_SETUNDERLINE
;
750 eUnderline
= LINESTYLE_BOLDDASHDOT
;
751 goto ATTR_SETUNDERLINE
;
753 eUnderline
= LINESTYLE_BOLDDASHDOTDOT
;
754 goto ATTR_SETUNDERLINE
;
756 eUnderline
= LINESTYLE_BOLDWAVE
;
757 goto ATTR_SETUNDERLINE
;
759 eUnderline
= LINESTYLE_DOUBLEWAVE
;
760 goto ATTR_SETUNDERLINE
;
763 eUnderline
= LINESTYLE_SINGLE
;
765 if( aPlainMap
.nWordlineMode
)
767 pSet
->Put( SvxWordLineModeItem( true, aPlainMap
.nWordlineMode
));
769 goto ATTR_SETUNDERLINE
;
772 if( aPlainMap
.nUnderline
)
774 pSet
->Put( SvxUnderlineItem( eUnderline
, aPlainMap
.nUnderline
));
779 if( aPlainMap
.nUnderline
)
781 std::unique_ptr
<SvxUnderlineItem
> aUL(std::make_unique
<SvxUnderlineItem
>(LINESTYLE_SINGLE
, aPlainMap
.nUnderline
));
782 const SfxPoolItem
* pItem(nullptr);
784 if( SfxItemState::SET
== pSet
->GetItemState(aPlainMap
.nUnderline
, false, &pItem
) )
787 if( LINESTYLE_NONE
== static_cast<const SvxUnderlineItem
*>(pItem
)->GetLineStyle() )
790 aUL
.reset(static_cast<SvxUnderlineItem
*>(pItem
->Clone()));
794 aUL
.reset(static_cast<SvxUnderlineItem
*>(pSet
->Get( aPlainMap
.nUnderline
, false).Clone()));
797 if(LINESTYLE_NONE
== aUL
->GetLineStyle())
799 aUL
->SetLineStyle(LINESTYLE_SINGLE
);
802 aUL
->SetColor(GetColor(sal_uInt16(nTokenValue
)));
809 if( !IsAttrSttPos() )
811 eOverline
= nTokenValue
? LINESTYLE_SINGLE
: LINESTYLE_NONE
;
812 goto ATTR_SETOVERLINE
;
815 eOverline
= LINESTYLE_DOTTED
;
816 goto ATTR_SETOVERLINE
;
818 eOverline
= LINESTYLE_DASH
;
819 goto ATTR_SETOVERLINE
;
821 eOverline
= LINESTYLE_DASHDOT
;
822 goto ATTR_SETOVERLINE
;
824 eOverline
= LINESTYLE_DASHDOTDOT
;
825 goto ATTR_SETOVERLINE
;
827 eOverline
= LINESTYLE_DOUBLE
;
828 goto ATTR_SETOVERLINE
;
830 eOverline
= LINESTYLE_NONE
;
831 goto ATTR_SETOVERLINE
;
833 eOverline
= LINESTYLE_BOLD
;
834 goto ATTR_SETOVERLINE
;
836 eOverline
= LINESTYLE_WAVE
;
837 goto ATTR_SETOVERLINE
;
839 eOverline
= LINESTYLE_BOLDDOTTED
;
840 goto ATTR_SETOVERLINE
;
842 eOverline
= LINESTYLE_BOLDDASH
;
843 goto ATTR_SETOVERLINE
;
845 eOverline
= LINESTYLE_LONGDASH
;
846 goto ATTR_SETOVERLINE
;
848 eOverline
= LINESTYLE_BOLDLONGDASH
;
849 goto ATTR_SETOVERLINE
;
851 eOverline
= LINESTYLE_BOLDDASHDOT
;
852 goto ATTR_SETOVERLINE
;
854 eOverline
= LINESTYLE_BOLDDASHDOTDOT
;
855 goto ATTR_SETOVERLINE
;
857 eOverline
= LINESTYLE_BOLDWAVE
;
858 goto ATTR_SETOVERLINE
;
860 eOverline
= LINESTYLE_DOUBLEWAVE
;
861 goto ATTR_SETOVERLINE
;
864 eOverline
= LINESTYLE_SINGLE
;
866 if( aPlainMap
.nWordlineMode
)
868 pSet
->Put( SvxWordLineModeItem( true, aPlainMap
.nWordlineMode
));
870 goto ATTR_SETOVERLINE
;
873 if( aPlainMap
.nUnderline
)
875 pSet
->Put( SvxOverlineItem( eOverline
, aPlainMap
.nOverline
));
880 if( aPlainMap
.nOverline
)
882 std::unique_ptr
<SvxOverlineItem
> aOL(std::make_unique
<SvxOverlineItem
>(LINESTYLE_SINGLE
, aPlainMap
.nOverline
));
883 const SfxPoolItem
* pItem(nullptr);
885 if( SfxItemState::SET
== pSet
->GetItemState(aPlainMap
.nOverline
, false, &pItem
) )
888 if( LINESTYLE_NONE
== static_cast<const SvxOverlineItem
*>(pItem
)->GetLineStyle() )
891 aOL
.reset(static_cast<SvxOverlineItem
*>(pItem
->Clone()));
895 aOL
.reset(static_cast<SvxOverlineItem
*>(pSet
->Get( aPlainMap
.nOverline
, false).Clone()));
898 if(LINESTYLE_NONE
== aOL
->GetLineStyle())
900 aOL
->SetLineStyle(LINESTYLE_SINGLE
);
903 aOL
->SetColor(GetColor(sal_uInt16(nTokenValue
)));
911 if( aPlainMap
.nEscapement
)
913 const sal_uInt16 nEsc
= aPlainMap
.nEscapement
;
914 if( -1 == nTokenValue
|| RTF_SUPER
== nToken
)
918 const SvxEscapementItem
& rOld
=
919 static_cast<const SvxEscapementItem
&>(pSet
->Get( nEsc
,false));
922 if( DFLT_ESC_AUTO_SUB
== rOld
.GetEsc() )
924 nEs
= DFLT_ESC_AUTO_SUPER
;
925 nProp
= rOld
.GetProportionalHeight();
929 nEs
= static_cast<short>(nTokenValue
);
930 nProp
= (nToken
== RTF_SUPER
) ? DFLT_ESC_PROP
: 100;
932 pSet
->Put( SvxEscapementItem( nEs
, nProp
, nEsc
));
937 if( aPlainMap
.nColor
)
939 pSet
->Put( SvxColorItem( GetColor( sal_uInt16(nTokenValue
) ),
943 //#i12501# While cb is clearly documented in the rtf spec, word
944 //doesn't accept it at all
947 if( aPlainMap
.nBgColor
)
949 pSet
->Put( SvxBrushItem( GetColor( sal_uInt16(nTokenValue
) ),
950 aPlainMap
.nBgColor
));
956 if( aPlainMap
.nLanguage
)
958 pSet
->Put( SvxLanguageItem( LanguageType(nTokenValue
),
959 aPlainMap
.nLanguage
));
964 if( aPlainMap
.nCJKLanguage
)
966 pSet
->Put( SvxLanguageItem( LanguageType(nTokenValue
),
967 aPlainMap
.nCJKLanguage
));
972 SvxLanguageItem
aTmpItem( LanguageType(nTokenValue
),
973 SID_ATTR_CHAR_LANGUAGE
);
974 SetScriptAttr( eCharType
, *pSet
, aTmpItem
);
979 bIsLeftToRightDef
= false;
982 bIsLeftToRightDef
= true;
985 if (aPardMap
.nDirection
)
987 pSet
->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_RL_TB
,
988 aPardMap
.nDirection
));
992 if (aPardMap
.nDirection
)
994 pSet
->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB
,
995 aPardMap
.nDirection
));
998 case RTF_LOCH
: eCharType
= LOW_CHARTYPE
; break;
999 case RTF_HICH
: eCharType
= HIGH_CHARTYPE
; break;
1000 case RTF_DBCH
: eCharType
= DOUBLEBYTE_CHARTYPE
; break;
1004 eEmphasis
= FontEmphasisMark::NONE
;
1005 goto ATTR_SETEMPHASIS
;
1007 eEmphasis
= (FontEmphasisMark::Dot
| FontEmphasisMark::PosAbove
);
1008 goto ATTR_SETEMPHASIS
;
1011 eEmphasis
= (FontEmphasisMark::Accent
| FontEmphasisMark::PosAbove
);
1013 if( aPlainMap
.nEmphasis
)
1015 pSet
->Put( SvxEmphasisMarkItem( eEmphasis
,
1016 aPlainMap
.nEmphasis
));
1021 if( aPlainMap
.nTwoLines
)
1023 sal_Unicode cStt
, cEnd
;
1024 switch ( nTokenValue
)
1026 case 1: cStt
= '('; cEnd
= ')'; break;
1027 case 2: cStt
= '['; cEnd
= ']'; break;
1028 case 3: cStt
= '<'; cEnd
= '>'; break;
1029 case 4: cStt
= '{'; cEnd
= '}'; break;
1030 default: cStt
= 0; cEnd
= 0; break;
1033 pSet
->Put( SvxTwoLinesItem( true, cStt
, cEnd
,
1034 aPlainMap
.nTwoLines
));
1038 case RTF_CHARSCALEX
:
1039 if (aPlainMap
.nCharScaleX
)
1042 if (nTokenValue
< 1 || nTokenValue
> 600)
1044 pSet
->Put( SvxCharScaleWidthItem( sal_uInt16(nTokenValue
),
1045 aPlainMap
.nCharScaleX
));
1050 if( aPlainMap
.nHorzVert
)
1052 // RTF knows only 90deg
1053 pSet
->Put( SvxCharRotateItem( 900, 1 == nTokenValue
,
1054 aPlainMap
.nHorzVert
));
1059 if (aPlainMap
.nRelief
)
1061 pSet
->Put(SvxCharReliefItem(FontRelief::Embossed
,
1062 aPlainMap
.nRelief
));
1066 if (aPlainMap
.nRelief
)
1068 pSet
->Put(SvxCharReliefItem(FontRelief::Engraved
,
1069 aPlainMap
.nRelief
));
1073 if (aPlainMap
.nHidden
)
1075 pSet
->Put(SvxCharHiddenItem(nTokenValue
!= 0,
1076 aPlainMap
.nHidden
));
1080 case RTF_CHBGDKVERT
:
1081 case RTF_CHBGDKHORIZ
:
1084 case RTF_CHBGDKFDIAG
:
1085 case RTF_CHBGDCROSS
:
1088 case RTF_CHBGDKDCROSS
:
1089 case RTF_CHBGDKCROSS
:
1090 case RTF_CHBGDKBDIAG
:
1094 if( aPlainMap
.nBgColor
)
1095 ReadBackgroundAttr( nToken
, *pSet
);
1100 // tests on Swg internal tokens
1101 bool bHandled
= false;
1103 if( RTF_IGNOREFLAG
!= GetNextToken())
1105 else if( (nToken
= GetNextToken() ) & RTF_SWGDEFS
)
1113 UnknownAttrToken( nToken
);
1114 // overwrite the closing parenthesis
1117 case RTF_SWG_ESCPROP
:
1119 // Store percentage change!
1120 sal_uInt8 nProp
= sal_uInt8( nTokenValue
/ 100 );
1122 if( 1 == ( nTokenValue
% 100 ))
1123 // Recognize own auto-flags!
1124 nEsc
= DFLT_ESC_AUTO_SUPER
;
1126 if( aPlainMap
.nEscapement
)
1127 pSet
->Put( SvxEscapementItem( nEsc
, nProp
,
1128 aPlainMap
.nEscapement
));
1134 SvxHyphenZoneItem
aHypenZone(
1135 (nTokenValue
& 1) != 0,
1136 aPardMap
.nHyphenzone
);
1137 aHypenZone
.SetPageEnd((nTokenValue
& 2) != 0);
1139 if( aPardMap
.nHyphenzone
&&
1140 RTF_HYPHLEAD
== GetNextToken() &&
1141 RTF_HYPHTRAIL
== GetNextToken() &&
1142 RTF_HYPHMAX
== GetNextToken() )
1144 aHypenZone
.GetMinLead() =
1145 sal_uInt8(GetStackPtr( -2 )->nTokenValue
);
1146 aHypenZone
.GetMinTrail() =
1147 sal_uInt8(GetStackPtr( -1 )->nTokenValue
);
1148 aHypenZone
.GetMaxHyphens() =
1149 sal_uInt8(nTokenValue
);
1151 pSet
->Put( aHypenZone
);
1154 SkipGroup(); // at the end of the group
1161 do { // middle check loop
1162 SvxShadowLocation eSL
= SvxShadowLocation( nTokenValue
);
1163 if( RTF_SHDW_DIST
!= GetNextToken() )
1165 sal_uInt16 nDist
= sal_uInt16( nTokenValue
);
1167 if( RTF_SHDW_STYLE
!= GetNextToken() )
1170 if( RTF_SHDW_COL
!= GetNextToken() )
1172 sal_uInt16 nCol
= sal_uInt16( nTokenValue
);
1174 if( RTF_SHDW_FCOL
!= GetNextToken() )
1177 Color aColor
= GetColor( nCol
);
1179 if( aPardMap
.nShadow
)
1180 pSet
->Put( SvxShadowItem( aPardMap
.nShadow
,
1181 &aColor
, nDist
, eSL
) );
1187 SkipGroup(); // at the end of the group
1193 if( (nToken
& ~(0xff | RTF_SWGDEFS
)) == RTF_TABSTOPDEF
)
1195 nToken
= SkipToken( -2 );
1196 ReadTabAttr( nToken
, *pSet
);
1199 cmc: #i76140, he who consumed the { must consume the }
1200 We rewound to a state of { being the current
1201 token so it is our responsibility to consume the }
1202 token if we consumed the {. We will not have consumed
1203 the { if it belonged to our caller, i.e. if the { we
1204 are handling is the "firsttoken" passed to us then
1205 the *caller* must consume it, not us. Otherwise *we*
1208 if (nToken
== BRACELEFT
&& !bFirstToken
)
1210 nToken
= GetNextToken();
1211 SAL_WARN_IF( nToken
!= BRACERIGHT
,
1213 "} did not follow { as expected");
1216 else if( (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
)
1218 nToken
= SkipToken( -2 );
1219 ReadBorderAttr( nToken
, *pSet
);
1221 else // so no more attribute
1228 cmc: #i4727# / #i12713# Who owns this closing bracket?
1229 If we read the opening one, we must read this one, if
1230 other is counting the brackets so as to push/pop off
1231 the correct environment then we will have pushed a new
1232 environment for the start { of this, but will not see
1233 the } and so is out of sync for the rest of the
1236 if (bHandled
&& !bFirstToken
)
1243 if( nSkip
) // all completely unknown
1246 --nSkip
; // BRACELEFT: is the next token
1253 if( (nToken
& ~0xff ) == RTF_TABSTOPDEF
)
1254 ReadTabAttr( nToken
, *pSet
);
1255 else if( (nToken
& ~0xff ) == RTF_BRDRDEF
)
1256 ReadBorderAttr( nToken
, *pSet
);
1257 else if( (nToken
& ~0xff ) == RTF_SHADINGDEF
)
1258 ReadBackgroundAttr( nToken
, *pSet
);
1261 // unknown token, so token "returned in Parser"
1270 nToken
= GetNextToken();
1272 bFirstToken
= false;
1276 void SvxRTFParser::ReadTabAttr( int nToken
, SfxItemSet
& rSet
)
1278 bool bMethodOwnsToken
= false; // #i52542# patch from cmc.
1279 // then read all the TabStops
1280 SvxTabStop aTabStop
;
1281 SvxTabStopItem
aAttr( 0, 0, SvxTabAdjust::Default
, aPardMap
.nTabStop
);
1282 bool bContinue
= true;
1286 case RTF_TB
: // BarTab ???
1291 aTabStop
.GetTabPos() = nTokenValue
;
1292 aAttr
.Insert( aTabStop
);
1293 aTabStop
= SvxTabStop(); // all values default
1298 aTabStop
.GetAdjustment() = SvxTabAdjust::Left
;
1301 aTabStop
.GetAdjustment() = SvxTabAdjust::Right
;
1304 aTabStop
.GetAdjustment() = SvxTabAdjust::Center
;
1307 aTabStop
.GetAdjustment() = SvxTabAdjust::Decimal
;
1310 case RTF_TLDOT
: aTabStop
.GetFill() = '.'; break;
1311 case RTF_TLHYPH
: aTabStop
.GetFill() = ' '; break;
1312 case RTF_TLUL
: aTabStop
.GetFill() = '_'; break;
1313 case RTF_TLTH
: aTabStop
.GetFill() = '-'; break;
1314 case RTF_TLEQ
: aTabStop
.GetFill() = '='; break;
1318 // Swg - control BRACELEFT RTF_IGNOREFLAG RTF_TLSWG BRACERIGHT
1320 if( RTF_IGNOREFLAG
!= GetNextToken() )
1322 else if( RTF_TLSWG
!= ( nToken
= GetNextToken() ))
1326 aTabStop
.GetDecimal() = sal_uInt8(nTokenValue
& 0xff);
1327 aTabStop
.GetFill() = sal_uInt8((nTokenValue
>> 8) & 0xff);
1328 // overwrite the closing parenthesis
1329 if (bMethodOwnsToken
)
1334 SkipToken( nSkip
); // Ignore back again
1345 nToken
= GetNextToken();
1346 bMethodOwnsToken
= true;
1348 } while( bContinue
);
1350 // Fill with defaults is still missing!
1355 static void SetBorderLine( int nBorderTyp
, SvxBoxItem
& rItem
,
1356 const SvxBorderLine
& rBorder
)
1358 switch( nBorderTyp
)
1360 case RTF_BOX
: // run through all levels
1362 rItem
.SetLine( &rBorder
, SvxBoxItemLine::TOP
);
1363 if( RTF_BOX
!= nBorderTyp
)
1367 rItem
.SetLine( &rBorder
, SvxBoxItemLine::BOTTOM
);
1368 if( RTF_BOX
!= nBorderTyp
)
1372 rItem
.SetLine( &rBorder
, SvxBoxItemLine::LEFT
);
1373 if( RTF_BOX
!= nBorderTyp
)
1377 rItem
.SetLine( &rBorder
, SvxBoxItemLine::RIGHT
);
1378 if( RTF_BOX
!= nBorderTyp
)
1383 void SvxRTFParser::ReadBorderAttr( int nToken
, SfxItemSet
& rSet
,
1386 // then read the border attribute
1387 std::unique_ptr
<SvxBoxItem
> aAttr(std::make_unique
<SvxBoxItem
>(aPardMap
.nBox
));
1388 const SfxPoolItem
* pItem(nullptr);
1390 if( SfxItemState::SET
== rSet
.GetItemState( aPardMap
.nBox
, false, &pItem
) )
1392 aAttr
.reset(static_cast<SvxBoxItem
*>(pItem
->Clone()));
1395 SvxBorderLine
aBrd( nullptr, DEF_LINE_WIDTH_0
); // Simple plain line
1396 bool bContinue
= true;
1400 bool bDoubleWidth
= false;
1410 nBorderTyp
= nToken
;
1413 case RTF_CLBRDRT
: // Cell top border
1417 if (nBorderTyp
!= 0)
1418 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1419 nBorderTyp
= RTF_BRDRT
;
1423 case RTF_CLBRDRB
: // Cell bottom border
1427 if (nBorderTyp
!= 0)
1428 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1429 nBorderTyp
= RTF_BRDRB
;
1433 case RTF_CLBRDRL
: // Cell left border
1437 if (nBorderTyp
!= 0)
1438 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1439 nBorderTyp
= RTF_BRDRL
;
1443 case RTF_CLBRDRR
: // Cell right border
1447 if (nBorderTyp
!= 0)
1448 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1449 nBorderTyp
= RTF_BRDRR
;
1454 case RTF_BRDRDOT
: // dotted border
1455 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DOTTED
);
1457 case RTF_BRDRDASH
: // dashed border
1458 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DASHED
);
1460 case RTF_BRDRHAIR
: // hairline border
1462 aBrd
.SetBorderLineStyle( SvxBorderLineStyle::SOLID
);
1463 aBrd
.SetWidth( DEF_LINE_WIDTH_0
);
1466 case RTF_BRDRDB
: // Double border
1467 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE
);
1469 case RTF_BRDRINSET
: // inset border
1470 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::INSET
);
1472 case RTF_BRDROUTSET
: // outset border
1473 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::OUTSET
);
1475 case RTF_BRDRTNTHSG
: // ThinThick Small gap
1476 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_SMALLGAP
);
1478 case RTF_BRDRTNTHMG
: // ThinThick Medium gap
1479 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_MEDIUMGAP
);
1481 case RTF_BRDRTNTHLG
: // ThinThick Large gap
1482 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THINTHICK_LARGEGAP
);
1484 case RTF_BRDRTHTNSG
: // ThickThin Small gap
1485 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_SMALLGAP
);
1487 case RTF_BRDRTHTNMG
: // ThickThin Medium gap
1488 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_MEDIUMGAP
);
1490 case RTF_BRDRTHTNLG
: // ThickThin Large gap
1491 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::THICKTHIN_LARGEGAP
);
1493 case RTF_BRDREMBOSS
: // Embossed border
1494 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::EMBOSSED
);
1496 case RTF_BRDRENGRAVE
: // Engraved border
1497 aBrd
.SetBorderLineStyle(SvxBorderLineStyle::ENGRAVED
);
1500 case RTF_BRDRS
: // single thickness border
1501 bDoubleWidth
= false;
1503 case RTF_BRDRTH
: // double thickness border width*2
1504 bDoubleWidth
= true;
1506 case RTF_BRDRW
: // border width <255
1507 nWidth
= nTokenValue
;
1510 case RTF_BRDRCF
: // Border color
1511 aBrd
.SetColor( GetColor( sal_uInt16(nTokenValue
) ) );
1514 case RTF_BRDRSH
: // Shadowed border
1515 rSet
.Put( SvxShadowItem( aPardMap
.nShadow
, nullptr, 60 /*3pt*/,
1516 SvxShadowLocation::BottomRight
) );
1519 case RTF_BRSP
: // Spacing to content in twip
1521 switch( nBorderTyp
)
1524 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::BOTTOM
);
1528 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::TOP
);
1532 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::LEFT
);
1536 aAttr
->SetDistance( static_cast<sal_uInt16
>(nTokenValue
), SvxBoxItemLine::RIGHT
);
1540 aAttr
->SetAllDistances( static_cast<sal_uInt16
>(nTokenValue
) );
1546 case RTF_BRDRBTW
: // Border formatting group
1547 case RTF_BRDRBAR
: // Border outside
1548 // TODO unhandled ATM
1552 bContinue
= (nToken
& ~(0xff| RTF_SWGDEFS
)) == RTF_BRDRDEF
;
1555 nToken
= GetNextToken();
1556 } while( bContinue
);
1558 // Finally compute the border width
1559 if ( bDoubleWidth
) nWidth
*= 2;
1560 aBrd
.SetWidth( nWidth
);
1562 SetBorderLine( nBorderTyp
, *aAttr
, aBrd
);
1568 static sal_uInt32
CalcShading( sal_uInt32 nColor
, sal_uInt32 nFillColor
, sal_uInt8 nShading
)
1570 nColor
= (nColor
* nShading
) / 100;
1571 nFillColor
= (nFillColor
* ( 100 - nShading
)) / 100;
1572 return nColor
+ nFillColor
;
1575 void SvxRTFParser::ReadBackgroundAttr( int nToken
, SfxItemSet
& rSet
,
1578 // then read the border attribute
1579 bool bContinue
= true;
1580 sal_uInt16 nColor
= USHRT_MAX
, nFillColor
= USHRT_MAX
;
1581 sal_uInt8 nFillValue
= 0;
1583 sal_uInt16 nWh
= ( nToken
& ~0xff ) == RTF_CHRFMT
1584 ? aPlainMap
.nBgColor
1593 nFillColor
= sal_uInt16( nTokenValue
);
1599 nColor
= sal_uInt16( nTokenValue
);
1605 nFillValue
= static_cast<sal_uInt8
>( nTokenValue
/ 100 );
1609 case RTF_CHBGDKHORIZ
:
1611 case RTF_CLBGDKVERT
:
1612 case RTF_CHBGDKVERT
:
1614 case RTF_CLBGDKBDIAG
:
1615 case RTF_CHBGDKBDIAG
:
1617 case RTF_CLBGDKFDIAG
:
1618 case RTF_CHBGDKFDIAG
:
1620 case RTF_CLBGDKCROSS
:
1621 case RTF_CHBGDKCROSS
:
1623 case RTF_CLBGDKDCROSS
:
1624 case RTF_CHBGDKDCROSS
:
1625 case RTF_BGDKDCROSS
:
1645 case RTF_CLBGDCROSS
:
1646 case RTF_CHBGDCROSS
:
1654 bContinue
= (nToken
& ~(0xff | RTF_TABLEDEF
) ) == RTF_SHADINGDEF
;
1656 bContinue
= (nToken
& ~0xff) == RTF_SHADINGDEF
;
1659 nToken
= GetNextToken();
1660 } while( bContinue
);
1662 Color
aCol( COL_WHITE
), aFCol
;
1665 // there was only one of two colors specified or no BrushType
1666 if( USHRT_MAX
!= nFillColor
)
1669 aCol
= GetColor( nFillColor
);
1671 else if( USHRT_MAX
!= nColor
)
1672 aFCol
= GetColor( nColor
);
1676 if( USHRT_MAX
!= nColor
)
1677 aCol
= GetColor( nColor
);
1681 if( USHRT_MAX
!= nFillColor
)
1682 aFCol
= GetColor( nFillColor
);
1688 if( 0 == nFillValue
|| 100 == nFillValue
)
1692 static_cast<sal_uInt8
>(CalcShading( aCol
.GetRed(), aFCol
.GetRed(), nFillValue
)),
1693 static_cast<sal_uInt8
>(CalcShading( aCol
.GetGreen(), aFCol
.GetGreen(), nFillValue
)),
1694 static_cast<sal_uInt8
>(CalcShading( aCol
.GetBlue(), aFCol
.GetBlue(), nFillValue
)) );
1696 rSet
.Put( SvxBrushItem( aColor
, nWh
) );
1701 // pard / plain handling
1702 void SvxRTFParser::RTFPardPlain( bool const bPard
, SfxItemSet
** ppSet
)
1704 if( !bNewGroup
&& !aAttrStack
.empty() ) // not at the beginning of a new group
1706 SvxRTFItemStackType
* pCurrent
= aAttrStack
.back().get();
1708 int nLastToken
= GetStackPtr(-1)->nTokenId
;
1709 bool bNewStkEntry
= true;
1710 if( RTF_PARD
!= nLastToken
&&
1711 RTF_PLAIN
!= nLastToken
&&
1712 BRACELEFT
!= nLastToken
)
1714 if (pCurrent
->aAttrSet
.Count() || pCurrent
->m_pChildList
|| pCurrent
->nStyleNo
)
1717 std::unique_ptr
<SvxRTFItemStackType
> pNew(new SvxRTFItemStackType( *pCurrent
, *pInsPos
, true ));
1718 pNew
->SetRTFDefaults( GetRTFDefaults() );
1720 // Set all until here valid attributes
1722 pCurrent
= aAttrStack
.empty() ? nullptr : aAttrStack
.back().get(); // can be changed after AttrGroupEnd!
1723 pNew
->aAttrSet
.SetParent( pCurrent
? &pCurrent
->aAttrSet
: nullptr );
1724 aAttrStack
.push_back( std::move(pNew
) );
1725 pCurrent
= aAttrStack
.back().get();
1729 // continue to use this entry as new
1730 pCurrent
->SetStartPos( *pInsPos
);
1731 bNewStkEntry
= false;
1735 // now reset all to default
1737 ( pCurrent
->aAttrSet
.GetParent() || pCurrent
->aAttrSet
.Count() ))
1739 const SfxPoolItem
*pItem
, *pDef
;
1740 const sal_uInt16
* pPtr
;
1742 const SfxItemSet
* pDfltSet
= &GetRTFDefaults();
1745 pCurrent
->nStyleNo
= 0;
1746 pPtr
= reinterpret_cast<sal_uInt16
*>(&aPardMap
);
1747 nCnt
= sizeof(aPardMap
) / sizeof(sal_uInt16
);
1751 pPtr
= reinterpret_cast<sal_uInt16
*>(&aPlainMap
);
1752 nCnt
= sizeof(aPlainMap
) / sizeof(sal_uInt16
);
1755 for( sal_uInt16 n
= 0; n
< nCnt
; ++n
, ++pPtr
)
1757 // Item set and different -> Set the Default Pool
1760 else if (SfxItemPool::IsSlot(*pPtr
))
1761 pCurrent
->aAttrSet
.ClearItem( *pPtr
);
1762 else if( IsChkStyleAttr() )
1763 pCurrent
->aAttrSet
.Put( pDfltSet
->Get( *pPtr
) );
1764 else if( !pCurrent
->aAttrSet
.GetParent() )
1766 if( SfxItemState::SET
==
1767 pDfltSet
->GetItemState( *pPtr
, false, &pDef
))
1768 pCurrent
->aAttrSet
.Put( *pDef
);
1770 pCurrent
->aAttrSet
.ClearItem( *pPtr
);
1772 else if( SfxItemState::SET
== pCurrent
->aAttrSet
.GetParent()->
1773 GetItemState( *pPtr
, true, &pItem
) &&
1774 *( pDef
= &pDfltSet
->Get( *pPtr
)) != *pItem
)
1775 pCurrent
->aAttrSet
.Put( *pDef
);
1778 if( SfxItemState::SET
==
1779 pDfltSet
->GetItemState( *pPtr
, false, &pDef
))
1780 pCurrent
->aAttrSet
.Put( *pDef
);
1782 pCurrent
->aAttrSet
.ClearItem( *pPtr
);
1787 pCurrent
->nStyleNo
= 0; // reset Style number
1789 *ppSet
= &pCurrent
->aAttrSet
;
1793 //Once we have a default font, then any text without a font specifier is
1794 //in the default font, and thus has the default font charset, otherwise
1795 //we can fall back to the ansicpg set codeset
1796 if (nDfltFont
!= -1)
1798 const vcl::Font
& rSVFont
= GetFont(sal_uInt16(nDfltFont
));
1799 SetEncoding(rSVFont
.GetCharSet());
1802 SetEncoding(GetCodeSet());
1807 void SvxRTFParser::SetDefault( int nToken
, int nValue
)
1812 SfxItemSet
aTmp( *pAttrPool
, aWhichMap
.data() );
1813 bool bOldFlag
= bIsLeftToRightDef
;
1814 bIsLeftToRightDef
= true;
1818 bIsLeftToRightDef
= false;
1824 const vcl::Font
& rSVFont
= GetFont( sal_uInt16(nValue
) );
1825 SvxFontItem
aTmpItem(
1826 rSVFont
.GetFamilyType(), rSVFont
.GetFamilyName(),
1827 rSVFont
.GetStyleName(), rSVFont
.GetPitch(),
1828 rSVFont
.GetCharSet(), SID_ATTR_CHAR_FONT
);
1829 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1834 bIsLeftToRightDef
= false;
1837 // store default Language
1840 SvxLanguageItem
aTmpItem( LanguageType(nValue
), SID_ATTR_CHAR_LANGUAGE
);
1841 SetScriptAttr( NOTDEF_CHARTYPE
, aTmp
, aTmpItem
);
1846 if( aPardMap
.nTabStop
)
1848 // RTF defines 720 twips as default
1849 bIsSetDfltTab
= true;
1850 if( -1 == nValue
|| !nValue
)
1853 // who would like to have no twips ...
1856 nTokenValue
= nValue
;
1858 nValue
= nTokenValue
;
1861 // Calculate the ratio of default TabWidth / Tabs and
1862 // calculate the corresponding new number.
1863 // ?? how did one come up with 13 ??
1864 sal_uInt16 nTabCount
= (SVX_TAB_DEFDIST
* 13 ) / sal_uInt16(nValue
);
1866 cmc, make sure we have at least one, or all hell breaks loose in
1867 everybody exporters, #i8247#
1872 // we want Defaulttabs
1873 SvxTabStopItem
aNewTab( nTabCount
, sal_uInt16(nValue
),
1874 SvxTabAdjust::Default
, aPardMap
.nTabStop
);
1876 const_cast<SvxTabStop
&>(aNewTab
[ --nTabCount
]).GetAdjustment() = SvxTabAdjust::Default
;
1878 pAttrPool
->SetPoolDefaultItem( aNewTab
);
1882 bIsLeftToRightDef
= bOldFlag
;
1886 SfxItemIter
aIter( aTmp
);
1887 const SfxPoolItem
* pItem
= aIter
.GetCurItem();
1890 pAttrPool
->SetPoolDefaultItem( *pItem
);
1891 pItem
= aIter
.NextItem();
1896 // default: no conversion, leaving everything in twips.
1897 void SvxRTFParser::CalcValue()
1901 // for tokens that are not evaluated in ReadAttr
1902 void SvxRTFParser::UnknownAttrToken( int )
1906 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */