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