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 .
20 #include <drawingml/textcharacterpropertiescontext.hxx>
22 #include <oox/helper/attributelist.hxx>
23 #include <drawingml/colorchoicecontext.hxx>
24 #include <drawingml/linepropertiescontext.hxx>
25 #include <drawingml/misccontexts.hxx>
26 #include <drawingml/textcharacterproperties.hxx>
27 #include <drawingml/texteffectscontext.hxx>
28 #include "hyperlinkcontext.hxx"
29 #include <oox/token/namespaces.hxx>
30 #include <oox/token/tokens.hxx>
31 #include <sax/fastattribs.hxx>
33 #include <sal/log.hxx>
35 using namespace ::oox::core
;
36 using namespace ::com::sun::star::uno
;
37 using namespace ::com::sun::star::xml::sax
;
38 using namespace ::com::sun::star::awt
;
40 namespace oox::drawingml
{
42 // CT_TextCharacterProperties
43 TextCharacterPropertiesContext::TextCharacterPropertiesContext(
44 ContextHandler2Helper
const & rParent
,
45 const AttributeList
& rAttribs
,
46 TextCharacterProperties
& rTextCharacterProperties
)
47 : ContextHandler2( rParent
)
48 , mrTextCharacterProperties( rTextCharacterProperties
)
50 int nVisualTokenAmount
= sax_fastparser::castToFastAttributeList(
51 rAttribs
.getFastAttributeList() ).getFastAttributeTokens().size();
53 if ( rAttribs
.hasAttribute( XML_lang
) )
55 mrTextCharacterProperties
.moLang
= rAttribs
.getString( XML_lang
);
56 --nVisualTokenAmount
; // Not a visual attribute
58 if ( rAttribs
.hasAttribute( XML_altLang
))
60 --nVisualTokenAmount
; // Not a visual attribute
62 if ( rAttribs
.hasAttribute( XML_sz
) )
63 mrTextCharacterProperties
.moHeight
= rAttribs
.getInteger( XML_sz
);
64 if ( rAttribs
.hasAttribute( XML_spc
) )
65 mrTextCharacterProperties
.moSpacing
= rAttribs
.getInteger( XML_spc
);
66 if ( rAttribs
.hasAttribute( XML_u
) )
67 mrTextCharacterProperties
.moUnderline
= rAttribs
.getToken( XML_u
);
68 if ( rAttribs
.hasAttribute( XML_strike
) )
69 mrTextCharacterProperties
.moStrikeout
= rAttribs
.getToken( XML_strike
);
70 if ( rAttribs
.hasAttribute( XML_baseline
) && rAttribs
.getInteger( XML_baseline
, 0 ) != 0 )
71 mrTextCharacterProperties
.moBaseline
= rAttribs
.getInteger( XML_baseline
);
73 if ( rAttribs
.hasAttribute( XML_b
) )
74 mrTextCharacterProperties
.moBold
= rAttribs
.getBool( XML_b
);
75 if ( rAttribs
.hasAttribute( XML_i
) )
76 mrTextCharacterProperties
.moItalic
= rAttribs
.getBool( XML_i
);
77 if( rAttribs
.hasAttribute( XML_cap
) )
78 mrTextCharacterProperties
.moCaseMap
= rAttribs
.getToken( XML_cap
);
79 if ( rAttribs
.hasAttribute( XML_dirty
) )
81 --nVisualTokenAmount
; // Not a visual attribute
83 if ( rAttribs
.hasAttribute( XML_smtClean
) )
85 --nVisualTokenAmount
; // Not a visual attribute
88 if ( nVisualTokenAmount
> 0 )
89 mrTextCharacterProperties
.mbHasVisualRunProperties
= true;
91 /* TODO / unhandled so far:
105 TextCharacterPropertiesContext::~TextCharacterPropertiesContext()
109 ContextHandlerRef
TextCharacterPropertiesContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
111 if( aElementToken
!= A_TOKEN(lang
) )
112 mrTextCharacterProperties
.mbHasVisualRunProperties
= true;
114 switch( aElementToken
)
116 case A_TOKEN(ln
): // CT_LineProperties
117 // TODO still largely unsupported
118 if (!mrTextCharacterProperties
.moTextOutlineProperties
.has_value())
119 mrTextCharacterProperties
.moTextOutlineProperties
.emplace();
120 return new LinePropertiesContext(*this, rAttribs
, *mrTextCharacterProperties
.moTextOutlineProperties
);
122 case A_TOKEN( noFill
):
123 case A_TOKEN( solidFill
):
124 case A_TOKEN( gradFill
):
125 case A_TOKEN( pattFill
):
126 case A_TOKEN( blipFill
): // Fontwork uses blibFill.
127 return FillPropertiesContext::createFillContext(*this, aElementToken
, rAttribs
, mrTextCharacterProperties
.maFillProperties
, nullptr);
128 // EG_EffectProperties
129 case A_TOKEN( effectDag
): // CT_EffectContainer 5.1.10.25
130 case A_TOKEN( effectLst
): // CT_EffectList 5.1.10.26
132 case A_TOKEN( highlight
): // CT_Color
133 return new ColorContext(*this, mrTextCharacterProperties
.maHighlightColor
);
134 case W_TOKEN( highlight
):
135 mrTextCharacterProperties
.maHighlightColor
= rAttribs
.getHighlightColor(W_TOKEN(val
));
137 // EG_TextUnderlineLine
138 case A_TOKEN( uLnTx
): // CT_TextUnderlineLineFollowText
139 mrTextCharacterProperties
.moUnderlineLineFollowText
= true;
141 // TODO unsupported yet
142 // case A_TOKEN( uLn ): // CT_LineProperties
143 // return new LinePropertiesContext( getHandler(), rAttribs, maUnderlineProperties );
145 // EG_TextUnderlineFill
146 case A_TOKEN( uFillTx
): // CT_TextUnderlineFillFollowText
147 mrTextCharacterProperties
.moUnderlineFillFollowText
= true;
149 case A_TOKEN( uFill
): // CT_TextUnderlineFillGroupWrapper->EG_FillProperties (not supported)
150 return new SimpleFillPropertiesContext( *this, mrTextCharacterProperties
.maUnderlineColor
);
153 case A_TOKEN( latin
): // CT_TextFont
154 mrTextCharacterProperties
.maLatinFont
.setAttributes( rAttribs
);
156 case A_TOKEN( ea
): // CT_TextFont
157 mrTextCharacterProperties
.maAsianFont
.setAttributes( rAttribs
);
159 case A_TOKEN( cs
): // CT_TextFont
160 mrTextCharacterProperties
.maComplexFont
.setAttributes( rAttribs
);
162 case A_TOKEN( sym
): // CT_TextFont
163 mrTextCharacterProperties
.maSymbolFont
.setAttributes( rAttribs
);
166 case A_TOKEN( hlinkClick
): // CT_Hyperlink
167 case A_TOKEN( hlinkMouseOver
): // CT_Hyperlink
168 return new HyperLinkContext( *this, rAttribs
, mrTextCharacterProperties
.maHyperlinkPropertyMap
);
169 case W_TOKEN( rFonts
):
170 if( rAttribs
.hasAttribute(W_TOKEN(ascii
)) )
172 mrTextCharacterProperties
.maLatinFont
.setAttributes(rAttribs
.getStringDefaulted(W_TOKEN(ascii
)));
174 if (rAttribs
.hasAttribute(W_TOKEN(asciiTheme
)))
176 mrTextCharacterProperties
.maLatinThemeFont
.setAttributes(rAttribs
.getStringDefaulted(W_TOKEN(asciiTheme
)));
178 if( rAttribs
.hasAttribute(W_TOKEN(cs
)) )
180 mrTextCharacterProperties
.maComplexFont
.setAttributes(rAttribs
.getStringDefaulted(W_TOKEN(cs
)));
182 if (rAttribs
.hasAttribute(W_TOKEN(cstheme
)))
184 mrTextCharacterProperties
.maComplexThemeFont
.setAttributes(rAttribs
.getStringDefaulted(W_TOKEN(cstheme
)));
186 if( rAttribs
.hasAttribute(W_TOKEN(eastAsia
)) )
188 mrTextCharacterProperties
.maAsianFont
.setAttributes(rAttribs
.getStringDefaulted(W_TOKEN(eastAsia
)));
190 if (rAttribs
.hasAttribute(W_TOKEN(eastAsiaTheme
)))
192 mrTextCharacterProperties
.maAsianThemeFont
.setAttributes(rAttribs
.getStringDefaulted(W_TOKEN(eastAsiaTheme
)));
197 // If you add here, check if it is in drawingmltypes.cxx 113.
198 auto attrib
= rAttribs
.getStringDefaulted(W_TOKEN(val
));
199 if (attrib
== "single" || attrib
== "words") // TODO: implement words properly. Now it is a single line.
200 mrTextCharacterProperties
.moUnderline
= XML_sng
;
201 else if (attrib
== "wavyHeavy")
202 mrTextCharacterProperties
.moUnderline
= XML_wavyHeavy
;
203 else if (attrib
== "wavyDouble")
204 mrTextCharacterProperties
.moUnderline
= XML_wavyDbl
;
205 else if (attrib
== "wave")
206 mrTextCharacterProperties
.moUnderline
= XML_wavy
;
207 else if (attrib
== "thick")
208 mrTextCharacterProperties
.moUnderline
= XML_heavy
;
209 else if (attrib
== "dottedHeavy")
210 mrTextCharacterProperties
.moUnderline
= XML_dottedHeavy
;
211 else if (attrib
== "dotted")
212 mrTextCharacterProperties
.moUnderline
= XML_dotted
;
213 else if (attrib
== "dashDotDotHeavy")
214 mrTextCharacterProperties
.moUnderline
= XML_dotDotDashHeavy
;
215 else if (attrib
== "dotDotDash")
216 mrTextCharacterProperties
.moUnderline
= XML_dotDotDash
;
217 else if (attrib
== "dashDotHeavy")
218 mrTextCharacterProperties
.moUnderline
= XML_dotDashHeavy
;
219 else if (attrib
== "dotDash")
220 mrTextCharacterProperties
.moUnderline
= XML_dotDash
;
221 else if (attrib
== "double")
222 mrTextCharacterProperties
.moUnderline
= XML_dbl
;
223 else if (attrib
== "dashLongHeavy")
224 mrTextCharacterProperties
.moUnderline
= XML_dashLongHeavy
;
225 else if (attrib
== "dashLong")
226 mrTextCharacterProperties
.moUnderline
= XML_dashLong
;
227 else if (attrib
== "dashedHeavy")
228 mrTextCharacterProperties
.moUnderline
= XML_dashHeavy
;
229 else if (attrib
== "dash")
230 mrTextCharacterProperties
.moUnderline
= XML_dash
;
231 else if (attrib
== "none")
232 mrTextCharacterProperties
.moUnderline
= XML_none
;
233 auto colorAttrib
= rAttribs
.getIntegerHex(W_TOKEN(color
));
234 if (colorAttrib
.has_value())
236 oox::drawingml::Color theColor
;
237 theColor
.setSrgbClr(colorAttrib
.value());
238 mrTextCharacterProperties
.maUnderlineColor
= theColor
;
242 case W_TOKEN( spacing
):
244 auto attrib
= rAttribs
.getInteger(W_TOKEN( val
), 0);
245 mrTextCharacterProperties
.moSpacing
= attrib
;
249 mrTextCharacterProperties
.moBold
= rAttribs
.getBool(W_TOKEN( val
), true);
252 mrTextCharacterProperties
.moItalic
= rAttribs
.getBool(W_TOKEN( val
), true);
256 case W_TOKEN( strike
):
257 if (rAttribs
.getBool(W_TOKEN(val
), true))
258 mrTextCharacterProperties
.moStrikeout
= XML_sngStrike
;
260 case W_TOKEN( dstrike
):
261 if (rAttribs
.getBool(W_TOKEN(val
), true))
262 mrTextCharacterProperties
.moStrikeout
= XML_dblStrike
;
264 case W_TOKEN( color
):
265 if (rAttribs
.getInteger(W_TOKEN(val
)).has_value())
267 mrTextCharacterProperties
.maFillProperties
.maFillColor
.setSrgbClr(rAttribs
.getIntegerHex(W_TOKEN(val
), 0));
268 mrTextCharacterProperties
.maFillProperties
.moFillType
= XML_solidFill
;
272 if (rAttribs
.getInteger(W_TOKEN(val
)).has_value())
274 sal_Int32 nVal
= rAttribs
.getInteger(W_TOKEN(val
), 0);
275 // wml has half points, dml has hundred points
276 mrTextCharacterProperties
.moHeight
= nVal
* 50;
279 case W_TOKEN( szCs
):
281 case W_TOKEN( caps
):
283 if( rAttribs
.getBool(W_TOKEN( val
), true) )
284 mrTextCharacterProperties
.moCaseMap
= XML_all
;
286 mrTextCharacterProperties
.moCaseMap
= XML_none
;
289 case W_TOKEN( smallCaps
):
291 if( rAttribs
.getBool(W_TOKEN( val
), true) )
292 mrTextCharacterProperties
.moCaseMap
= XML_small
;
294 mrTextCharacterProperties
.moCaseMap
= XML_none
;
297 case W_TOKEN(vertAlign
):
299 // Map wordprocessingML <w:vertAlign w:val="..."/> to drawingML
300 // <a:rPr baseline="...">.
301 sal_Int32 nVal
= rAttribs
.getToken(W_TOKEN(val
), 0);
302 if (nVal
== XML_superscript
)
303 mrTextCharacterProperties
.moBaseline
= 30000;
304 else if (nVal
== XML_subscript
)
305 mrTextCharacterProperties
.moBaseline
= -25000;
309 mrTextCharacterProperties
.moLang
= rAttribs
.getStringDefaulted(W_TOKEN(val
));
311 case OOX_TOKEN(w14
, glow
):
312 case OOX_TOKEN(w14
, shadow
):
313 case OOX_TOKEN(w14
, reflection
):
314 case OOX_TOKEN(w14
, textOutline
):
315 case OOX_TOKEN(w14
, textFill
):
316 case OOX_TOKEN(w14
, scene3d
):
317 case OOX_TOKEN(w14
, props3d
):
318 case OOX_TOKEN(w14
, ligatures
):
319 case OOX_TOKEN(w14
, numForm
):
320 case OOX_TOKEN(w14
, numSpacing
):
321 case OOX_TOKEN(w14
, stylisticSets
):
322 case OOX_TOKEN(w14
, cntxtAlts
):
324 return new TextEffectsContext( *this, aElementToken
, mrTextCharacterProperties
.maTextEffectsProperties
);
328 SAL_WARN("oox", "TextCharacterPropertiesContext::onCreateContext: unhandled element: " << getBaseToken(aElementToken
));
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */