1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "TransGradientStyle.hxx"
27 #include <com/sun/star/awt/Gradient.hpp>
28 #include <xmloff/attrlist.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include <xmloff/xmluconv.hxx>
31 #include "xmloff/xmlnmspe.hxx"
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/ustring.hxx>
34 #include <tools/debug.hxx>
35 #include <xmloff/xmltkmap.hxx>
36 #include <xmloff/xmlexp.hxx>
37 #include <xmloff/xmlimp.hxx>
38 
39 
40 using namespace ::com::sun::star;
41 using ::rtl::OUString;
42 using ::rtl::OUStringBuffer;
43 
44 using namespace ::xmloff::token;
45 
46 enum SvXMLTokenMapAttrs
47 {
48 	XML_TOK_GRADIENT_NAME,
49 	XML_TOK_GRADIENT_DISPLAY_NAME,
50 	XML_TOK_GRADIENT_STYLE,
51 	XML_TOK_GRADIENT_CX,
52 	XML_TOK_GRADIENT_CY,
53 	XML_TOK_GRADIENT_START,
54 	XML_TOK_GRADIENT_END,
55 	XML_TOK_GRADIENT_ANGLE,
56 	XML_TOK_GRADIENT_BORDER,
57 	XML_TOK_TABSTOP_END=XML_TOK_UNKNOWN
58 };
59 
60 
61 SvXMLEnumMapEntry __READONLY_DATA pXML_GradientStyle_Enum[] =
62 {
63 	{ XML_GRADIENTSTYLE_LINEAR,		    awt::GradientStyle_LINEAR },
64 	{ XML_GRADIENTSTYLE_AXIAL,			awt::GradientStyle_AXIAL },
65 	{ XML_GRADIENTSTYLE_RADIAL,		    awt::GradientStyle_RADIAL },
66 	{ XML_GRADIENTSTYLE_ELLIPSOID,		awt::GradientStyle_ELLIPTICAL },
67 	{ XML_GRADIENTSTYLE_SQUARE,		    awt::GradientStyle_SQUARE },
68 	{ XML_GRADIENTSTYLE_RECTANGULAR,	awt::GradientStyle_RECT },
69 	{ XML_TOKEN_INVALID,                0 }
70 };
71 
72 
73 //-------------------------------------------------------------
74 // Import
75 //-------------------------------------------------------------
76 
XMLTransGradientStyleImport(SvXMLImport & rImp)77 XMLTransGradientStyleImport::XMLTransGradientStyleImport( SvXMLImport& rImp )
78     : rImport(rImp)
79 {
80 }
81 
~XMLTransGradientStyleImport()82 XMLTransGradientStyleImport::~XMLTransGradientStyleImport()
83 {
84 }
85 
importXML(const uno::Reference<xml::sax::XAttributeList> & xAttrList,uno::Any & rValue,OUString & rStrName)86 sal_Bool XMLTransGradientStyleImport::importXML(
87     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
88     uno::Any& rValue,
89     OUString& rStrName )
90 {
91 	sal_Bool bRet           = sal_False;
92 	sal_Bool bHasName       = sal_False;
93 	sal_Bool bHasStyle      = sal_False;
94 	OUString aDisplayName;
95 
96 	awt::Gradient aGradient;
97 	aGradient.XOffset = 0;
98 	aGradient.YOffset = 0;
99 	aGradient.StartIntensity = 100;
100 	aGradient.EndIntensity = 100;
101 	aGradient.Angle = 0;
102 	aGradient.Border = 0;
103 
104     {
105         static __FAR_DATA SvXMLTokenMapEntry aTrGradientAttrTokenMap[] =
106 {
107 	{ XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_GRADIENT_NAME },
108 	{ XML_NAMESPACE_DRAW, XML_DISPLAY_NAME, XML_TOK_GRADIENT_DISPLAY_NAME },
109 	{ XML_NAMESPACE_DRAW, XML_STYLE, XML_TOK_GRADIENT_STYLE },
110 	{ XML_NAMESPACE_DRAW, XML_CX, XML_TOK_GRADIENT_CX },
111 	{ XML_NAMESPACE_DRAW, XML_CY, XML_TOK_GRADIENT_CY },
112 	{ XML_NAMESPACE_DRAW, XML_START, XML_TOK_GRADIENT_START },
113 	{ XML_NAMESPACE_DRAW, XML_END, XML_TOK_GRADIENT_END },
114 	{ XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, XML_TOK_GRADIENT_ANGLE },
115 	{ XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, XML_TOK_GRADIENT_BORDER },
116 	XML_TOKEN_MAP_END
117 };
118 
119 	SvXMLTokenMap aTokenMap( aTrGradientAttrTokenMap );
120     SvXMLNamespaceMap& rNamespaceMap = rImport.GetNamespaceMap();
121 
122 	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
123 	for( sal_Int16 i=0; i < nAttrCount; i++ )
124 	{
125 		const OUString& rFullAttrName = xAttrList->getNameByIndex( i );
126 		OUString aStrAttrName;
127 		sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rFullAttrName, &aStrAttrName );
128 		const OUString& rStrValue = xAttrList->getValueByIndex( i );
129 
130 		sal_Int32 nTmpValue;
131 
132 		switch( aTokenMap.Get( nPrefix, aStrAttrName ) )
133 		{
134 		case XML_TOK_GRADIENT_NAME:
135 			{
136 				rStrName = rStrValue;
137 				bHasName = sal_True;
138 			}
139 			break;
140 		case XML_TOK_GRADIENT_DISPLAY_NAME:
141 			{
142 				aDisplayName = rStrValue;
143 			}
144 			break;
145 		case XML_TOK_GRADIENT_STYLE:
146 			{
147 				sal_uInt16 eValue;
148 				if( SvXMLUnitConverter::convertEnum( eValue, rStrValue, pXML_GradientStyle_Enum ) )
149 				{
150 					aGradient.Style = (awt::GradientStyle) eValue;
151 					bHasStyle = sal_True;
152 				}
153 			}
154 			break;
155 		case XML_TOK_GRADIENT_CX:
156 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
157 			aGradient.XOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
158 			break;
159 		case XML_TOK_GRADIENT_CY:
160 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
161 			aGradient.YOffset = sal::static_int_cast< sal_Int16 >(nTmpValue);
162 			break;
163 		case XML_TOK_GRADIENT_START:
164 			{
165 				sal_Int32 aStartTransparency;
166 				SvXMLUnitConverter::convertPercent( aStartTransparency, rStrValue );
167 
168 				sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
169                     ( (100 - aStartTransparency) * 255 ) / 100 );
170 
171 				Color aColor( n, n, n );
172 				aGradient.StartColor = (sal_Int32)( aColor.GetColor() );
173 			}
174 			break;
175 		case XML_TOK_GRADIENT_END:
176 			{
177 				sal_Int32 aEndTransparency;
178 				SvXMLUnitConverter::convertPercent( aEndTransparency, rStrValue );
179 
180 				sal_uInt8 n = sal::static_int_cast< sal_uInt8 >(
181                     ( (100 - aEndTransparency) * 255 ) / 100 );
182 
183 				Color aColor( n, n, n );
184 				aGradient.EndColor = (sal_Int32)( aColor.GetColor() );
185 			}
186 			break;
187 		case XML_TOK_GRADIENT_ANGLE:
188 			{
189 				sal_Int32 nValue;
190 				SvXMLUnitConverter::convertNumber( nValue, rStrValue, 0, 3600 );
191 				aGradient.Angle = sal_Int16( nValue );
192 			}
193 			break;
194 		case XML_TOK_GRADIENT_BORDER:
195 			SvXMLUnitConverter::convertPercent( nTmpValue, rStrValue );
196 			aGradient.Border = sal::static_int_cast< sal_Int16 >(nTmpValue);
197 			break;
198 
199 		default:
200 			DBG_WARNING( "Unknown token at import transparency gradient style" )
201 			;
202 		}
203 	}
204 
205 	rValue <<= aGradient;
206 
207 	if( aDisplayName.getLength() )
208 	{
209 		rImport.AddStyleDisplayName( XML_STYLE_FAMILY_SD_GRADIENT_ID, rStrName,
210 									 aDisplayName );
211 		rStrName = aDisplayName;
212 	}
213 
214 	bRet = bHasName && bHasStyle;
215 
216     }
217 
218 	return bRet;
219 }
220 
221 
222 //-------------------------------------------------------------
223 // Export
224 //-------------------------------------------------------------
225 
226 #ifndef SVX_LIGHT
227 
XMLTransGradientStyleExport(SvXMLExport & rExp)228 XMLTransGradientStyleExport::XMLTransGradientStyleExport( SvXMLExport& rExp )
229     : rExport(rExp)
230 {
231 }
232 
~XMLTransGradientStyleExport()233 XMLTransGradientStyleExport::~XMLTransGradientStyleExport()
234 {
235 }
236 
237 
exportXML(const OUString & rStrName,const uno::Any & rValue)238 sal_Bool XMLTransGradientStyleExport::exportXML(
239     const OUString& rStrName,
240     const uno::Any& rValue )
241 {
242 	sal_Bool bRet = sal_False;
243 	awt::Gradient aGradient;
244 
245 	if( rStrName.getLength() )
246 	{
247 		if( rValue >>= aGradient )
248 		{
249 			OUString aStrValue;
250 			OUStringBuffer aOut;
251 
252 			// Style
253 			if( !SvXMLUnitConverter::convertEnum( aOut, aGradient.Style, pXML_GradientStyle_Enum ) )
254 			{
255 				bRet = sal_False;
256 			}
257 			else
258 			{
259 				// Name
260 				sal_Bool bEncoded = sal_False;
261 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_NAME,
262 									  rExport.EncodeStyleName( rStrName,
263 										 					   &bEncoded ) );
264 				if( bEncoded )
265 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_DISPLAY_NAME,
266 									  	  rStrName );
267 
268 				aStrValue = aOut.makeStringAndClear();
269 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_STYLE, aStrValue );
270 
271 				// Center x/y
272 				if( aGradient.Style != awt::GradientStyle_LINEAR &&
273 					aGradient.Style != awt::GradientStyle_AXIAL   )
274 				{
275 					SvXMLUnitConverter::convertPercent( aOut, aGradient.XOffset );
276 					aStrValue = aOut.makeStringAndClear();
277 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CX, aStrValue );
278 
279 					SvXMLUnitConverter::convertPercent( aOut, aGradient.YOffset );
280 					aStrValue = aOut.makeStringAndClear();
281 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_CY, aStrValue );
282 				}
283 
284 
285 				Color aColor;
286 
287 				// Transparency start
288 				aColor.SetColor( aGradient.StartColor );
289 				sal_Int32 aStartValue = 100 - (sal_Int32)(((aColor.GetRed() + 1) * 100) / 255);
290 				SvXMLUnitConverter::convertPercent( aOut, aStartValue );
291 				aStrValue = aOut.makeStringAndClear();
292 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_START, aStrValue );
293 
294 				// Transparency end
295 				aColor.SetColor( aGradient.EndColor );
296 				sal_Int32 aEndValue = 100 - (sal_Int32)(((aColor.GetRed() + 1) * 100) / 255);
297 				SvXMLUnitConverter::convertPercent( aOut, aEndValue );
298 				aStrValue = aOut.makeStringAndClear();
299 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_END, aStrValue );
300 
301 				// Angle
302 				if( aGradient.Style != awt::GradientStyle_RADIAL )
303 				{
304 					SvXMLUnitConverter::convertNumber( aOut, sal_Int32( aGradient.Angle ) );
305 					aStrValue = aOut.makeStringAndClear();
306 					rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_ANGLE, aStrValue );
307 				}
308 
309 				// Border
310 				SvXMLUnitConverter::convertPercent( aOut, aGradient.Border );
311 				aStrValue = aOut.makeStringAndClear();
312 				rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_GRADIENT_BORDER, aStrValue );
313 
314 				// Do Write
315 				SvXMLElementExport rElem( rExport,
316 										  XML_NAMESPACE_DRAW, XML_OPACITY,
317 										  sal_True, sal_False );
318 			}
319 		}
320 	}
321 
322 	return bRet;
323 }
324 
325 #endif // #ifndef SVX_LIGHT
326