Line data Source code
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 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <xmloff/GradientStyle.hxx>
21 :
22 : #include <com/sun/star/awt/Gradient.hpp>
23 :
24 : #include <sax/tools/converter.hxx>
25 :
26 : #include <xmloff/attrlist.hxx>
27 : #include <xmloff/nmspmap.hxx>
28 : #include <xmloff/xmluconv.hxx>
29 : #include <xmloff/xmlnmspe.hxx>
30 : #include <xmloff/xmltoken.hxx>
31 : #include <rtl/ustrbuf.hxx>
32 : #include <rtl/ustring.hxx>
33 : #include <tools/debug.hxx>
34 : #include <xmloff/xmltkmap.hxx>
35 : #include <xmloff/xmlexp.hxx>
36 : #include <xmloff/xmlimp.hxx>
37 :
38 : using namespace ::com::sun::star;
39 :
40 : using namespace ::xmloff::token;
41 :
42 : enum SvXMLTokenMapAttrs
43 : {
44 : XML_TOK_GRADIENT_NAME,
45 : XML_TOK_GRADIENT_DISPLAY_NAME,
46 : XML_TOK_GRADIENT_STYLE,
47 : XML_TOK_GRADIENT_CX,
48 : XML_TOK_GRADIENT_CY,
49 : XML_TOK_GRADIENT_STARTCOLOR,
50 : XML_TOK_GRADIENT_ENDCOLOR,
51 : XML_TOK_GRADIENT_STARTINT,
52 : XML_TOK_GRADIENT_ENDINT,
53 : XML_TOK_GRADIENT_ANGLE,
54 : XML_TOK_GRADIENT_BORDER,
55 : XML_TOK_TABSTOP_END=XML_TOK_UNKNOWN
56 : };
57 :
58 : SvXMLEnumMapEntry const pXML_GradientStyle_Enum[] =
59 : {
60 : { XML_GRADIENTSTYLE_LINEAR, awt::GradientStyle_LINEAR },
61 : { XML_GRADIENTSTYLE_AXIAL, awt::GradientStyle_AXIAL },
62 : { XML_GRADIENTSTYLE_RADIAL, awt::GradientStyle_RADIAL },
63 : { XML_GRADIENTSTYLE_ELLIPSOID, awt::GradientStyle_ELLIPTICAL },
64 : { XML_GRADIENTSTYLE_SQUARE, awt::GradientStyle_SQUARE },
65 : { XML_GRADIENTSTYLE_RECTANGULAR, awt::GradientStyle_RECT },
66 : { XML_TOKEN_INVALID, 0 }
67 : };
68 :
69 : // Import
70 200 : XMLGradientStyleImport::XMLGradientStyleImport(
71 : SvXMLImport& rImp )
72 200 : : rImport(rImp)
73 : {
74 200 : }
75 :
76 200 : XMLGradientStyleImport::~XMLGradientStyleImport()
77 : {
78 200 : }
79 :
80 200 : bool XMLGradientStyleImport::importXML(
81 : const uno::Reference< xml::sax::XAttributeList >& xAttrList,
82 : uno::Any& rValue,
83 : OUString& rStrName )
84 : {
85 : static const SvXMLTokenMapEntry aGradientAttrTokenMap[] =
86 : {
87 : { XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_GRADIENT_NAME },
88 : { XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, XML_TOK_GRADIENT_DISPLAY_NAME },
89 : { XML_NAMESPACE_DRAW, XML_STYLE, XML_TOK_GRADIENT_STYLE },
90 : { XML_NAMESPACE_DRAW, XML_CX, XML_TOK_GRADIENT_CX },
91 : { XML_NAMESPACE_DRAW, XML_CY, XML_TOK_GRADIENT_CY },
92 : { XML_NAMESPACE_DRAW, XML_START_COLOR, XML_TOK_GRADIENT_STARTCOLOR },
93 : { XML_NAMESPACE_DRAW, XML_END_COLOR, XML_TOK_GRADIENT_ENDCOLOR },
94 : { XML_NAMESPACE_DRAW, XML_START_INTENSITY, XML_TOK_GRADIENT_STARTINT },
95 : { XML_NAMESPACE_DRAW, XML_END_INTENSITY, XML_TOK_GRADIENT_ENDINT },
96 : { XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, XML_TOK_GRADIENT_ANGLE },
97 : { XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, XML_TOK_GRADIENT_BORDER },
98 : XML_TOKEN_MAP_END
99 : };
100 :
101 200 : bool bHasName = false;
102 200 : bool bHasStyle = false;
103 200 : bool bHasStartColor = false;
104 200 : bool bHasEndColor = false;
105 200 : OUString aDisplayName;
106 :
107 200 : awt::Gradient aGradient;
108 200 : aGradient.XOffset = 0;
109 200 : aGradient.YOffset = 0;
110 200 : aGradient.StartIntensity = 100;
111 200 : aGradient.EndIntensity = 100;
112 200 : aGradient.Angle = 0;
113 200 : aGradient.Border = 0;
114 :
115 400 : SvXMLTokenMap aTokenMap( aGradientAttrTokenMap );
116 200 : SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
117 :
118 200 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
119 1998 : for( sal_Int16 i=0; i < nAttrCount; i++ )
120 : {
121 1798 : const OUString& rFullAttrName = xAttrList->getNameByIndex( i );
122 3596 : OUString aStrAttrName;
123 1798 : sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rFullAttrName, &aStrAttrName );
124 3596 : const OUString& rStrValue = xAttrList->getValueByIndex( i );
125 :
126 : sal_Int32 nTmpValue;
127 :
128 1798 : switch( aTokenMap.Get( nPrefix, aStrAttrName ) )
129 : {
130 : case XML_TOK_GRADIENT_NAME:
131 : {
132 200 : rStrName = rStrValue;
133 200 : bHasName = true;
134 : }
135 200 : break;
136 : case XML_TOK_GRADIENT_DISPLAY_NAME:
137 : {
138 150 : aDisplayName = rStrValue;
139 : }
140 150 : break;
141 : case XML_TOK_GRADIENT_STYLE:
142 : {
143 : sal_uInt16 eValue;
144 200 : if( SvXMLUnitConverter::convertEnum( eValue, rStrValue, pXML_GradientStyle_Enum ) )
145 : {
146 200 : aGradient.Style = (awt::GradientStyle) eValue;
147 200 : bHasStyle = true;
148 : }
149 : }
150 200 : break;
151 : case XML_TOK_GRADIENT_CX:
152 34 : ::sax::Converter::convertPercent( nTmpValue, rStrValue );
153 34 : aGradient.XOffset = static_cast< sal_Int16 >( nTmpValue );
154 34 : break;
155 : case XML_TOK_GRADIENT_CY:
156 34 : ::sax::Converter::convertPercent( nTmpValue, rStrValue );
157 34 : aGradient.YOffset = static_cast< sal_Int16 >( nTmpValue );
158 34 : break;
159 : case XML_TOK_GRADIENT_STARTCOLOR:
160 : {
161 : bHasStartColor = ::sax::Converter::convertColor(
162 200 : aGradient.StartColor, rStrValue);
163 : }
164 200 : break;
165 : case XML_TOK_GRADIENT_ENDCOLOR:
166 : {
167 : bHasStartColor = ::sax::Converter::convertColor(
168 200 : aGradient.EndColor, rStrValue);
169 : }
170 200 : break;
171 : case XML_TOK_GRADIENT_STARTINT:
172 200 : ::sax::Converter::convertPercent( nTmpValue, rStrValue );
173 200 : aGradient.StartIntensity = static_cast< sal_Int16 >( nTmpValue );
174 200 : break;
175 : case XML_TOK_GRADIENT_ENDINT:
176 200 : ::sax::Converter::convertPercent( nTmpValue, rStrValue );
177 200 : aGradient.EndIntensity = static_cast< sal_Int16 >( nTmpValue );
178 200 : break;
179 : case XML_TOK_GRADIENT_ANGLE:
180 : {
181 : sal_Int32 nValue;
182 180 : ::sax::Converter::convertNumber( nValue, rStrValue, 0, 3600 );
183 180 : aGradient.Angle = sal_Int16( nValue );
184 : }
185 180 : break;
186 : case XML_TOK_GRADIENT_BORDER:
187 200 : ::sax::Converter::convertPercent( nTmpValue, rStrValue );
188 200 : aGradient.Border = static_cast< sal_Int16 >( nTmpValue );
189 200 : break;
190 :
191 : default:
192 : DBG_WARNING( "Unknown token at import gradient style" )
193 : ;
194 : }
195 1798 : }
196 :
197 200 : rValue <<= aGradient;
198 :
199 200 : if( !aDisplayName.isEmpty() )
200 : {
201 : rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_GRADIENT_ID, rStrName,
202 150 : aDisplayName );
203 150 : rStrName = aDisplayName;
204 : }
205 :
206 200 : bool bRet = bHasName && bHasStyle && bHasStartColor && bHasEndColor;
207 :
208 400 : return bRet;
209 : }
210 :
211 : // Export
212 :
213 674 : XMLGradientStyleExport::XMLGradientStyleExport(
214 : SvXMLExport& rExp )
215 674 : : rExport(rExp)
216 : {
217 674 : }
218 :
219 674 : XMLGradientStyleExport::~XMLGradientStyleExport()
220 : {
221 674 : }
222 :
223 8 : bool XMLGradientStyleExport::exportXML(
224 : const OUString& rStrName,
225 : const uno::Any& rValue )
226 : {
227 8 : bool bRet = false;
228 8 : awt::Gradient aGradient;
229 :
230 8 : if( !rStrName.isEmpty() )
231 : {
232 8 : if( rValue >>= aGradient )
233 : {
234 8 : OUString aStrValue;
235 16 : OUStringBuffer aOut;
236 :
237 : // Style
238 8 : if( !SvXMLUnitConverter::convertEnum( aOut, aGradient.Style, pXML_GradientStyle_Enum ) )
239 : {
240 0 : bRet = false;
241 : }
242 : else
243 : {
244 : // Name
245 8 : bool bEncoded = false;
246 8 : OUString aStrName( rStrName );
247 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME,
248 : rExport.EncodeStyleName( aStrName,
249 8 : &bEncoded ) );
250 8 : if( bEncoded )
251 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME,
252 8 : aStrName );
253 :
254 8 : aStrValue = aOut.makeStringAndClear();
255 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_STYLE, aStrValue );
256 :
257 : // Center x/y
258 12 : if( aGradient.Style != awt::GradientStyle_LINEAR &&
259 4 : aGradient.Style != awt::GradientStyle_AXIAL )
260 : {
261 0 : ::sax::Converter::convertPercent(aOut, aGradient.XOffset);
262 0 : aStrValue = aOut.makeStringAndClear();
263 0 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CX, aStrValue );
264 0 : ::sax::Converter::convertPercent(aOut, aGradient.YOffset);
265 0 : aStrValue = aOut.makeStringAndClear();
266 0 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CY, aStrValue );
267 : }
268 :
269 : // Color start
270 8 : ::sax::Converter::convertColor(aOut, aGradient.StartColor);
271 8 : aStrValue = aOut.makeStringAndClear();
272 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_START_COLOR, aStrValue );
273 :
274 : // Color end
275 8 : ::sax::Converter::convertColor(aOut, aGradient.EndColor);
276 8 : aStrValue = aOut.makeStringAndClear();
277 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_END_COLOR, aStrValue );
278 :
279 : // Intensity start
280 8 : ::sax::Converter::convertPercent(aOut, aGradient.StartIntensity);
281 8 : aStrValue = aOut.makeStringAndClear();
282 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_START_INTENSITY, aStrValue );
283 :
284 : // Intensity end
285 8 : ::sax::Converter::convertPercent(aOut, aGradient.EndIntensity);
286 8 : aStrValue = aOut.makeStringAndClear();
287 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_END_INTENSITY, aStrValue );
288 :
289 : // Angle
290 8 : if( aGradient.Style != awt::GradientStyle_RADIAL )
291 : {
292 8 : ::sax::Converter::convertNumber(aOut, sal_Int32(aGradient.Angle));
293 8 : aStrValue = aOut.makeStringAndClear();
294 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, aStrValue );
295 : }
296 :
297 : // Border
298 8 : ::sax::Converter::convertPercent( aOut, aGradient.Border );
299 8 : aStrValue = aOut.makeStringAndClear();
300 8 : rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, aStrValue );
301 :
302 : // Do Write
303 : SvXMLElementExport aElem( rExport, XML_NAMESPACE_DRAW, XML_GRADIENT,
304 8 : true, false );
305 8 : }
306 : }
307 : }
308 :
309 8 : return bRet;
310 : }
311 :
312 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|