1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  */
10 
11 #include <drawingml/texteffectscontext.hxx>
12 #include <oox/helper/attributelist.hxx>
13 #include <oox/token/namespaces.hxx>
14 #include <oox/token/tokens.hxx>
15 
16 #include <map>
17 
18 namespace oox { namespace drawingml {
19 
20 namespace
21 {
22 
lclGetNameForElementId(sal_uInt32 aId)23 OUString const & lclGetNameForElementId(sal_uInt32 aId)
24 {
25     static std::map<sal_uInt32, OUString> const aIdMap
26     {
27         { OOX_TOKEN(w14, srgbClr)      , "srgbClr" },
28         { OOX_TOKEN(w14, schemeClr)    , "schemeClr" },
29         { OOX_TOKEN(w14, tint)         , "tint" },
30         { OOX_TOKEN(w14, shade)        , "shade" },
31         { OOX_TOKEN(w14, alpha)        , "alpha" },
32         { OOX_TOKEN(w14, hueMod)       , "hueMod" },
33         { OOX_TOKEN(w14, sat)          , "sat" },
34         { OOX_TOKEN(w14, satOff)       , "satOff" },
35         { OOX_TOKEN(w14, satMod)       , "satMod" },
36         { OOX_TOKEN(w14, lum)          , "lum" },
37         { OOX_TOKEN(w14, lumOff)       , "lumOff" },
38         { OOX_TOKEN(w14, lumMod)       , "lumMod" },
39         { OOX_TOKEN(w14, noFill)       , "noFill" },
40         { OOX_TOKEN(w14, solidFill)    , "solidFill" },
41         { OOX_TOKEN(w14, gradFill)     , "gradFill" },
42         { OOX_TOKEN(w14, gsLst)        , "gsLst" },
43         { OOX_TOKEN(w14, gs)           , "gs" },
44         { OOX_TOKEN(w14, pos)          , "pos" },
45         { OOX_TOKEN(w14, lin)          , "lin" },
46         { OOX_TOKEN(w14, path)         , "path" },
47         { OOX_TOKEN(w14, fillToRect)   , "fillToRect" },
48         { OOX_TOKEN(w14, prstDash)     , "prstDash" },
49         { OOX_TOKEN(w14, round)        , "round" },
50         { OOX_TOKEN(w14, bevel)        , "bevel" },
51         { OOX_TOKEN(w14, miter)        , "miter" },
52         { OOX_TOKEN(w14, camera)       , "camera" },
53         { OOX_TOKEN(w14, lightRig)     , "lightRig" },
54         { OOX_TOKEN(w14, rot)          , "rot" },
55         { OOX_TOKEN(w14, bevelT)       , "bevelT" },
56         { OOX_TOKEN(w14, bevelB)       , "bevelB" },
57         { OOX_TOKEN(w14, extrusionClr) , "extrusionClr" },
58         { OOX_TOKEN(w14, contourClr)   , "contourClr"} ,
59         { OOX_TOKEN(w14, styleSet)     , "styleSet" },
60 
61         { OOX_TOKEN(w14, glow)         , "glow" },
62         { OOX_TOKEN(w14, shadow)       , "shadow" },
63         { OOX_TOKEN(w14, reflection)   , "reflection" },
64         { OOX_TOKEN(w14, textOutline)  , "textOutline" },
65         { OOX_TOKEN(w14, textFill)     , "textFill" },
66         { OOX_TOKEN(w14, scene3d)      , "scene3d" },
67         { OOX_TOKEN(w14, props3d)      , "props3d" },
68         { OOX_TOKEN(w14, ligatures)    , "ligatures" },
69         { OOX_TOKEN(w14, numForm)      , "numForm" },
70         { OOX_TOKEN(w14, numSpacing)   , "numSpacing" },
71         { OOX_TOKEN(w14, stylisticSets), "stylisticSets" },
72         { OOX_TOKEN(w14, cntxtAlts)    , "cntxtAlts" },
73     };
74 
75     return aIdMap.find(aId)->second;
76 }
77 
lclGetGrabBagName(sal_uInt32 aId)78 OUString const & lclGetGrabBagName(sal_uInt32 aId)
79 {
80     static std::map<sal_uInt32, OUString> const aGrabBagNameMap
81     {
82         { OOX_TOKEN(w14, glow)         , "CharGlowTextEffect" },
83         { OOX_TOKEN(w14, shadow)       , "CharShadowTextEffect" },
84         { OOX_TOKEN(w14, reflection)   , "CharReflectionTextEffect" },
85         { OOX_TOKEN(w14, textOutline)  , "CharTextOutlineTextEffect" },
86         { OOX_TOKEN(w14, textFill)     , "CharTextFillTextEffect" },
87         { OOX_TOKEN(w14, scene3d)      , "CharScene3DTextEffect" },
88         { OOX_TOKEN(w14, props3d)      , "CharProps3DTextEffect" },
89         { OOX_TOKEN(w14, ligatures)    , "CharLigaturesTextEffect" },
90         { OOX_TOKEN(w14, numForm)      , "CharNumFormTextEffect" },
91         { OOX_TOKEN(w14, numSpacing)   , "CharNumSpacingTextEffect" },
92         { OOX_TOKEN(w14, stylisticSets), "CharStylisticSetsTextEffect" },
93         { OOX_TOKEN(w14, cntxtAlts)    , "CharCntxtAltsTextEffect" },
94     };
95 
96     return aGrabBagNameMap.find(aId)->second;
97 }
98 
99 }
100 
101 using namespace oox::core;
102 using namespace com::sun::star::uno;
103 using namespace com::sun::star::beans;
104 
TextEffectsContext(ContextHandler2Helper const & rParent,sal_Int32 aElementToken,std::vector<PropertyValue> & rTextEffectsProperties)105 TextEffectsContext::TextEffectsContext(
106                         ContextHandler2Helper const & rParent,
107                         sal_Int32 aElementToken,
108                         std::vector<PropertyValue>& rTextEffectsProperties)
109     : ContextHandler2(rParent)
110     , mrTextEffectsProperties(rTextEffectsProperties)
111     , mnCurrentElement(aElementToken)
112 {
113 }
114 
~TextEffectsContext()115 TextEffectsContext::~TextEffectsContext()
116 {
117 }
118 
pushAttributeToGrabBag(sal_Int32 aAttributeId,const OUString & rElementName,const AttributeList & rAttribs)119 void TextEffectsContext::pushAttributeToGrabBag (sal_Int32 aAttributeId, const OUString& rElementName, const AttributeList& rAttribs)
120 {
121     if (!rAttribs.hasAttribute(aAttributeId))
122         return;
123     OUString aString = rAttribs.getString(aAttributeId).get();
124     mpGrabBagStack->addString(rElementName, aString);
125 }
126 
processAttributes(const AttributeList & rAttribs)127 void TextEffectsContext::processAttributes(const AttributeList& rAttribs)
128 {
129     mpGrabBagStack->push("attributes");
130     switch(mnCurrentElement)
131     {
132         case OOX_TOKEN(w14, glow):
133         {
134             pushAttributeToGrabBag(OOX_TOKEN(w14, rad),  "rad",  rAttribs);
135         }
136         break;
137         case OOX_TOKEN(w14, srgbClr):
138         case OOX_TOKEN(w14, schemeClr):
139         case OOX_TOKEN(w14, tint):
140         case OOX_TOKEN(w14, shade):
141         case OOX_TOKEN(w14, alpha):
142         case OOX_TOKEN(w14, hueMod):
143         case OOX_TOKEN(w14, sat):
144         case OOX_TOKEN(w14, satOff):
145         case OOX_TOKEN(w14, satMod):
146         case OOX_TOKEN(w14, lum):
147         case OOX_TOKEN(w14, lumOff):
148         case OOX_TOKEN(w14, lumMod):
149         {
150             pushAttributeToGrabBag(OOX_TOKEN(w14, val),  "val",  rAttribs);
151         }
152         break;
153         case OOX_TOKEN(w14, shadow):
154         {
155             pushAttributeToGrabBag(OOX_TOKEN(w14, blurRad),  "blurRad",  rAttribs);
156             pushAttributeToGrabBag(OOX_TOKEN(w14, dist),     "dist",  rAttribs);
157             pushAttributeToGrabBag(OOX_TOKEN(w14, dir),      "dir",  rAttribs);
158             pushAttributeToGrabBag(OOX_TOKEN(w14, sx),       "sx",  rAttribs);
159             pushAttributeToGrabBag(OOX_TOKEN(w14, sy),       "sy",  rAttribs);
160             pushAttributeToGrabBag(OOX_TOKEN(w14, kx),       "kx",  rAttribs);
161             pushAttributeToGrabBag(OOX_TOKEN(w14, ky),       "ky",  rAttribs);
162             pushAttributeToGrabBag(OOX_TOKEN(w14, algn),     "algn",  rAttribs);
163         }
164         break;
165         case OOX_TOKEN(w14, reflection):
166         {
167             pushAttributeToGrabBag(OOX_TOKEN(w14, blurRad),  "blurRad",  rAttribs);
168             pushAttributeToGrabBag(OOX_TOKEN(w14, stA),      "stA",  rAttribs);
169             pushAttributeToGrabBag(OOX_TOKEN(w14, stPos),    "stPos",  rAttribs);
170             pushAttributeToGrabBag(OOX_TOKEN(w14, endA),     "endA",  rAttribs);
171             pushAttributeToGrabBag(OOX_TOKEN(w14, endPos),   "endPos",  rAttribs);
172             pushAttributeToGrabBag(OOX_TOKEN(w14, dist),     "dist",  rAttribs);
173             pushAttributeToGrabBag(OOX_TOKEN(w14, dir),      "dir",  rAttribs);
174             pushAttributeToGrabBag(OOX_TOKEN(w14, fadeDir),  "fadeDir",  rAttribs);
175             pushAttributeToGrabBag(OOX_TOKEN(w14, sx),       "sx",  rAttribs);
176             pushAttributeToGrabBag(OOX_TOKEN(w14, sy),       "sy",  rAttribs);
177             pushAttributeToGrabBag(OOX_TOKEN(w14, kx),       "kx",  rAttribs);
178             pushAttributeToGrabBag(OOX_TOKEN(w14, ky),       "ky",  rAttribs);
179             pushAttributeToGrabBag(OOX_TOKEN(w14, algn),     "algn",  rAttribs);
180         }
181         break;
182         case OOX_TOKEN(w14, textOutline):
183         {
184             pushAttributeToGrabBag(OOX_TOKEN(w14, w),     "w",   rAttribs);
185             pushAttributeToGrabBag(OOX_TOKEN(w14, cap),  "cap",  rAttribs);
186             pushAttributeToGrabBag(OOX_TOKEN(w14, cmpd), "cmpd", rAttribs);
187             pushAttributeToGrabBag(OOX_TOKEN(w14, algn), "algn", rAttribs);
188         }
189         break;
190         case OOX_TOKEN(w14, prstDash):
191         {
192             pushAttributeToGrabBag(OOX_TOKEN(w14, val),  "val",  rAttribs);
193         }
194         break;
195         case OOX_TOKEN(w14, gs):
196         {
197             pushAttributeToGrabBag(OOX_TOKEN(w14, pos),  "pos", rAttribs);
198         }
199         break;
200         case OOX_TOKEN(w14, lin):
201         {
202             pushAttributeToGrabBag(OOX_TOKEN(w14, ang),    "ang", rAttribs);
203             pushAttributeToGrabBag(OOX_TOKEN(w14, scaled), "scaled", rAttribs);
204         }
205         break;
206         case OOX_TOKEN(w14, path):
207         {
208             pushAttributeToGrabBag(OOX_TOKEN(w14, path), "path", rAttribs);
209         }
210         break;
211         case OOX_TOKEN(w14, fillToRect):
212         {
213             pushAttributeToGrabBag(OOX_TOKEN(w14, l), "l", rAttribs);
214             pushAttributeToGrabBag(OOX_TOKEN(w14, t), "t", rAttribs);
215             pushAttributeToGrabBag(OOX_TOKEN(w14, r), "r", rAttribs);
216             pushAttributeToGrabBag(OOX_TOKEN(w14, b), "b", rAttribs);
217         }
218         break;
219         case OOX_TOKEN(w14, miter):
220         {
221             pushAttributeToGrabBag(OOX_TOKEN(w14, lim), "lim", rAttribs);
222         }
223         break;
224         case OOX_TOKEN(w14, camera):
225         {
226             pushAttributeToGrabBag(OOX_TOKEN(w14, prst), "prst", rAttribs);
227         }
228         break;
229         case OOX_TOKEN(w14, lightRig):
230         {
231             pushAttributeToGrabBag(OOX_TOKEN(w14, rig), "rig", rAttribs);
232             pushAttributeToGrabBag(OOX_TOKEN(w14, dir), "dir", rAttribs);
233         }
234         break;
235         case OOX_TOKEN(w14, rot):
236         {
237             pushAttributeToGrabBag(OOX_TOKEN(w14, lat), "lat", rAttribs);
238             pushAttributeToGrabBag(OOX_TOKEN(w14, lon), "lon", rAttribs);
239             pushAttributeToGrabBag(OOX_TOKEN(w14, rev), "rev", rAttribs);
240         }
241         break;
242         case OOX_TOKEN(w14, props3d):
243         {
244             pushAttributeToGrabBag(OOX_TOKEN(w14, extrusionH),   "extrusionH", rAttribs);
245             pushAttributeToGrabBag(OOX_TOKEN(w14, contourW),     "contourW", rAttribs);
246             pushAttributeToGrabBag(OOX_TOKEN(w14, prstMaterial), "prstMaterial", rAttribs);
247         }
248         break;
249         case OOX_TOKEN(w14, bevelT):
250         case OOX_TOKEN(w14, bevelB):
251         {
252             pushAttributeToGrabBag(OOX_TOKEN(w14, w),    "w", rAttribs);
253             pushAttributeToGrabBag(OOX_TOKEN(w14, h),    "h", rAttribs);
254             pushAttributeToGrabBag(OOX_TOKEN(w14, prst), "prst", rAttribs);
255         }
256         break;
257         case OOX_TOKEN(w14, ligatures):
258         case OOX_TOKEN(w14, numForm):
259         case OOX_TOKEN(w14, numSpacing):
260         {
261             pushAttributeToGrabBag(OOX_TOKEN(w14, val), "val", rAttribs);
262         }
263         break;
264         case OOX_TOKEN(w14, styleSet):
265         {
266             pushAttributeToGrabBag(OOX_TOKEN(w14, id), "id", rAttribs);
267             pushAttributeToGrabBag(OOX_TOKEN(w14, val), "val", rAttribs);
268         }
269         break;
270         case OOX_TOKEN(w14, cntxtAlts):
271         {
272             pushAttributeToGrabBag(OOX_TOKEN(w14, val), "val", rAttribs);
273         }
274         break;
275         default:
276             break;
277     }
278 
279     mpGrabBagStack->pop();
280 }
281 
onStartElement(const oox::AttributeList & rAttribs)282 void TextEffectsContext::onStartElement(const oox::AttributeList& rAttribs)
283 {
284     if (mpGrabBagStack == nullptr)
285     {
286         OUString aGrabBagName = lclGetGrabBagName(mnCurrentElement);
287         mpGrabBagStack.reset(new GrabBagStack(aGrabBagName));
288     }
289 
290     OUString aElementName = lclGetNameForElementId(mnCurrentElement);
291     mpGrabBagStack->push(aElementName);
292     processAttributes(rAttribs);
293 }
294 
onEndElement()295 void TextEffectsContext::onEndElement()
296 {
297     mpGrabBagStack->pop();
298 
299     if (mpGrabBagStack->isStackEmpty())
300     {
301         Sequence<PropertyValue> aSeq;
302         PropertyValue aPropertyValue = mpGrabBagStack->getRootProperty();
303         aPropertyValue.Value >>= aSeq;
304         aPropertyValue.Value <<= aSeq[0];
305 
306         mrTextEffectsProperties.push_back(aPropertyValue);
307     }
308 
309 }
310 
onCreateContext(sal_Int32 aElementToken,const AttributeList &)311 ContextHandlerRef TextEffectsContext::onCreateContext(sal_Int32 aElementToken, const AttributeList& /*rAttribs*/)
312 {
313     mnCurrentElement = aElementToken;
314     return this;
315 }
316 
317 } }
318 
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
320