Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / oox / source / drawingml / textcharacterpropertiescontext.cxx
blobfb4390e4c7a79604424e7c4b2f6e31004d093433
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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:
92 A_TOKEN( kern )
93 XML_altLang
94 A_TOKEN( kumimoji )
95 A_TOKEN( spc )
96 A_TOKEN( normalizeH )
97 A_TOKEN( noProof )
98 A_TOKEN( dirty )
99 A_TOKEN( err )
100 A_TOKEN( smtClean )
101 A_TOKEN( smtId )
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);
121 // EG_FillProperties
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
131 break;
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));
136 break;
137 // EG_TextUnderlineLine
138 case A_TOKEN( uLnTx ): // CT_TextUnderlineLineFollowText
139 mrTextCharacterProperties.moUnderlineLineFollowText = true;
140 break;
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;
148 break;
149 case A_TOKEN( uFill ): // CT_TextUnderlineFillGroupWrapper->EG_FillProperties (not supported)
150 return new SimpleFillPropertiesContext( *this, mrTextCharacterProperties.maUnderlineColor );
152 // CT_FontCollection
153 case A_TOKEN( latin ): // CT_TextFont
154 mrTextCharacterProperties.maLatinFont.setAttributes( rAttribs );
155 break;
156 case A_TOKEN( ea ): // CT_TextFont
157 mrTextCharacterProperties.maAsianFont.setAttributes( rAttribs );
158 break;
159 case A_TOKEN( cs ): // CT_TextFont
160 mrTextCharacterProperties.maComplexFont.setAttributes( rAttribs );
161 break;
162 case A_TOKEN( sym ): // CT_TextFont
163 mrTextCharacterProperties.maSymbolFont.setAttributes( rAttribs );
164 break;
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)));
194 break;
195 case W_TOKEN( u ):
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;
240 break;
242 case W_TOKEN( spacing ):
244 auto attrib = rAttribs.getInteger(W_TOKEN( val ), 0);
245 mrTextCharacterProperties.moSpacing = attrib;
246 break;
248 case W_TOKEN( b ):
249 mrTextCharacterProperties.moBold = rAttribs.getBool(W_TOKEN( val ), true);
250 break;
251 case W_TOKEN( i ):
252 mrTextCharacterProperties.moItalic = rAttribs.getBool(W_TOKEN( val ), true);
253 break;
254 case W_TOKEN( bCs ):
255 break;
256 case W_TOKEN( strike ):
257 if (rAttribs.getBool(W_TOKEN(val), true))
258 mrTextCharacterProperties.moStrikeout = XML_sngStrike;
259 break;
260 case W_TOKEN( dstrike ):
261 if (rAttribs.getBool(W_TOKEN(val), true))
262 mrTextCharacterProperties.moStrikeout = XML_dblStrike;
263 break;
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;
270 break;
271 case W_TOKEN( sz ):
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;
278 break;
279 case W_TOKEN( szCs ):
280 break;
281 case W_TOKEN( caps ):
283 if( rAttribs.getBool(W_TOKEN( val ), true) )
284 mrTextCharacterProperties.moCaseMap = XML_all;
285 else
286 mrTextCharacterProperties.moCaseMap = XML_none;
288 break;
289 case W_TOKEN( smallCaps ):
291 if( rAttribs.getBool(W_TOKEN( val ), true) )
292 mrTextCharacterProperties.moCaseMap = XML_small;
293 else
294 mrTextCharacterProperties.moCaseMap = XML_none;
296 break;
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;
306 break;
308 case W_TOKEN(lang):
309 mrTextCharacterProperties.moLang = rAttribs.getStringDefaulted(W_TOKEN(val));
310 break;
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 );
326 break;
327 default:
328 SAL_WARN("oox", "TextCharacterPropertiesContext::onCreateContext: unhandled element: " << getBaseToken(aElementToken));
329 break;
332 return this;
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */