1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 #include "xmloff/GradientStyle.hxx"
31 #include <com/sun/star/awt/Gradient.hpp>
32 #include <xmloff/attrlist.hxx>
33 #include <xmloff/nmspmap.hxx>
34 #include <xmloff/xmluconv.hxx>
35 #include "xmloff/xmlnmspe.hxx"
36 #include <xmloff/xmltoken.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <rtl/ustring.hxx>
39 #include <tools/debug.hxx>
40 #include <xmloff/xmltkmap.hxx>
41 #include <xmloff/xmlexp.hxx>
42 #include <xmloff/xmlimp.hxx>
43 
44 
45 
46 using namespace ::com::sun::star;
47 using ::rtl::OUString;
48 using ::rtl::OUStringBuffer;
49 
50 using namespace ::xmloff::token;
51 
52 enum SvXMLTokenMapAttrs
53 {
54 	XML_TOK_GRADIENT_NAME,
55 	XML_TOK_GRADIENT_DISPLAY_NAME,
56 	XML_TOK_GRADIENT_STYLE,
57 	XML_TOK_GRADIENT_CX,
58 	XML_TOK_GRADIENT_CY,
59 	XML_TOK_GRADIENT_STARTCOLOR,
60 	XML_TOK_GRADIENT_ENDCOLOR,
61 	XML_TOK_GRADIENT_STARTINT,
62 	XML_TOK_GRADIENT_ENDINT,
63 	XML_TOK_GRADIENT_ANGLE,
64 	XML_TOK_GRADIENT_BORDER,
65 	XML_TOK_TABSTOP_END=XML_TOK_UNKNOWN
66 };
67 
68 
69 SvXMLEnumMapEntry __READONLY_DATA pXML_GradientStyle_Enum[] =
70 {
71 	{ XML_GRADIENTSTYLE_LINEAR,		    awt::GradientStyle_LINEAR },
72 	{ XML_GRADIENTSTYLE_AXIAL,			awt::GradientStyle_AXIAL },
73 	{ XML_GRADIENTSTYLE_RADIAL,		    awt::GradientStyle_RADIAL },
74 	{ XML_GRADIENTSTYLE_ELLIPSOID,		awt::GradientStyle_ELLIPTICAL },
75 	{ XML_GRADIENTSTYLE_SQUARE,		    awt::GradientStyle_SQUARE },
76 	{ XML_GRADIENTSTYLE_RECTANGULAR,	awt::GradientStyle_RECT },
77 	{ XML_TOKEN_INVALID, 0 }
78 };
79 
80 //-------------------------------------------------------------
81 // Import
82 //-------------------------------------------------------------
83 XMLGradientStyleImport::XMLGradientStyleImport(
84     SvXMLImport& rImp )
85     : rImport(rImp)
86 {
87 }
88 
89 XMLGradientStyleImport::~XMLGradientStyleImport()
90 {
91 }
92 
93 sal_Bool XMLGradientStyleImport::importXML(
94     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
95     uno::Any& rValue,
96     OUString& rStrName )
97 {
98 	sal_Bool bRet           = sal_False;
99 	sal_Bool bHasName       = sal_False;
100 	sal_Bool bHasStyle      = sal_False;
101 	sal_Bool bHasStartColor = sal_False;
102 	sal_Bool bHasEndColor   = sal_False;
103 	OUString aDisplayName;
104 
105 	awt::Gradient aGradient;
106 	aGradient.XOffset = 0;
107 	aGradient.YOffset = 0;
108 	aGradient.StartIntensity = 100;
109 	aGradient.EndIntensity = 100;
110 	aGradient.Angle = 0;
111 	aGradient.Border = 0;
112 
113     {
114         static __FAR_DATA SvXMLTokenMapEntry aGradientAttrTokenMap[] =
115 {
116 	{ XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_GRADIENT_NAME },
117 	{ XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, XML_TOK_GRADIENT_DISPLAY_NAME },
118 	{ XML_NAMESPACE_DRAW, XML_STYLE, XML_TOK_GRADIENT_STYLE },
119 	{ XML_NAMESPACE_DRAW, XML_CX, XML_TOK_GRADIENT_CX },
120 	{ XML_NAMESPACE_DRAW, XML_CY, XML_TOK_GRADIENT_CY },
121 	{ XML_NAMESPACE_DRAW, XML_START_COLOR, XML_TOK_GRADIENT_STARTCOLOR },
122 	{ XML_NAMESPACE_DRAW, XML_END_COLOR, XML_TOK_GRADIENT_ENDCOLOR },
123 	{ XML_NAMESPACE_DRAW, XML_START_INTENSITY, XML_TOK_GRADIENT_STARTINT },
124 	{ XML_NAMESPACE_DRAW, XML_END_INTENSITY, XML_TOK_GRADIENT_ENDINT },
125 	{ XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, XML_TOK_GRADIENT_ANGLE },
126     { XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, XML_TOK_GRADIENT_BORDER },
127 	XML_TOKEN_MAP_END
128 };
129 
130 	SvXMLTokenMap aTokenMap( aGradientAttrTokenMap );
131     SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
132 
133 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
134 	for( sal_Int16 i=0; i < nAttrCount; i++ )
135 	{
136 		const OUString& rFullAttrName = xAttrList->getNameByIndex( i );
137 		OUString aStrAttrName;
138 		sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rFullAttrName, &aStrAttrName );
139 		const OUString& rStrValue = xAttrList->getValueByIndex( i );
140 
141 		sal_Int32 nTmpValue;
142 
143 		switch( aTokenMap.Get( nPrefix, aStrAttrName ) )
144 		{
145 		case XML_TOK_GRADIENT_NAME:
146 			{
147 				rStrName = rStrValue;
148 				bHasName = sal_True;
149 			}
150 			break;
151 		case XML_TOK_GRADIENT_DISPLAY_NAME:
152 			{
153 				aDisplayName = rStrValue;
154 			}
155 			break;
156 		case XML_TOK_GRADIENT_STYLE:
157 			{
158 				sal_uInt16 eValue;
159 				if( SvXMLUnitConverter::convertEnum( eValue, rStrValue, pXML_GradientStyle_Enum ) )
160 				{
161 					aGradient.Style = (awt::GradientStyle) eValue;
162 					bHasStyle = sal_True;
163 				}
164 			}
165 			break;
166 		case XML_TOK_GRADIENT_CX:
167 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
168 			aGradient.XOffset = static_cast< sal_Int16 >( nTmpValue );
169 			break;
170 		case XML_TOK_GRADIENT_CY:
171 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
172 			aGradient.YOffset = static_cast< sal_Int16 >( nTmpValue );
173 			break;
174 		case XML_TOK_GRADIENT_STARTCOLOR:
175 			{
176 				Color aColor;
177                 bHasStartColor = SvXMLUnitConverter::convertColor( aColor, rStrValue );
178 				if( bHasStartColor )
179 					aGradient.StartColor = (sal_Int32)( aColor.GetColor() );
180 			}
181 			break;
182 		case XML_TOK_GRADIENT_ENDCOLOR:
183 			{
184 				Color aColor;
185                 bHasStartColor = SvXMLUnitConverter::convertColor( aColor, rStrValue );
186 				if( bHasStartColor )
187 					aGradient.EndColor = (sal_Int32)( aColor.GetColor() );
188 			}
189 			break;
190 		case XML_TOK_GRADIENT_STARTINT:
191 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
192 			aGradient.StartIntensity = static_cast< sal_Int16 >( nTmpValue );
193 			break;
194 		case XML_TOK_GRADIENT_ENDINT:
195 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
196 			aGradient.EndIntensity = static_cast< sal_Int16 >( nTmpValue );
197 			break;
198 		case XML_TOK_GRADIENT_ANGLE:
199 			{
200 				sal_Int32 nValue;
201 				SvXMLUnitConverter::convertNumber( nValue, rStrValue, 0, 3600 );
202 				aGradient.Angle = sal_Int16( nValue );
203 			}
204 			break;
205 		case XML_TOK_GRADIENT_BORDER:
206 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
207 			aGradient.Border = static_cast< sal_Int16 >( nTmpValue );
208 			break;
209 
210 		default:
211 			DBG_WARNING( "Unknown token at import gradient style" )
212 			;
213 		}
214 	}
215 
216 	rValue <<= aGradient;
217 
218 	if( aDisplayName.getLength() )
219 	{
220 		rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_GRADIENT_ID, rStrName,
221 									 aDisplayName );
222 		rStrName = aDisplayName;
223 	}
224 
225 	bRet = bHasName && bHasStyle && bHasStartColor && bHasEndColor;
226 
227     }
228 
229 	return bRet;
230 }
231 
232 
233 //-------------------------------------------------------------
234 // Export
235 //-------------------------------------------------------------
236 
237 #ifndef SVX_LIGHT
238 
239 XMLGradientStyleExport::XMLGradientStyleExport(
240     SvXMLExport& rExp )
241     : rExport(rExp)
242 {
243 }
244 
245 XMLGradientStyleExport::~XMLGradientStyleExport()
246 {
247 }
248 
249 sal_Bool XMLGradientStyleExport::exportXML(
250     const OUString& rStrName,
251     const uno::Any& rValue )
252 {
253 	sal_Bool bRet = sal_False;
254 	awt::Gradient aGradient;
255 
256 	if( rStrName.getLength() )
257 	{
258 		if( rValue >>= aGradient )
259 		{
260 			OUString aStrValue;
261 			OUStringBuffer aOut;
262 
263 			// Style
264 			if( !SvXMLUnitConverter::convertEnum( aOut, aGradient.Style, pXML_GradientStyle_Enum ) )
265 			{
266 				bRet = sal_False;
267 			}
268 			else
269 			{
270 				// Name
271 				sal_Bool bEncoded = sal_False;
272 				OUString aStrName( rStrName );
273 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME,
274 									  rExport.EncodeStyleName( aStrName,
275 										 					   &bEncoded ) );
276 				if( bEncoded )
277 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME,
278 									  	  aStrName );
279 
280 
281 				aStrValue = aOut.makeStringAndClear();
282 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_STYLE, aStrValue );
283 
284 				// Center x/y
285 				if( aGradient.Style != awt::GradientStyle_LINEAR &&
286 					aGradient.Style != awt::GradientStyle_AXIAL   )
287 				{
288 					SvXMLUnitConverter::convertPercent( aOut, aGradient.XOffset );
289 					aStrValue = aOut.makeStringAndClear();
290 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CX, aStrValue );
291 
292 					SvXMLUnitConverter::convertPercent( aOut, aGradient.YOffset );
293 					aStrValue = aOut.makeStringAndClear();
294 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CY, aStrValue );
295 				}
296 
297 				Color aColor;
298 
299 				// Color start
300 				aColor.SetColor( aGradient.StartColor );
301 				SvXMLUnitConverter::convertColor( aOut, aColor );
302 				aStrValue = aOut.makeStringAndClear();
303 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_START_COLOR, aStrValue );
304 
305 				// Color end
306 				aColor.SetColor( aGradient.EndColor );
307 				SvXMLUnitConverter::convertColor( aOut, aColor );
308 				aStrValue = aOut.makeStringAndClear();
309 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_END_COLOR, aStrValue );
310 
311 				// Intensity start
312 				SvXMLUnitConverter::convertPercent( aOut, aGradient.StartIntensity );
313 				aStrValue = aOut.makeStringAndClear();
314 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_START_INTENSITY, aStrValue );
315 
316 				// Intensity end
317 				SvXMLUnitConverter::convertPercent( aOut, aGradient.EndIntensity );
318 				aStrValue = aOut.makeStringAndClear();
319 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_END_INTENSITY, aStrValue );
320 
321 				// Angle
322 				if( aGradient.Style != awt::GradientStyle_RADIAL )
323 				{
324 					SvXMLUnitConverter::convertNumber( aOut, sal_Int32( aGradient.Angle ) );
325 					aStrValue = aOut.makeStringAndClear();
326 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, aStrValue );
327 				}
328 
329 				// Border
330 				SvXMLUnitConverter::convertPercent( aOut, aGradient.Border );
331 				aStrValue = aOut.makeStringAndClear();
332 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, aStrValue );
333 
334 				// Do Write
335 				SvXMLElementExport aElem( rExport, XML_NAMESPACE_DRAW, XML_GRADIENT,
336                                       sal_True, sal_False );
337 			}
338 		}
339 	}
340 
341 	return bRet;
342 }
343 
344 #endif // #ifndef SVX_LIGHT
345