| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmloff.hxx" |
| #include "ximp3dscene.hxx" |
| #include <xmloff/xmluconv.hxx> |
| #include "xexptran.hxx" |
| #include <xmloff/xmltoken.hxx> |
| #include "xmloff/xmlnmspe.hxx" |
| #include <com/sun/star/drawing/Direction3D.hpp> |
| #include <com/sun/star/drawing/CameraGeometry.hpp> |
| #include "eventimp.hxx" |
| #include "descriptionimp.hxx" |
| |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| |
| using namespace ::com::sun::star; |
| using namespace ::xmloff::token; |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // dr3d:3dlight context |
| |
| SdXML3DLightContext::SdXML3DLightContext( |
| SvXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const rtl::OUString& rLName, |
| const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList) |
| : SvXMLImportContext( rImport, nPrfx, rLName), |
| maDiffuseColor(0x00000000), |
| maDirection(0.0, 0.0, 1.0), |
| mbEnabled(sal_False), |
| mbSpecular(sal_False) |
| { |
| // read attributes for the 3DScene |
| sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; |
| for(sal_Int16 i=0; i < nAttrCount; i++) |
| { |
| OUString sAttrName = xAttrList->getNameByIndex( i ); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); |
| OUString sValue = xAttrList->getValueByIndex( i ); |
| const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DLightAttrTokenMap(); |
| |
| switch(rAttrTokenMap.Get(nPrefix, aLocalName)) |
| { |
| case XML_TOK_3DLIGHT_DIFFUSE_COLOR: |
| { |
| GetImport().GetMM100UnitConverter().convertColor(maDiffuseColor, sValue); |
| break; |
| } |
| case XML_TOK_3DLIGHT_DIRECTION: |
| { |
| GetImport().GetMM100UnitConverter().convertB3DVector(maDirection, sValue); |
| break; |
| } |
| case XML_TOK_3DLIGHT_ENABLED: |
| { |
| GetImport().GetMM100UnitConverter().convertBool(mbEnabled, sValue); |
| break; |
| } |
| case XML_TOK_3DLIGHT_SPECULAR: |
| { |
| GetImport().GetMM100UnitConverter().convertBool(mbSpecular, sValue); |
| break; |
| } |
| } |
| } |
| } |
| |
| SdXML3DLightContext::~SdXML3DLightContext() |
| { |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| TYPEINIT1( SdXML3DSceneShapeContext, SdXMLShapeContext ); |
| |
| SdXML3DSceneShapeContext::SdXML3DSceneShapeContext( |
| SvXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const OUString& rLocalName, |
| const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, |
| uno::Reference< drawing::XShapes >& rShapes, |
| sal_Bool bTemporaryShapes) |
| : SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport ) |
| { |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext() |
| { |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| void SdXML3DSceneShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList) |
| { |
| // create new 3DScene shape and add it to rShapes, use it |
| // as base for the new 3DScene import |
| AddShape( "com.sun.star.drawing.Shape3DSceneObject" ); |
| if( mxShape.is() ) |
| { |
| SetStyle(); |
| |
| mxChilds = uno::Reference< drawing::XShapes >::query( mxShape ); |
| if( mxChilds.is() ) |
| GetImport().GetShapeImport()->pushGroupForSorting( mxChilds ); |
| |
| SetLayer(); |
| |
| // set pos, size, shear and rotate |
| SetTransformation(); |
| } |
| |
| // read attributes for the 3DScene |
| sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; |
| for(sal_Int16 i=0; i < nAttrCount; i++) |
| { |
| OUString sAttrName = xAttrList->getNameByIndex( i ); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); |
| OUString sValue = xAttrList->getValueByIndex( i ); |
| processSceneAttribute( nPrefix, aLocalName, sValue ); |
| } |
| |
| // #91047# call parent function is missing here, added it |
| if(mxShape.is()) |
| { |
| // call parent |
| SdXMLShapeContext::StartElement(xAttrList); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| void SdXML3DSceneShapeContext::EndElement() |
| { |
| if(mxShape.is()) |
| { |
| uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY); |
| if(xPropSet.is()) |
| { |
| setSceneAttributes( xPropSet ); |
| } |
| |
| if( mxChilds.is() ) |
| GetImport().GetShapeImport()->popGroupAndSort(); |
| |
| // call parent |
| SdXMLShapeContext::EndElement(); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| SvXMLImportContext* SdXML3DSceneShapeContext::CreateChildContext( sal_uInt16 nPrefix, |
| const OUString& rLocalName, |
| const uno::Reference< xml::sax::XAttributeList>& xAttrList ) |
| { |
| SvXMLImportContext* pContext = 0L; |
| |
| // #i68101# |
| if( nPrefix == XML_NAMESPACE_SVG && |
| (IsXMLToken( rLocalName, XML_TITLE ) || IsXMLToken( rLocalName, XML_DESC ) ) ) |
| { |
| pContext = new SdXMLDescriptionContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape ); |
| } |
| else if( nPrefix == XML_NAMESPACE_OFFICE && IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) ) |
| { |
| pContext = new SdXMLEventsContext( GetImport(), nPrefix, rLocalName, xAttrList, mxShape ); |
| } |
| // look for local light context first |
| else if(nPrefix == XML_NAMESPACE_DR3D && IsXMLToken( rLocalName, XML_LIGHT ) ) |
| { |
| // dr3d:light inside dr3d:scene context |
| pContext = create3DLightContext( nPrefix, rLocalName, xAttrList ); |
| } |
| |
| // call GroupChildContext function at common ShapeImport |
| if(!pContext) |
| { |
| pContext = GetImport().GetShapeImport()->Create3DSceneChildContext( |
| GetImport(), nPrefix, rLocalName, xAttrList, mxChilds); |
| } |
| |
| // call parent when no own context was created |
| if(!pContext) |
| { |
| pContext = SvXMLImportContext::CreateChildContext( |
| nPrefix, rLocalName, xAttrList); |
| } |
| |
| return pContext; |
| } |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport& rImporter ) |
| : mrImport( rImporter ), |
| mbSetTransform( sal_False ), |
| mxPrjMode(drawing::ProjectionMode_PERSPECTIVE), |
| mnDistance(1000), |
| mnFocalLength(1000), |
| mnShadowSlant(0), |
| mxShadeMode(drawing::ShadeMode_SMOOTH), |
| maAmbientColor(0x00666666), |
| mbLightingMode(sal_False), |
| maVRP(0.0, 0.0, 1.0), |
| maVPN(0.0, 0.0, 1.0), |
| maVUP(0.0, 1.0, 0.0), |
| mbVRPUsed(sal_False), |
| mbVPNUsed(sal_False), |
| mbVUPUsed(sal_False) |
| { |
| } |
| |
| SdXML3DSceneAttributesHelper::~SdXML3DSceneAttributesHelper() |
| { |
| // release remembered light contexts, they are no longer needed |
| while(maList.Count()) |
| maList.Remove(maList.Count() - 1)->ReleaseRef(); |
| } |
| |
| /** creates a 3d ligth context and adds it to the internal list for later processing */ |
| SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( sal_uInt16 nPrfx, const rtl::OUString& rLName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList) |
| { |
| SvXMLImportContext* pContext = new SdXML3DLightContext(mrImport, nPrfx, rLName, xAttrList); |
| |
| // remember SdXML3DLightContext for later evaluation |
| if(pContext) |
| { |
| pContext->AddRef(); |
| maList.Insert((SdXML3DLightContext*)pContext, LIST_APPEND); |
| } |
| |
| return pContext; |
| } |
| |
| /** this should be called for each scene attribute */ |
| void SdXML3DSceneAttributesHelper::processSceneAttribute( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue ) |
| { |
| if( XML_NAMESPACE_DR3D == nPrefix ) |
| { |
| if( IsXMLToken( rLocalName, XML_TRANSFORM ) ) |
| { |
| SdXMLImExTransform3D aTransform(rValue, mrImport.GetMM100UnitConverter()); |
| if(aTransform.NeedsAction()) |
| mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat); |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_VRP ) ) |
| { |
| ::basegfx::B3DVector aNewVec; |
| mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue); |
| |
| if(aNewVec != maVRP) |
| { |
| maVRP = aNewVec; |
| mbVRPUsed = sal_True; |
| } |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_VPN ) ) |
| { |
| ::basegfx::B3DVector aNewVec; |
| mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue); |
| |
| if(aNewVec != maVPN) |
| { |
| maVPN = aNewVec; |
| mbVPNUsed = sal_True; |
| } |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_VUP ) ) |
| { |
| ::basegfx::B3DVector aNewVec; |
| mrImport.GetMM100UnitConverter().convertB3DVector(aNewVec, rValue); |
| |
| if(aNewVec != maVUP) |
| { |
| maVUP = aNewVec; |
| mbVUPUsed = sal_True; |
| } |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_PROJECTION ) ) |
| { |
| if( IsXMLToken( rValue, XML_PARALLEL ) ) |
| mxPrjMode = drawing::ProjectionMode_PARALLEL; |
| else |
| mxPrjMode = drawing::ProjectionMode_PERSPECTIVE; |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_DISTANCE ) ) |
| { |
| mrImport.GetMM100UnitConverter().convertMeasure(mnDistance, rValue); |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_FOCAL_LENGTH ) ) |
| { |
| mrImport.GetMM100UnitConverter().convertMeasure(mnFocalLength, rValue); |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_SHADOW_SLANT ) ) |
| { |
| mrImport.GetMM100UnitConverter().convertNumber(mnShadowSlant, rValue); |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_SHADE_MODE ) ) |
| { |
| if( IsXMLToken( rValue, XML_FLAT ) ) |
| mxShadeMode = drawing::ShadeMode_FLAT; |
| else if( IsXMLToken( rValue, XML_PHONG ) ) |
| mxShadeMode = drawing::ShadeMode_PHONG; |
| else if( IsXMLToken( rValue, XML_GOURAUD ) ) |
| mxShadeMode = drawing::ShadeMode_SMOOTH; |
| else |
| mxShadeMode = drawing::ShadeMode_DRAFT; |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_AMBIENT_COLOR ) ) |
| { |
| mrImport.GetMM100UnitConverter().convertColor(maAmbientColor, rValue); |
| return; |
| } |
| else if( IsXMLToken( rLocalName, XML_LIGHTING_MODE ) ) |
| { |
| mrImport.GetMM100UnitConverter().convertBool(mbLightingMode, rValue); |
| return; |
| } |
| } |
| } |
| |
| /** this sets the scene attributes at this propertyset */ |
| void SdXML3DSceneAttributesHelper::setSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet ) |
| { |
| uno::Any aAny; |
| |
| // world transformation |
| if(mbSetTransform) |
| { |
| aAny <<= mxHomMat; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")), aAny); |
| } |
| |
| // distance |
| aAny <<= mnDistance; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneDistance")), aAny); |
| |
| // focalLength |
| aAny <<= mnFocalLength; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneFocalLength")), aAny); |
| |
| // shadowSlant |
| aAny <<= (sal_Int16)mnShadowSlant; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadowSlant")), aAny); |
| |
| // shadeMode |
| aAny <<= mxShadeMode; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadeMode")), aAny); |
| |
| // ambientColor |
| aAny <<= maAmbientColor.GetColor(); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneAmbientColor")), aAny); |
| |
| // lightingMode |
| aAny <<= mbLightingMode; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneTwoSidedLighting")), aAny); |
| |
| if(maList.Count()) |
| { |
| uno::Any aAny2; |
| uno::Any aAny3; |
| |
| // set lights |
| for(sal_uInt32 a(0L); a < maList.Count(); a++) |
| { |
| SdXML3DLightContext* pCtx = (SdXML3DLightContext*)maList.GetObject(a); |
| |
| // set anys |
| aAny <<= pCtx->GetDiffuseColor().GetColor(); |
| drawing::Direction3D xLightDir; |
| xLightDir.DirectionX = pCtx->GetDirection().getX(); |
| xLightDir.DirectionY = pCtx->GetDirection().getY(); |
| xLightDir.DirectionZ = pCtx->GetDirection().getZ(); |
| aAny2 <<= xLightDir; |
| aAny3 <<= pCtx->GetEnabled(); |
| |
| switch(a) |
| { |
| case 0: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor1")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection1")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn1")), aAny3); |
| break; |
| } |
| case 1: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor2")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection2")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn2")), aAny3); |
| break; |
| } |
| case 2: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor3")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection3")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn3")), aAny3); |
| break; |
| } |
| case 3: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor4")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection4")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn4")), aAny3); |
| break; |
| } |
| case 4: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor5")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection5")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn5")), aAny3); |
| break; |
| } |
| case 5: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor6")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection6")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn6")), aAny3); |
| break; |
| } |
| case 6: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor7")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection7")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn7")), aAny3); |
| break; |
| } |
| case 7: |
| { |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor8")), aAny); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection8")), aAny2); |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn8")), aAny3); |
| break; |
| } |
| } |
| } |
| } |
| |
| // CameraGeometry and camera settings |
| drawing::CameraGeometry aCamGeo; |
| aCamGeo.vrp.PositionX = maVRP.getX(); |
| aCamGeo.vrp.PositionY = maVRP.getY(); |
| aCamGeo.vrp.PositionZ = maVRP.getZ(); |
| aCamGeo.vpn.DirectionX = maVPN.getX(); |
| aCamGeo.vpn.DirectionY = maVPN.getY(); |
| aCamGeo.vpn.DirectionZ = maVPN.getZ(); |
| aCamGeo.vup.DirectionX = maVUP.getX(); |
| aCamGeo.vup.DirectionY = maVUP.getY(); |
| aCamGeo.vup.DirectionZ = maVUP.getZ(); |
| aAny <<= aCamGeo; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DCameraGeometry")), aAny); |
| |
| // #91047# set drawing::ProjectionMode AFTER camera geometry is set |
| // projection "D3DScenePerspective" drawing::ProjectionMode |
| aAny <<= mxPrjMode; |
| xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DScenePerspective")), aAny); |
| } |