xref: /AOO41X/main/xmloff/source/draw/shapeexport3.cxx (revision f7c60c9c54b9df31f919e125fa03a7515f4855a8)
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 <com/sun/star/drawing/HomogenMatrix.hpp>
27 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
28 #include <com/sun/star/drawing/ProjectionMode.hpp>
29 #include <com/sun/star/drawing/ShadeMode.hpp>
30 #include <com/sun/star/drawing/Direction3D.hpp>
31 #include <com/sun/star/drawing/Position3D.hpp>
32 #include <com/sun/star/drawing/CameraGeometry.hpp>
33 #include <com/sun/star/drawing/DoubleSequence.hpp>
34 #include <tools/gen.hxx>
35 
36 #ifndef _XMLOFF_SHAPEEXPORT_HXX
37 #include <xmloff/shapeexport.hxx>
38 #endif
39 #include "sdpropls.hxx"
40 #include <tools/debug.hxx>
41 #include <rtl/ustrbuf.hxx>
42 #include <xmloff/xmlexp.hxx>
43 #include <xmloff/xmluconv.hxx>
44 #include "xexptran.hxx"
45 #include <xmloff/xmltoken.hxx>
46 #include <basegfx/vector/b3dvector.hxx>
47 
48 #include "xmloff/xmlnmspe.hxx"
49 
50 using ::rtl::OUString;
51 using ::rtl::OUStringBuffer;
52 
53 using namespace ::com::sun::star;
54 using namespace ::xmloff::token;
55 
56 
57 //////////////////////////////////////////////////////////////////////////////
58 
59 void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
60 {
61 	uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
62 	if(xShapes.is() && xShapes->getCount())
63 	{
64 		uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
65 		DBG_ASSERT( xPropSet.is(), "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
66 		if( xPropSet.is() )
67 		{
68 			// Transformation
69 			ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);
70 
71 			// 3d attributes
72 			export3DSceneAttributes( xPropSet );
73 
74 			// write 3DScene shape
75 			sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
76 			SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DR3D, XML_SCENE, bCreateNewline, sal_True);
77 
78 			ImpExportDescription( xShape ); // #i68101#
79 			ImpExportEvents( xShape );
80 
81 			// write 3DSceneLights
82 			export3DLamps( xPropSet );
83 
84 			// #89764# if export of position is supressed for group shape,
85 			// positions of contained objects should be written relative to
86 			// the upper left edge of the group.
87 			awt::Point aUpperLeft;
88 
89 			if(!(nFeatures & SEF_EXPORT_POSITION))
90 			{
91 				nFeatures |= SEF_EXPORT_POSITION;
92 				aUpperLeft = xShape->getPosition();
93 				pRefPoint = &aUpperLeft;
94 			}
95 
96 			// write members
97 			exportShapes( xShapes, nFeatures, pRefPoint );
98 		}
99 	}
100 }
101 
102 //////////////////////////////////////////////////////////////////////////////
103 
104 void XMLShapeExport::ImpExport3DShape(
105 	const uno::Reference< drawing::XShape >& xShape,
106 	XmlShapeType eShapeType, sal_Int32 /* nFeatures = SEF_DEFAULT */, awt::Point* /*pRefPoint = NULL */)
107 {
108 	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
109 	if(xPropSet.is())
110 	{
111 		OUString aStr;
112 		OUStringBuffer sStringBuffer;
113 
114 		// transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
115 		uno::Any aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")));
116 		drawing::HomogenMatrix xHomMat;
117 		aAny >>= xHomMat;
118 		SdXMLImExTransform3D aTransform;
119 		aTransform.AddHomogenMatrix(xHomMat);
120 		if(aTransform.NeedsAction())
121 			mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
122 
123 		switch(eShapeType)
124 		{
125 			case XmlShapeTypeDraw3DCubeObject:
126 			{
127 				// write 3DCube shape
128 				SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_CUBE, sal_True, sal_True);
129 
130 				// minEdge
131 				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPosition")));
132 				drawing::Position3D aPosition3D;
133 				aAny >>= aPosition3D;
134 				::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
135 
136 				// maxEdge
137 				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSize")));
138 				drawing::Direction3D aDirection3D;
139 				aAny >>= aDirection3D;
140 				::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
141 
142 				// transform maxEdge from distance to pos
143 				aDir3D = aPos3D + aDir3D;
144 
145 				// write minEdge
146 				if(aPos3D != ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
147 				{
148 					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aPos3D);
149 					aStr = sStringBuffer.makeStringAndClear();
150 					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MIN_EDGE, aStr);
151 				}
152 
153 				// write maxEdge
154 				if(aDir3D != ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
155 				{
156 					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aDir3D);
157 					aStr = sStringBuffer.makeStringAndClear();
158 					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MAX_EDGE, aStr);
159 				}
160 
161 				break;
162 			}
163 			case XmlShapeTypeDraw3DSphereObject:
164 			{
165 				// write 3DSphere shape
166 				SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_SPHERE, sal_True, sal_True);
167 
168 				// Center
169 				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPosition")));
170 				drawing::Position3D aPosition3D;
171 				aAny >>= aPosition3D;
172 				::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);
173 
174 				// Size
175 				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSize")));
176 				drawing::Direction3D aDirection3D;
177 				aAny >>= aDirection3D;
178 				::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);
179 
180 				// write Center
181 				if(aPos3D != ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
182 				{
183 					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aPos3D);
184 					aStr = sStringBuffer.makeStringAndClear();
185 					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_CENTER, aStr);
186 				}
187 
188 				// write Size
189 				if(aDir3D != ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
190 				{
191 					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aDir3D);
192 					aStr = sStringBuffer.makeStringAndClear();
193 					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SIZE, aStr);
194 				}
195 
196 				break;
197 			}
198 			case XmlShapeTypeDraw3DLatheObject:
199 			case XmlShapeTypeDraw3DExtrudeObject:
200 			{
201 				// write special 3DLathe/3DExtrude attributes
202 				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D")));
203 				drawing::PolyPolygonShape3D xPolyPolygon3D;
204 				aAny >>= xPolyPolygon3D;
205 
206 				// look for maximal values
207 				double fXMin = 0;
208 				double fXMax = 0;
209 				double fYMin = 0;
210 				double fYMax = 0;
211 				sal_Bool bInit(sal_False);
212 				sal_Int32 nOuterSequenceCount(xPolyPolygon3D.SequenceX.getLength());
213 				drawing::DoubleSequence* pInnerSequenceX = xPolyPolygon3D.SequenceX.getArray();
214 				drawing::DoubleSequence* pInnerSequenceY = xPolyPolygon3D.SequenceY.getArray();
215 
216 				sal_Int32 a;
217                 for (a = 0; a < nOuterSequenceCount; a++)
218 				{
219 					sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength());
220 					double* pArrayX = pInnerSequenceX->getArray();
221 					double* pArrayY = pInnerSequenceY->getArray();
222 
223 					for(sal_Int32 b(0L); b < nInnerSequenceCount; b++)
224 					{
225 						double fX = *pArrayX++;
226 						double fY = *pArrayY++;
227 
228 						if(bInit)
229 						{
230 							if(fX > fXMax)
231 								fXMax = fX;
232 
233 							if(fX < fXMin)
234 								fXMin = fX;
235 
236 							if(fY > fYMax)
237 								fYMax = fY;
238 
239 							if(fY < fYMin)
240 								fYMin = fY;
241 						}
242 						else
243 						{
244 							fXMin = fXMax = fX;
245 							fYMin = fYMax = fY;
246 							bInit = sal_True;
247 						}
248 					}
249 
250 					pInnerSequenceX++;
251 					pInnerSequenceY++;
252 				}
253 
254 				// export ViewBox
255 				awt::Point aMinPoint(FRound(fXMin), FRound(fYMin));
256 				awt::Size aMaxSize(FRound(fXMax) - aMinPoint.X, FRound(fYMax) - aMinPoint.Y);
257 				SdXMLImExViewBox aViewBox(
258 					aMinPoint.X, aMinPoint.Y, aMaxSize.Width, aMaxSize.Height);
259 				mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX,
260 					aViewBox.GetExportString());
261 
262 				// prepare svx:d element export
263 				SdXMLImExSvgDElement aSvgDElement(aViewBox);
264 				pInnerSequenceX = xPolyPolygon3D.SequenceX.getArray();
265 				pInnerSequenceY = xPolyPolygon3D.SequenceY.getArray();
266 
267                 for (a = 0; a < nOuterSequenceCount; a++)
268 				{
269 					sal_Int32 nInnerSequenceCount(pInnerSequenceX->getLength());
270 					double* pArrayX = pInnerSequenceX->getArray();
271 					double* pArrayY = pInnerSequenceY->getArray();
272 					drawing::PointSequence aPoly(nInnerSequenceCount);
273 					awt::Point* pInnerSequence = aPoly.getArray();
274 
275 					for(sal_Int32 b(0L); b < nInnerSequenceCount; b++)
276 					{
277 						double fX = *pArrayX++;
278 						double fY = *pArrayY++;
279 
280 						*pInnerSequence = awt::Point(FRound(fX), FRound(fY));
281 						pInnerSequence++;
282 					}
283 
284 					// calculate closed flag
285 					awt::Point* pFirst = aPoly.getArray();
286 					awt::Point* pLast = pFirst + (nInnerSequenceCount - 1);
287 					sal_Bool bClosed = (pFirst->X == pLast->X && pFirst->Y == pLast->Y);
288 
289 					aSvgDElement.AddPolygon(&aPoly, 0L, aMinPoint,
290 						aMaxSize, bClosed);
291 
292 					// #80594# corrected error in PolyPolygon3D export for 3D XML
293 					pInnerSequenceX++;
294 					pInnerSequenceY++;
295 				}
296 
297 				// write point array
298 				mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aSvgDElement.GetExportString());
299 
300 				if(eShapeType == XmlShapeTypeDraw3DLatheObject)
301 				{
302 					// write 3DLathe shape
303 					SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_ROTATE, sal_True, sal_True);
304 				}
305 				else
306 				{
307 					// write 3DExtrude shape
308 					SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_EXTRUDE, sal_True, sal_True);
309 				}
310 				break;
311 			}
312 			default:
313 				break;
314 		}
315 	}
316 }
317 
318 //////////////////////////////////////////////////////////////////////////////
319 
320 /** helper for chart that adds all attributes of a 3d scene element to the export */
321 void XMLShapeExport::export3DSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
322 {
323 	OUString aStr;
324 	OUStringBuffer sStringBuffer;
325 
326 	// world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
327 	uno::Any aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")));
328 	drawing::HomogenMatrix xHomMat;
329 	aAny >>= xHomMat;
330 	SdXMLImExTransform3D aTransform;
331 	aTransform.AddHomogenMatrix(xHomMat);
332 	if(aTransform.NeedsAction())
333 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));
334 
335 	// VRP, VPN, VUP
336 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DCameraGeometry")));
337 	drawing::CameraGeometry aCamGeo;
338 	aAny >>= aCamGeo;
339 
340 	::basegfx::B3DVector aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
341 	if(aVRP != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
342 	{
343 		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aVRP);
344 		aStr = sStringBuffer.makeStringAndClear();
345 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VRP, aStr);
346 	}
347 
348 	::basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
349 	if(aVPN != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
350 	{
351 		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aVPN);
352 		aStr = sStringBuffer.makeStringAndClear();
353 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VPN, aStr);
354 	}
355 
356 	::basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
357 	if(aVUP != ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
358 	{
359 		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aVUP);
360 		aStr = sStringBuffer.makeStringAndClear();
361 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VUP, aStr);
362 	}
363 
364 	// projection "D3DScenePerspective" drawing::ProjectionMode
365 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DScenePerspective")));
366 	drawing::ProjectionMode xPrjMode;
367 	aAny >>= xPrjMode;
368 	if(xPrjMode == drawing::ProjectionMode_PARALLEL)
369 		aStr = GetXMLToken(XML_PARALLEL);
370 	else
371 		aStr = GetXMLToken(XML_PERSPECTIVE);
372 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_PROJECTION, aStr);
373 
374 	// distance
375 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneDistance")));
376 	sal_Int32 nDistance = 0;
377 	aAny >>= nDistance;
378 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDistance);
379 	aStr = sStringBuffer.makeStringAndClear();
380 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DISTANCE, aStr);
381 
382 	// focalLength
383 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneFocalLength")));
384 	sal_Int32 nFocalLength = 0;
385 	aAny >>= nFocalLength;
386 	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nFocalLength);
387 	aStr = sStringBuffer.makeStringAndClear();
388 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_FOCAL_LENGTH, aStr);
389 
390 	// shadowSlant
391 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadowSlant")));
392 	sal_Int16 nShadowSlant = 0;
393 	aAny >>= nShadowSlant;
394 	mrExport.GetMM100UnitConverter().convertNumber(sStringBuffer, (sal_Int32)nShadowSlant);
395 	aStr = sStringBuffer.makeStringAndClear();
396 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, aStr);
397 
398 	// shadeMode
399 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadeMode")));
400 	drawing::ShadeMode xShadeMode;
401 	if(aAny >>= xShadeMode)
402 	{
403 		if(xShadeMode == drawing::ShadeMode_FLAT)
404 			aStr = GetXMLToken(XML_FLAT);
405 		else if(xShadeMode == drawing::ShadeMode_PHONG)
406 			aStr = GetXMLToken(XML_PHONG);
407 		else if(xShadeMode == drawing::ShadeMode_SMOOTH)
408 			aStr = GetXMLToken(XML_GOURAUD);
409 		else
410 			aStr = GetXMLToken(XML_DRAFT);
411 	}
412 	else
413 	{
414 		// ShadeMode enum not there, write default
415 		aStr = GetXMLToken(XML_GOURAUD);
416 	}
417 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr);
418 
419 	// ambientColor
420 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneAmbientColor")));
421 	sal_Int32 aColTemp = 0;
422 	Color aAmbientColor;
423 	aAny >>= aColTemp; aAmbientColor.SetColor(aColTemp);
424 	mrExport.GetMM100UnitConverter().convertColor(sStringBuffer, aAmbientColor);
425 	aStr = sStringBuffer.makeStringAndClear();
426 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_AMBIENT_COLOR, aStr);
427 
428 	// lightingMode
429 	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneTwoSidedLighting")));
430 	sal_Bool bTwoSidedLighting = false;
431 	aAny >>= bTwoSidedLighting;
432 	mrExport.GetMM100UnitConverter().convertBool(sStringBuffer, bTwoSidedLighting);
433 	aStr = sStringBuffer.makeStringAndClear();
434 	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_LIGHTING_MODE, aStr);
435 }
436 
437 /** helper for chart that exports all lamps from the propertyset */
438 void XMLShapeExport::export3DLamps( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
439 {
440 	// write lamps 1..8 as content
441 	OUString aStr;
442 	OUStringBuffer sStringBuffer;
443 
444 	const OUString aColorPropName(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor") );
445 	const OUString aDirectionPropName(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection") );
446 	const OUString aLightOnPropName(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn") );
447 
448 	OUString aPropName;
449 	OUString aIndexStr;
450 	sal_Int32 aColTemp = 0;
451 	Color aLightColor;
452 	::basegfx::B3DVector aLightDirection;
453 	drawing::Direction3D xLightDir;
454 	sal_Bool bLightOnOff = false;
455 	for(sal_Int32 nLamp = 1; nLamp <= 8; nLamp++)
456 	{
457 		aIndexStr = OUString::valueOf( nLamp );
458 
459 		// lightcolor
460 		aPropName = aColorPropName;
461 		aPropName += aIndexStr;
462 		xPropSet->getPropertyValue( aPropName ) >>= aColTemp;
463 		aLightColor.SetColor(aColTemp);
464 		mrExport.GetMM100UnitConverter().convertColor(sStringBuffer, aLightColor);
465 		aStr = sStringBuffer.makeStringAndClear();
466 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, aStr);
467 
468 		// lightdirection
469 		aPropName = aDirectionPropName;
470 		aPropName += aIndexStr;
471 		xPropSet->getPropertyValue(aPropName) >>= xLightDir;
472 		aLightDirection = ::basegfx::B3DVector(xLightDir.DirectionX, xLightDir.DirectionY, xLightDir.DirectionZ);
473 		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aLightDirection);
474 		aStr = sStringBuffer.makeStringAndClear();
475 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIRECTION, aStr);
476 
477 		// lighton
478 		aPropName = aLightOnPropName;
479 		aPropName += aIndexStr;
480 		xPropSet->getPropertyValue(aPropName) >>= bLightOnOff;
481 		mrExport.GetMM100UnitConverter().convertBool(sStringBuffer, bLightOnOff);
482 		aStr = sStringBuffer.makeStringAndClear();
483 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_ENABLED, aStr);
484 
485 		// specular
486 		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SPECULAR,
487 			nLamp == 1 ? XML_TRUE : XML_FALSE);
488 
489 		// write light entry
490 		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_LIGHT, sal_True, sal_True);
491 	}
492 }
493 
494 //////////////////////////////////////////////////////////////////////////////
495