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 "TransGradientStyle.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 <rtl/ustrbuf.hxx>
37 #include <rtl/ustring.hxx>
38 #include <tools/debug.hxx>
39 #include <xmloff/xmltkmap.hxx>
40 #include <xmloff/xmlexp.hxx>
41 #include <xmloff/xmlimp.hxx>
42 
43 
44 using namespace ::com::sun::star;
45 using ::rtl::OUString;
46 using ::rtl::OUStringBuffer;
47 
48 using namespace ::xmloff::token;
49 
50 enum SvXMLTokenMapAttrs
51 {
52 	XML_TOK_GRADIENT_NAME,
53 	XML_TOK_GRADIENT_DISPLAY_NAME,
54 	XML_TOK_GRADIENT_STYLE,
55 	XML_TOK_GRADIENT_CX,
56 	XML_TOK_GRADIENT_CY,
57 	XML_TOK_GRADIENT_START,
58 	XML_TOK_GRADIENT_END,
59 	XML_TOK_GRADIENT_ANGLE,
60 	XML_TOK_GRADIENT_BORDER,
61 	XML_TOK_TABSTOP_END=XML_TOK_UNKNOWN
62 };
63 
64 
65 SvXMLEnumMapEntry __READONLY_DATA pXML_GradientStyle_Enum[] =
66 {
67 	{ XML_GRADIENTSTYLE_LINEAR,		    awt::GradientStyle_LINEAR },
68 	{ XML_GRADIENTSTYLE_AXIAL,			awt::GradientStyle_AXIAL },
69 	{ XML_GRADIENTSTYLE_RADIAL,		    awt::GradientStyle_RADIAL },
70 	{ XML_GRADIENTSTYLE_ELLIPSOID,		awt::GradientStyle_ELLIPTICAL },
71 	{ XML_GRADIENTSTYLE_SQUARE,		    awt::GradientStyle_SQUARE },
72 	{ XML_GRADIENTSTYLE_RECTANGULAR,	awt::GradientStyle_RECT },
73 	{ XML_TOKEN_INVALID,                0 }
74 };
75 
76 
77 //-------------------------------------------------------------
78 // Import
79 //-------------------------------------------------------------
80 
81 XMLTransGradientStyleImport::XMLTransGradientStyleImport( SvXMLImport& rImp )
82     : rImport(rImp)
83 {
84 }
85 
86 XMLTransGradientStyleImport::~XMLTransGradientStyleImport()
87 {
88 }
89 
90 sal_Bool XMLTransGradientStyleImport::importXML(
91     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
92     uno::Any& rValue,
93     OUString& rStrName )
94 {
95 	sal_Bool bRet           = sal_False;
96 	sal_Bool bHasName       = sal_False;
97 	sal_Bool bHasStyle      = sal_False;
98 	OUString aDisplayName;
99 
100 	awt::Gradient aGradient;
101 	aGradient.XOffset = 0;
102 	aGradient.YOffset = 0;
103 	aGradient.StartIntensity = 100;
104 	aGradient.EndIntensity = 100;
105 	aGradient.Angle = 0;
106 	aGradient.Border = 0;
107 
108     {
109         static __FAR_DATA SvXMLTokenMapEntry aTrGradientAttrTokenMap[] =
110 {
111 	{ XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_GRADIENT_NAME },
112 	{ XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, XML_TOK_GRADIENT_DISPLAY_NAME },
113 	{ XML_NAMESPACE_DRAW, XML_STYLE, XML_TOK_GRADIENT_STYLE },
114 	{ XML_NAMESPACE_DRAW, XML_CX, XML_TOK_GRADIENT_CX },
115 	{ XML_NAMESPACE_DRAW, XML_CY, XML_TOK_GRADIENT_CY },
116 	{ XML_NAMESPACE_DRAW, XML_START, XML_TOK_GRADIENT_START },
117 	{ XML_NAMESPACE_DRAW, XML_END, XML_TOK_GRADIENT_END },
118 	{ XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, XML_TOK_GRADIENT_ANGLE },
119 	{ XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, XML_TOK_GRADIENT_BORDER },
120 	XML_TOKEN_MAP_END
121 };
122 
123 	SvXMLTokenMap aTokenMap( aTrGradientAttrTokenMap );
124     SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
125 
126 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
127 	for( sal_Int16 i=0; i < nAttrCount; i++ )
128 	{
129 		const OUString& rFullAttrName = xAttrList->getNameByIndex( i );
130 		OUString aStrAttrName;
131 		sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rFullAttrName, &aStrAttrName );
132 		const OUString& rStrValue = xAttrList->getValueByIndex( i );
133 
134 		sal_Int32 nTmpValue;
135 
136 		switch( aTokenMap.Get( nPrefix, aStrAttrName ) )
137 		{
138 		case XML_TOK_GRADIENT_NAME:
139 			{
140 				rStrName = rStrValue;
141 				bHasName = sal_True;
142 			}
143 			break;
144 		case XML_TOK_GRADIENT_DISPLAY_NAME:
145 			{
146 				aDisplayName = rStrValue;
147 			}
148 			break;
149 		case XML_TOK_GRADIENT_STYLE:
150 			{
151 				sal_uInt16 eValue;
152 				if( SvXMLUnitConverter::convertEnum( eValue, rStrValue, pXML_GradientStyle_Enum ) )
153 				{
154 					aGradient.Style = (awt::GradientStyle) eValue;
155 					bHasStyle = sal_True;
156 				}
157 			}
158 			break;
159 		case XML_TOK_GRADIENT_CX:
160 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
161 			aGradient.XOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
162 			break;
163 		case XML_TOK_GRADIENT_CY:
164 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
165 			aGradient.YOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
166 			break;
167 		case XML_TOK_GRADIENT_START:
168 			{
169 				sal_Int32 aStartTransparency;
170 				SvXMLUnitConverter::convertPercent( aStartTransparency, rStrValue );
171 
172 				sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
173                     ( (100 - aStartTransparency) * 255 ) / 100 );
174 
175 				Color aColor( n, n, n );
176 				aGradient.StartColor = (sal_Int32)( aColor.GetColor() );
177 			}
178 			break;
179 		case XML_TOK_GRADIENT_END:
180 			{
181 				sal_Int32 aEndTransparency;
182 				SvXMLUnitConverter::convertPercent( aEndTransparency, rStrValue );
183 
184 				sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
185                     ( (100 - aEndTransparency) * 255 ) / 100 );
186 
187 				Color aColor( n, n, n );
188 				aGradient.EndColor = (sal_Int32)( aColor.GetColor() );
189 			}
190 			break;
191 		case XML_TOK_GRADIENT_ANGLE:
192 			{
193 				sal_Int32 nValue;
194 				SvXMLUnitConverter::convertNumber( nValue, rStrValue, 0, 3600 );
195 				aGradient.Angle = sal_Int16( nValue );
196 			}
197 			break;
198 		case XML_TOK_GRADIENT_BORDER:
199 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
200 			aGradient.Border = sal::static_int_cast< sal_Int16 >(nTmpValue);
201 			break;
202 
203 		default:
204 			DBG_WARNING( "Unknown token at import transparency gradient style" )
205 			;
206 		}
207 	}
208 
209 	rValue <<= aGradient;
210 
211 	if( aDisplayName.getLength() )
212 	{
213 		rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_GRADIENT_ID, rStrName,
214 									 aDisplayName );
215 		rStrName = aDisplayName;
216 	}
217 
218 	bRet = bHasName && bHasStyle;
219 
220     }
221 
222 	return bRet;
223 }
224 
225 
226 //-------------------------------------------------------------
227 // Export
228 //-------------------------------------------------------------
229 
230 #ifndef SVX_LIGHT
231 
232 XMLTransGradientStyleExport::XMLTransGradientStyleExport( SvXMLExport& rExp )
233     : rExport(rExp)
234 {
235 }
236 
237 XMLTransGradientStyleExport::~XMLTransGradientStyleExport()
238 {
239 }
240 
241 
242 sal_Bool XMLTransGradientStyleExport::exportXML(
243     const OUString& rStrName,
244     const uno::Any& rValue )
245 {
246 	sal_Bool bRet = sal_False;
247 	awt::Gradient aGradient;
248 
249 	if( rStrName.getLength() )
250 	{
251 		if( rValue >>= aGradient )
252 		{
253 			OUString aStrValue;
254 			OUStringBuffer aOut;
255 
256 			// Style
257 			if( !SvXMLUnitConverter::convertEnum( aOut, aGradient.Style, pXML_GradientStyle_Enum ) )
258 			{
259 				bRet = sal_False;
260 			}
261 			else
262 			{
263 				// Name
264 				sal_Bool bEncoded = sal_False;
265 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME,
266 									  rExport.EncodeStyleName( rStrName,
267 										 					   &bEncoded ) );
268 				if( bEncoded )
269 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME,
270 									  	  rStrName );
271 
272 				aStrValue = aOut.makeStringAndClear();
273 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_STYLE, aStrValue );
274 
275 				// Center x/y
276 				if( aGradient.Style != awt::GradientStyle_LINEAR &&
277 					aGradient.Style != awt::GradientStyle_AXIAL   )
278 				{
279 					SvXMLUnitConverter::convertPercent( aOut, aGradient.XOffset );
280 					aStrValue = aOut.makeStringAndClear();
281 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CX, aStrValue );
282 
283 					SvXMLUnitConverter::convertPercent( aOut, aGradient.YOffset );
284 					aStrValue = aOut.makeStringAndClear();
285 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CY, aStrValue );
286 				}
287 
288 
289 				Color aColor;
290 
291 				// Transparency start
292 				aColor.SetColor( aGradient.StartColor );
293 				sal_Int32 aStartValue = 100 - (sal_Int32)(((aColor.GetRed() + 1) * 100) / 255);
294 				SvXMLUnitConverter::convertPercent( aOut, aStartValue );
295 				aStrValue = aOut.makeStringAndClear();
296 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_START, aStrValue );
297 
298 				// Transparency end
299 				aColor.SetColor( aGradient.EndColor );
300 				sal_Int32 aEndValue = 100 - (sal_Int32)(((aColor.GetRed() + 1) * 100) / 255);
301 				SvXMLUnitConverter::convertPercent( aOut, aEndValue );
302 				aStrValue = aOut.makeStringAndClear();
303 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_END, aStrValue );
304 
305 				// Angle
306 				if( aGradient.Style != awt::GradientStyle_RADIAL )
307 				{
308 					SvXMLUnitConverter::convertNumber( aOut, sal_Int32( aGradient.Angle ) );
309 					aStrValue = aOut.makeStringAndClear();
310 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, aStrValue );
311 				}
312 
313 				// Border
314 				SvXMLUnitConverter::convertPercent( aOut, aGradient.Border );
315 				aStrValue = aOut.makeStringAndClear();
316 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, aStrValue );
317 
318 				// Do Write
319 				SvXMLElementExport rElem( rExport,
320 										  XML_NAMESPACE_DRAW, XML_OPACITY,
321 										  sal_True, sal_False );
322 			}
323 		}
324 	}
325 
326 	return bRet;
327 }
328 
329 #endif // #ifndef SVX_LIGHT
330