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 "ximp3dscene.hxx" 27 #include <xmloff/xmluconv.hxx> 28 #include "xexptran.hxx" 29 #include <xmloff/xmltoken.hxx> 30 #include "xmloff/xmlnmspe.hxx" 31 #include <com/sun/star/drawing/Direction3D.hpp> 32 #include <com/sun/star/drawing/CameraGeometry.hpp> 33 #include "eventimp.hxx" 34 #include "descriptionimp.hxx" 35 36 using ::rtl::OUString; 37 using ::rtl::OUStringBuffer; 38 39 using namespace ::com::sun::star; 40 using namespace ::xmloff::token; 41 42 ////////////////////////////////////////////////////////////////////////////// 43 // dr3d:3dlight context 44 45 SdXML3DLightContext::SdXML3DLightContext( 46 SvXMLImport& rImport, 47 sal_uInt16 nPrfx, 48 const rtl::OUString& rLName, 49 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList) 50 : SvXMLImportContext( rImport, nPrfx, rLName), 51 maDiffuseColor(0x00000000), 52 maDirection(0.0, 0.0, 1.0), 53 mbEnabled(sal_False), 54 mbSpecular(sal_False) 55 { 56 // read attributes for the 3DScene 57 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 58 for(sal_Int16 i=0; i < nAttrCount; i++) 59 { 60 OUString sAttrName = xAttrList->getNameByIndex( i ); 61 OUString aLocalName; 62 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); 63 OUString sValue = xAttrList->getValueByIndex( i ); 64 const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DLightAttrTokenMap(); 65 66 switch(rAttrTokenMap.Get(nPrefix, aLocalName)) 67 { 68 case XML_TOK_3DLIGHT_DIFFUSE_COLOR: 69 { 70 GetImport().GetMM100UnitConverter().convertColor(maDiffuseColor, sValue); 71 break; 72 } 73 case XML_TOK_3DLIGHT_DIRECTION: 74 { 75 GetImport().GetMM100UnitConverter().convertB3DVector(maDirection, sValue); 76 break; 77 } 78 case XML_TOK_3DLIGHT_ENABLED: 79 { 80 GetImport().GetMM100UnitConverter().convertBool(mbEnabled, sValue); 81 break; 82 } 83 case XML_TOK_3DLIGHT_SPECULAR: 84 { 85 GetImport().GetMM100UnitConverter().convertBool(mbSpecular, sValue); 86 break; 87 } 88 } 89 } 90 } 91 92 SdXML3DLightContext::~SdXML3DLightContext() 93 { 94 } 95 96 ////////////////////////////////////////////////////////////////////////////// 97 98 TYPEINIT1( SdXML3DSceneShapeContext, SdXMLShapeContext ); 99 100 SdXML3DSceneShapeContext::SdXML3DSceneShapeContext( 101 SvXMLImport& rImport, 102 sal_uInt16 nPrfx, 103 const OUString& rLocalName, 104 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, 105 uno::Reference< drawing::XShapes >& rShapes, 106 sal_Bool bTemporaryShapes) 107 : SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport ) 108 { 109 } 110 111 ////////////////////////////////////////////////////////////////////////////// 112 113 SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext() 114 { 115 } 116 117 ////////////////////////////////////////////////////////////////////////////// 118 119 void SdXML3DSceneShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList) 120 { 121 // create new 3DScene shape and add it to rShapes, use it 122 // as base for the new 3DScene import 123 AddShape( "com.sun.star.drawing.Shape3DSceneObject" ); 124 if( mxShape.is() ) 125 { 126 SetStyle(); 127 128 mxChilds = uno::Reference< drawing::XShapes >::query( mxShape ); 129 if( mxChilds.is() ) 130 GetImport().GetShapeImport()->pushGroupForSorting( mxChilds ); 131 132 SetLayer(); 133 134 // set pos, size, shear and rotate 135 SetTransformation(); 136 } 137 138 // read attributes for the 3DScene 139 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 140 for(sal_Int16 i=0; i < nAttrCount; i++) 141 { 142 OUString sAttrName = xAttrList->getNameByIndex( i ); 143 OUString aLocalName; 144 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); 145 OUString sValue = xAttrList->getValueByIndex( i ); 146 processSceneAttribute( nPrefix, aLocalName, sValue ); 147 } 148 149 // #91047# call parent function is missing here, added it 150 if(mxShape.is()) 151 { 152 // call parent 153 SdXMLShapeContext::StartElement(xAttrList); 154 } 155 } 156 157 ////////////////////////////////////////////////////////////////////////////// 158 159 void SdXML3DSceneShapeContext::EndElement() 160 { 161 if(mxShape.is()) 162 { 163 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY); 164 if(xPropSet.is()) 165 { 166 setSceneAttributes( xPropSet ); 167 } 168 169 if( mxChilds.is() ) 170 GetImport().GetShapeImport()->popGroupAndSort(); 171 172 // call parent 173 SdXMLShapeContext::EndElement(); 174 } 175 } 176 177 ////////////////////////////////////////////////////////////////////////////// 178 179 SvXMLImportContext* SdXML3DSceneShapeContext::CreateChildContext( sal_uInt16 nPrefix, 180 const OUString& rLocalName, 181 const uno::Reference< xml::sax::XAttributeList>& xAttrList ) 182 { 183 SvXMLImportContext* pContext = 0L; 184 185 // #i68101# 186 if( nPrefix == XML_NAMESPACE_SVG && 187 (IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) ) 188 { 189 pContext = new SdXMLDescriptionContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape ); 190 } 191 else if( nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) ) 192 { 193 pContext = new SdXMLEventsContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape ); 194 } 195 // look for local light context first 196 else if(nPrefix == XML_NAMESPACE_DR3D && IsXMLToken( rLocalName, XML_LIGHT ) ) 197 { 198 // dr3d:light inside dr3d:scene context 199 pContext = create3DLightContext( nPrefix, rLocalName, xAttrList ); 200 } 201 202 // call GroupChildContext function at common ShapeImport 203 if(!pContext) 204 { 205 pContext = GetImport().GetShapeImport()->Create3DSceneChildContext( 206 GetImport(), nPrefix, rLocalName, xAttrList, mxChilds); 207 } 208 209 // call parent when no own context was created 210 if(!pContext) 211 { 212 pContext = SvXMLImportContext::CreateChildContext( 213 nPrefix, rLocalName, xAttrList); 214 } 215 216 return pContext; 217 } 218 219 ////////////////////////////////////////////////////////////////////////////// 220 221 SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport& rImporter ) 222 : mrImport( rImporter ), 223 mbSetTransform( sal_False ), 224 mxPrjMode(drawing::ProjectionMode_PERSPECTIVE), 225 mnDistance(1000), 226 mnFocalLength(1000), 227 mnShadowSlant(0), 228 mxShadeMode(drawing::ShadeMode_SMOOTH), 229 maAmbientColor(0x00666666), 230 mbLightingMode(sal_False), 231 maVRP(0.0, 0.0, 1.0), 232 maVPN(0.0, 0.0, 1.0), 233 maVUP(0.0, 1.0, 0.0), 234 mbVRPUsed(sal_False), 235 mbVPNUsed(sal_False), 236 mbVUPUsed(sal_False) 237 { 238 } 239 240 SdXML3DSceneAttributesHelper::~SdXML3DSceneAttributesHelper() 241 { 242 // release remembered light contexts, they are no longer needed 243 while(maList.Count()) 244 maList.Remove(maList.Count() - 1)->ReleaseRef(); 245 } 246 247 /** creates a 3d ligth context and adds it to the internal list for later processing */ 248 SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( sal_uInt16 nPrfx, const rtl::OUString& rLName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList) 249 { 250 SvXMLImportContext* pContext = new SdXML3DLightContext(mrImport, nPrfx, rLName, xAttrList); 251 252 // remember SdXML3DLightContext for later evaluation 253 if(pContext) 254 { 255 pContext->AddRef(); 256 maList.Insert((SdXML3DLightContext*)pContext, LIST_APPEND); 257 } 258 259 return pContext; 260 } 261 262 /** this should be called for each scene attribute */ 263 void SdXML3DSceneAttributesHelper::processSceneAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue ) 264 { 265 if( XML_NAMESPACE_DR3D == nPrefix ) 266 { 267 if( IsXMLToken( rLocalName, XML_TRANSFORM ) ) 268 { 269 SdXMLImExTransform3D aTransform(rValue, mrImport.GetMM100UnitConverter()); 270 if(aTransform.NeedsAction()) 271 mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat); 272 return; 273 } 274 else if( IsXMLToken( rLocalName, XML_VRP ) ) 275 { 276 ::basegfx::B3DVector aNewVec; 277 mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue); 278 279 if(aNewVec != maVRP) 280 { 281 maVRP = aNewVec; 282 mbVRPUsed = sal_True; 283 } 284 return; 285 } 286 else if( IsXMLToken( rLocalName, XML_VPN ) ) 287 { 288 ::basegfx::B3DVector aNewVec; 289 mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue); 290 291 if(aNewVec != maVPN) 292 { 293 maVPN = aNewVec; 294 mbVPNUsed = sal_True; 295 } 296 return; 297 } 298 else if( IsXMLToken( rLocalName, XML_VUP ) ) 299 { 300 ::basegfx::B3DVector aNewVec; 301 mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue); 302 303 if(aNewVec != maVUP) 304 { 305 maVUP = aNewVec; 306 mbVUPUsed = sal_True; 307 } 308 return; 309 } 310 else if( IsXMLToken( rLocalName, XML_PROJECTION ) ) 311 { 312 if( IsXMLToken( rValue, XML_PARALLEL ) ) 313 mxPrjMode = drawing::ProjectionMode_PARALLEL; 314 else 315 mxPrjMode = drawing::ProjectionMode_PERSPECTIVE; 316 return; 317 } 318 else if( IsXMLToken( rLocalName, XML_DISTANCE ) ) 319 { 320 mrImport.GetMM100UnitConverter().convertMeasure(mnDistance, rValue); 321 return; 322 } 323 else if( IsXMLToken( rLocalName, XML_FOCAL_LENGTH ) ) 324 { 325 mrImport.GetMM100UnitConverter().convertMeasure(mnFocalLength, rValue); 326 return; 327 } 328 else if( IsXMLToken( rLocalName, XML_SHADOW_SLANT ) ) 329 { 330 mrImport.GetMM100UnitConverter().convertNumber(mnShadowSlant, rValue); 331 return; 332 } 333 else if( IsXMLToken( rLocalName, XML_SHADE_MODE ) ) 334 { 335 if( IsXMLToken( rValue, XML_FLAT ) ) 336 mxShadeMode = drawing::ShadeMode_FLAT; 337 else if( IsXMLToken( rValue, XML_PHONG ) ) 338 mxShadeMode = drawing::ShadeMode_PHONG; 339 else if( IsXMLToken( rValue, XML_GOURAUD ) ) 340 mxShadeMode = drawing::ShadeMode_SMOOTH; 341 else 342 mxShadeMode = drawing::ShadeMode_DRAFT; 343 return; 344 } 345 else if( IsXMLToken( rLocalName, XML_AMBIENT_COLOR ) ) 346 { 347 mrImport.GetMM100UnitConverter().convertColor(maAmbientColor, rValue); 348 return; 349 } 350 else if( IsXMLToken( rLocalName, XML_LIGHTING_MODE ) ) 351 { 352 mrImport.GetMM100UnitConverter().convertBool(mbLightingMode, rValue); 353 return; 354 } 355 } 356 } 357 358 /** this sets the scene attributes at this propertyset */ 359 void SdXML3DSceneAttributesHelper::setSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet ) 360 { 361 uno::Any aAny; 362 363 // world transformation 364 if(mbSetTransform) 365 { 366 aAny <<= mxHomMat; 367 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")), aAny); 368 } 369 370 // distance 371 aAny <<= mnDistance; 372 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneDistance")), aAny); 373 374 // focalLength 375 aAny <<= mnFocalLength; 376 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneFocalLength")), aAny); 377 378 // shadowSlant 379 aAny <<= (sal_Int16)mnShadowSlant; 380 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadowSlant")), aAny); 381 382 // shadeMode 383 aAny <<= mxShadeMode; 384 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadeMode")), aAny); 385 386 // ambientColor 387 aAny <<= maAmbientColor.GetColor(); 388 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneAmbientColor")), aAny); 389 390 // lightingMode 391 aAny <<= mbLightingMode; 392 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneTwoSidedLighting")), aAny); 393 394 if(maList.Count()) 395 { 396 uno::Any aAny2; 397 uno::Any aAny3; 398 399 // set lights 400 for(sal_uInt32 a(0L); a < maList.Count(); a++) 401 { 402 SdXML3DLightContext* pCtx = (SdXML3DLightContext*)maList.GetObject(a); 403 404 // set anys 405 aAny <<= pCtx->GetDiffuseColor().GetColor(); 406 drawing::Direction3D xLightDir; 407 xLightDir.DirectionX = pCtx->GetDirection().getX(); 408 xLightDir.DirectionY = pCtx->GetDirection().getY(); 409 xLightDir.DirectionZ = pCtx->GetDirection().getZ(); 410 aAny2 <<= xLightDir; 411 aAny3 <<= pCtx->GetEnabled(); 412 413 switch(a) 414 { 415 case 0: 416 { 417 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor1")), aAny); 418 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection1")), aAny2); 419 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn1")), aAny3); 420 break; 421 } 422 case 1: 423 { 424 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor2")), aAny); 425 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection2")), aAny2); 426 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn2")), aAny3); 427 break; 428 } 429 case 2: 430 { 431 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor3")), aAny); 432 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection3")), aAny2); 433 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn3")), aAny3); 434 break; 435 } 436 case 3: 437 { 438 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor4")), aAny); 439 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection4")), aAny2); 440 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn4")), aAny3); 441 break; 442 } 443 case 4: 444 { 445 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor5")), aAny); 446 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection5")), aAny2); 447 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn5")), aAny3); 448 break; 449 } 450 case 5: 451 { 452 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor6")), aAny); 453 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection6")), aAny2); 454 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn6")), aAny3); 455 break; 456 } 457 case 6: 458 { 459 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor7")), aAny); 460 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection7")), aAny2); 461 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn7")), aAny3); 462 break; 463 } 464 case 7: 465 { 466 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor8")), aAny); 467 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection8")), aAny2); 468 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn8")), aAny3); 469 break; 470 } 471 } 472 } 473 } 474 475 // CameraGeometry and camera settings 476 drawing::CameraGeometry aCamGeo; 477 aCamGeo.vrp.PositionX = maVRP.getX(); 478 aCamGeo.vrp.PositionY = maVRP.getY(); 479 aCamGeo.vrp.PositionZ = maVRP.getZ(); 480 aCamGeo.vpn.DirectionX = maVPN.getX(); 481 aCamGeo.vpn.DirectionY = maVPN.getY(); 482 aCamGeo.vpn.DirectionZ = maVPN.getZ(); 483 aCamGeo.vup.DirectionX = maVUP.getX(); 484 aCamGeo.vup.DirectionY = maVUP.getY(); 485 aCamGeo.vup.DirectionZ = maVUP.getZ(); 486 aAny <<= aCamGeo; 487 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DCameraGeometry")), aAny); 488 489 // #91047# set drawing::ProjectionMode AFTER camera geometry is set 490 // projection "D3DScenePerspective" drawing::ProjectionMode 491 aAny <<= mxPrjMode; 492 xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DScenePerspective")), aAny); 493 } 494