bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / draw / ximp3dscene.cxx
blobad3ac71e40fc08bc9a734b457f94f538f6420745
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sax/tools/converter.hxx>
22 #include "ximp3dscene.hxx"
23 #include <xmloff/xmluconv.hxx>
24 #include "xexptran.hxx"
25 #include <xmloff/xmltoken.hxx>
26 #include <xmloff/xmlnmspe.hxx>
27 #include <com/sun/star/drawing/Direction3D.hpp>
28 #include <com/sun/star/drawing/CameraGeometry.hpp>
29 #include "eventimp.hxx"
30 #include "descriptionimp.hxx"
32 using namespace ::com::sun::star;
33 using namespace ::xmloff::token;
35 // dr3d:3dlight context
37 SdXML3DLightContext::SdXML3DLightContext(
38 SvXMLImport& rImport,
39 sal_uInt16 nPrfx,
40 const OUString& rLName,
41 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList)
42 : SvXMLImportContext( rImport, nPrfx, rLName),
43 maDiffuseColor(0x00000000),
44 maDirection(0.0, 0.0, 1.0),
45 mbEnabled(false),
46 mbSpecular(false)
48 // read attributes for the 3DScene
49 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
50 for(sal_Int16 i=0; i < nAttrCount; i++)
52 OUString sAttrName = xAttrList->getNameByIndex( i );
53 OUString aLocalName;
54 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
55 OUString sValue = xAttrList->getValueByIndex( i );
56 const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DLightAttrTokenMap();
58 switch(rAttrTokenMap.Get(nPrefix, aLocalName))
60 case XML_TOK_3DLIGHT_DIFFUSE_COLOR:
62 ::sax::Converter::convertColor(maDiffuseColor, sValue);
63 break;
65 case XML_TOK_3DLIGHT_DIRECTION:
67 SvXMLUnitConverter::convertB3DVector(maDirection, sValue);
68 break;
70 case XML_TOK_3DLIGHT_ENABLED:
72 ::sax::Converter::convertBool(mbEnabled, sValue);
73 break;
75 case XML_TOK_3DLIGHT_SPECULAR:
77 ::sax::Converter::convertBool(mbSpecular, sValue);
78 break;
84 SdXML3DLightContext::~SdXML3DLightContext()
88 TYPEINIT1( SdXML3DSceneShapeContext, SdXMLShapeContext );
90 SdXML3DSceneShapeContext::SdXML3DSceneShapeContext(
91 SvXMLImport& rImport,
92 sal_uInt16 nPrfx,
93 const OUString& rLocalName,
94 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
95 uno::Reference< drawing::XShapes >& rShapes,
96 bool bTemporaryShapes)
97 : SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport )
101 SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext()
105 void SdXML3DSceneShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
107 // create new 3DScene shape and add it to rShapes, use it
108 // as base for the new 3DScene import
109 AddShape( "com.sun.star.drawing.Shape3DSceneObject" );
110 if( mxShape.is() )
112 SetStyle();
114 mxChildren = uno::Reference< drawing::XShapes >::query( mxShape );
115 if( mxChildren.is() )
116 GetImport().GetShapeImport()->pushGroupForSorting( mxChildren );
118 SetLayer();
120 // set pos, size, shear and rotate
121 SetTransformation();
124 // read attributes for the 3DScene
125 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
126 for(sal_Int16 i=0; i < nAttrCount; i++)
128 OUString sAttrName = xAttrList->getNameByIndex( i );
129 OUString aLocalName;
130 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
131 OUString sValue = xAttrList->getValueByIndex( i );
132 processSceneAttribute( nPrefix, aLocalName, sValue );
135 // #91047# call parent function is missing here, added it
136 if(mxShape.is())
138 // call parent
139 SdXMLShapeContext::StartElement(xAttrList);
143 void SdXML3DSceneShapeContext::EndElement()
145 if(mxShape.is())
147 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
148 if(xPropSet.is())
150 setSceneAttributes( xPropSet );
153 if( mxChildren.is() )
154 GetImport().GetShapeImport()->popGroupAndSort();
156 // call parent
157 SdXMLShapeContext::EndElement();
161 SvXMLImportContext* SdXML3DSceneShapeContext::CreateChildContext( sal_uInt16 nPrefix,
162 const OUString& rLocalName,
163 const uno::Reference< xml::sax::XAttributeList>& xAttrList )
165 SvXMLImportContext* pContext = 0L;
167 // #i68101#
168 if( nPrefix == XML_NAMESPACE_SVG &&
169 (IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) )
171 pContext = new SdXMLDescriptionContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape );
173 else if( nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
175 pContext = new SdXMLEventsContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape );
177 // look for local light context first
178 else if(nPrefix == XML_NAMESPACE_DR3D && IsXMLToken( rLocalName, XML_LIGHT ) )
180 // dr3d:light inside dr3d:scene context
181 pContext = create3DLightContext( nPrefix, rLocalName, xAttrList );
184 // call GroupChildContext function at common ShapeImport
185 if(!pContext)
187 pContext = GetImport().GetShapeImport()->Create3DSceneChildContext(
188 GetImport(), nPrefix, rLocalName, xAttrList, mxChildren);
191 // call parent when no own context was created
192 if(!pContext)
194 pContext = SvXMLImportContext::CreateChildContext(
195 nPrefix, rLocalName, xAttrList);
198 return pContext;
201 SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport& rImporter )
202 : mrImport( rImporter ),
203 mbSetTransform( false ),
204 mxPrjMode(drawing::ProjectionMode_PERSPECTIVE),
205 mnDistance(1000),
206 mnFocalLength(1000),
207 mnShadowSlant(0),
208 mxShadeMode(drawing::ShadeMode_SMOOTH),
209 maAmbientColor(0x00666666),
210 mbLightingMode(false),
211 maVRP(0.0, 0.0, 1.0),
212 maVPN(0.0, 0.0, 1.0),
213 maVUP(0.0, 1.0, 0.0),
214 mbVRPUsed(false),
215 mbVPNUsed(false),
216 mbVUPUsed(false)
220 SdXML3DSceneAttributesHelper::~SdXML3DSceneAttributesHelper()
222 // release remembered light contexts, they are no longer needed
223 for ( size_t i = maList.size(); i > 0; )
224 maList[ --i ]->ReleaseRef();
225 maList.clear();
228 /** creates a 3d ligth context and adds it to the internal list for later processing */
229 SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( sal_uInt16 nPrfx, const OUString& rLName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList)
231 SvXMLImportContext* pContext = new SdXML3DLightContext(mrImport, nPrfx, rLName, xAttrList);
233 // remember SdXML3DLightContext for later evaluation
234 pContext->AddFirstRef();
235 maList.push_back( static_cast<SdXML3DLightContext*>(pContext) );
237 return pContext;
240 /** this should be called for each scene attribute */
241 void SdXML3DSceneAttributesHelper::processSceneAttribute( sal_uInt16 nPrefix, const OUString& rLocalName, const OUString& rValue )
243 if( XML_NAMESPACE_DR3D == nPrefix )
245 if( IsXMLToken( rLocalName, XML_TRANSFORM ) )
247 SdXMLImExTransform3D aTransform(rValue, mrImport.GetMM100UnitConverter());
248 if(aTransform.NeedsAction())
249 mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
250 return;
252 else if( IsXMLToken( rLocalName, XML_VRP ) )
254 ::basegfx::B3DVector aNewVec;
255 SvXMLUnitConverter::convertB3DVector(aNewVec, rValue);
257 if(aNewVec != maVRP)
259 maVRP = aNewVec;
260 mbVRPUsed = true;
262 return;
264 else if( IsXMLToken( rLocalName, XML_VPN ) )
266 ::basegfx::B3DVector aNewVec;
267 SvXMLUnitConverter::convertB3DVector(aNewVec, rValue);
269 if(aNewVec != maVPN)
271 maVPN = aNewVec;
272 mbVPNUsed = true;
274 return;
276 else if( IsXMLToken( rLocalName, XML_VUP ) )
278 ::basegfx::B3DVector aNewVec;
279 SvXMLUnitConverter::convertB3DVector(aNewVec, rValue);
281 if(aNewVec != maVUP)
283 maVUP = aNewVec;
284 mbVUPUsed = true;
286 return;
288 else if( IsXMLToken( rLocalName, XML_PROJECTION ) )
290 if( IsXMLToken( rValue, XML_PARALLEL ) )
291 mxPrjMode = drawing::ProjectionMode_PARALLEL;
292 else
293 mxPrjMode = drawing::ProjectionMode_PERSPECTIVE;
294 return;
296 else if( IsXMLToken( rLocalName, XML_DISTANCE ) )
298 mrImport.GetMM100UnitConverter().convertMeasureToCore(mnDistance,
299 rValue);
300 return;
302 else if( IsXMLToken( rLocalName, XML_FOCAL_LENGTH ) )
304 mrImport.GetMM100UnitConverter().convertMeasureToCore(mnFocalLength,
305 rValue);
306 return;
308 else if( IsXMLToken( rLocalName, XML_SHADOW_SLANT ) )
310 ::sax::Converter::convertNumber(mnShadowSlant, rValue);
311 return;
313 else if( IsXMLToken( rLocalName, XML_SHADE_MODE ) )
315 if( IsXMLToken( rValue, XML_FLAT ) )
316 mxShadeMode = drawing::ShadeMode_FLAT;
317 else if( IsXMLToken( rValue, XML_PHONG ) )
318 mxShadeMode = drawing::ShadeMode_PHONG;
319 else if( IsXMLToken( rValue, XML_GOURAUD ) )
320 mxShadeMode = drawing::ShadeMode_SMOOTH;
321 else
322 mxShadeMode = drawing::ShadeMode_DRAFT;
323 return;
325 else if( IsXMLToken( rLocalName, XML_AMBIENT_COLOR ) )
327 ::sax::Converter::convertColor(maAmbientColor, rValue);
328 return;
330 else if( IsXMLToken( rLocalName, XML_LIGHTING_MODE ) )
332 ::sax::Converter::convertBool(mbLightingMode, rValue);
333 return;
338 /** this sets the scene attributes at this propertyset */
339 void SdXML3DSceneAttributesHelper::setSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
341 uno::Any aAny;
343 // world transformation
344 if(mbSetTransform)
346 aAny <<= mxHomMat;
347 xPropSet->setPropertyValue("D3DTransformMatrix", aAny);
350 // distance
351 aAny <<= mnDistance;
352 xPropSet->setPropertyValue("D3DSceneDistance", aAny);
354 // focalLength
355 aAny <<= mnFocalLength;
356 xPropSet->setPropertyValue("D3DSceneFocalLength", aAny);
358 // shadowSlant
359 aAny <<= (sal_Int16)mnShadowSlant;
360 xPropSet->setPropertyValue("D3DSceneShadowSlant", aAny);
362 // shadeMode
363 aAny <<= mxShadeMode;
364 xPropSet->setPropertyValue("D3DSceneShadeMode", aAny);
366 // ambientColor
367 aAny <<= maAmbientColor;
368 xPropSet->setPropertyValue("D3DSceneAmbientColor", aAny);
370 // lightingMode
371 aAny <<= mbLightingMode;
372 xPropSet->setPropertyValue("D3DSceneTwoSidedLighting", aAny);
374 if( !maList.empty() )
376 uno::Any aAny2;
377 uno::Any aAny3;
379 // set lights
380 for( size_t a = 0; a < maList.size(); a++)
382 SdXML3DLightContext* pCtx = (SdXML3DLightContext*)maList[ a ];
384 // set anys
385 aAny <<= pCtx->GetDiffuseColor();
386 drawing::Direction3D xLightDir;
387 xLightDir.DirectionX = pCtx->GetDirection().getX();
388 xLightDir.DirectionY = pCtx->GetDirection().getY();
389 xLightDir.DirectionZ = pCtx->GetDirection().getZ();
390 aAny2 <<= xLightDir;
391 aAny3 <<= pCtx->GetEnabled();
393 switch(a)
395 case 0:
397 xPropSet->setPropertyValue("D3DSceneLightColor1", aAny);
398 xPropSet->setPropertyValue("D3DSceneLightDirection1", aAny2);
399 xPropSet->setPropertyValue("D3DSceneLightOn1", aAny3);
400 break;
402 case 1:
404 xPropSet->setPropertyValue("D3DSceneLightColor2", aAny);
405 xPropSet->setPropertyValue("D3DSceneLightDirection2", aAny2);
406 xPropSet->setPropertyValue("D3DSceneLightOn2", aAny3);
407 break;
409 case 2:
411 xPropSet->setPropertyValue("D3DSceneLightColor3", aAny);
412 xPropSet->setPropertyValue("D3DSceneLightDirection3", aAny2);
413 xPropSet->setPropertyValue("D3DSceneLightOn3", aAny3);
414 break;
416 case 3:
418 xPropSet->setPropertyValue("D3DSceneLightColor4", aAny);
419 xPropSet->setPropertyValue("D3DSceneLightDirection4", aAny2);
420 xPropSet->setPropertyValue("D3DSceneLightOn4", aAny3);
421 break;
423 case 4:
425 xPropSet->setPropertyValue("D3DSceneLightColor5", aAny);
426 xPropSet->setPropertyValue("D3DSceneLightDirection5", aAny2);
427 xPropSet->setPropertyValue("D3DSceneLightOn5", aAny3);
428 break;
430 case 5:
432 xPropSet->setPropertyValue("D3DSceneLightColor6", aAny);
433 xPropSet->setPropertyValue("D3DSceneLightDirection6", aAny2);
434 xPropSet->setPropertyValue("D3DSceneLightOn6", aAny3);
435 break;
437 case 6:
439 xPropSet->setPropertyValue("D3DSceneLightColor7", aAny);
440 xPropSet->setPropertyValue("D3DSceneLightDirection7", aAny2);
441 xPropSet->setPropertyValue("D3DSceneLightOn7", aAny3);
442 break;
444 case 7:
446 xPropSet->setPropertyValue("D3DSceneLightColor8", aAny);
447 xPropSet->setPropertyValue("D3DSceneLightDirection8", aAny2);
448 xPropSet->setPropertyValue("D3DSceneLightOn8", aAny3);
449 break;
455 // CameraGeometry and camera settings
456 drawing::CameraGeometry aCamGeo;
457 aCamGeo.vrp.PositionX = maVRP.getX();
458 aCamGeo.vrp.PositionY = maVRP.getY();
459 aCamGeo.vrp.PositionZ = maVRP.getZ();
460 aCamGeo.vpn.DirectionX = maVPN.getX();
461 aCamGeo.vpn.DirectionY = maVPN.getY();
462 aCamGeo.vpn.DirectionZ = maVPN.getZ();
463 aCamGeo.vup.DirectionX = maVUP.getX();
464 aCamGeo.vup.DirectionY = maVUP.getY();
465 aCamGeo.vup.DirectionZ = maVUP.getZ();
466 aAny <<= aCamGeo;
467 xPropSet->setPropertyValue("D3DCameraGeometry", aAny);
469 // #91047# set drawing::ProjectionMode AFTER camera geometry is set
470 // projection "D3DScenePerspective" drawing::ProjectionMode
471 aAny <<= mxPrjMode;
472 xPropSet->setPropertyValue("D3DScenePerspective", aAny);
475 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */