1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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(
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),
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
);
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
);
65 case XML_TOK_3DLIGHT_DIRECTION
:
67 SvXMLUnitConverter::convertB3DVector(maDirection
, sValue
);
70 case XML_TOK_3DLIGHT_ENABLED
:
72 ::sax::Converter::convertBool(mbEnabled
, sValue
);
75 case XML_TOK_3DLIGHT_SPECULAR
:
77 ::sax::Converter::convertBool(mbSpecular
, sValue
);
84 SdXML3DLightContext::~SdXML3DLightContext()
88 TYPEINIT1( SdXML3DSceneShapeContext
, SdXMLShapeContext
);
90 SdXML3DSceneShapeContext::SdXML3DSceneShapeContext(
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" );
114 mxChildren
= uno::Reference
< drawing::XShapes
>::query( mxShape
);
115 if( mxChildren
.is() )
116 GetImport().GetShapeImport()->pushGroupForSorting( mxChildren
);
120 // set pos, size, shear and rotate
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
);
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
139 SdXMLShapeContext::StartElement(xAttrList
);
143 void SdXML3DSceneShapeContext::EndElement()
147 uno::Reference
< beans::XPropertySet
> xPropSet(mxShape
, uno::UNO_QUERY
);
150 setSceneAttributes( xPropSet
);
153 if( mxChildren
.is() )
154 GetImport().GetShapeImport()->popGroupAndSort();
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;
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
187 pContext
= GetImport().GetShapeImport()->Create3DSceneChildContext(
188 GetImport(), nPrefix
, rLocalName
, xAttrList
, mxChildren
);
191 // call parent when no own context was created
194 pContext
= SvXMLImportContext::CreateChildContext(
195 nPrefix
, rLocalName
, xAttrList
);
201 SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport
& rImporter
)
202 : mrImport( rImporter
),
203 mbSetTransform( false ),
204 mxPrjMode(drawing::ProjectionMode_PERSPECTIVE
),
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),
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();
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
) );
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
);
252 else if( IsXMLToken( rLocalName
, XML_VRP
) )
254 ::basegfx::B3DVector aNewVec
;
255 SvXMLUnitConverter::convertB3DVector(aNewVec
, rValue
);
264 else if( IsXMLToken( rLocalName
, XML_VPN
) )
266 ::basegfx::B3DVector aNewVec
;
267 SvXMLUnitConverter::convertB3DVector(aNewVec
, rValue
);
276 else if( IsXMLToken( rLocalName
, XML_VUP
) )
278 ::basegfx::B3DVector aNewVec
;
279 SvXMLUnitConverter::convertB3DVector(aNewVec
, rValue
);
288 else if( IsXMLToken( rLocalName
, XML_PROJECTION
) )
290 if( IsXMLToken( rValue
, XML_PARALLEL
) )
291 mxPrjMode
= drawing::ProjectionMode_PARALLEL
;
293 mxPrjMode
= drawing::ProjectionMode_PERSPECTIVE
;
296 else if( IsXMLToken( rLocalName
, XML_DISTANCE
) )
298 mrImport
.GetMM100UnitConverter().convertMeasureToCore(mnDistance
,
302 else if( IsXMLToken( rLocalName
, XML_FOCAL_LENGTH
) )
304 mrImport
.GetMM100UnitConverter().convertMeasureToCore(mnFocalLength
,
308 else if( IsXMLToken( rLocalName
, XML_SHADOW_SLANT
) )
310 ::sax::Converter::convertNumber(mnShadowSlant
, rValue
);
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
;
322 mxShadeMode
= drawing::ShadeMode_DRAFT
;
325 else if( IsXMLToken( rLocalName
, XML_AMBIENT_COLOR
) )
327 ::sax::Converter::convertColor(maAmbientColor
, rValue
);
330 else if( IsXMLToken( rLocalName
, XML_LIGHTING_MODE
) )
332 ::sax::Converter::convertBool(mbLightingMode
, rValue
);
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
)
343 // world transformation
347 xPropSet
->setPropertyValue("D3DTransformMatrix", aAny
);
352 xPropSet
->setPropertyValue("D3DSceneDistance", aAny
);
355 aAny
<<= mnFocalLength
;
356 xPropSet
->setPropertyValue("D3DSceneFocalLength", aAny
);
359 aAny
<<= (sal_Int16
)mnShadowSlant
;
360 xPropSet
->setPropertyValue("D3DSceneShadowSlant", aAny
);
363 aAny
<<= mxShadeMode
;
364 xPropSet
->setPropertyValue("D3DSceneShadeMode", aAny
);
367 aAny
<<= maAmbientColor
;
368 xPropSet
->setPropertyValue("D3DSceneAmbientColor", aAny
);
371 aAny
<<= mbLightingMode
;
372 xPropSet
->setPropertyValue("D3DSceneTwoSidedLighting", aAny
);
374 if( !maList
.empty() )
380 for( size_t a
= 0; a
< maList
.size(); a
++)
382 SdXML3DLightContext
* pCtx
= (SdXML3DLightContext
*)maList
[ a
];
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();
391 aAny3
<<= pCtx
->GetEnabled();
397 xPropSet
->setPropertyValue("D3DSceneLightColor1", aAny
);
398 xPropSet
->setPropertyValue("D3DSceneLightDirection1", aAny2
);
399 xPropSet
->setPropertyValue("D3DSceneLightOn1", aAny3
);
404 xPropSet
->setPropertyValue("D3DSceneLightColor2", aAny
);
405 xPropSet
->setPropertyValue("D3DSceneLightDirection2", aAny2
);
406 xPropSet
->setPropertyValue("D3DSceneLightOn2", aAny3
);
411 xPropSet
->setPropertyValue("D3DSceneLightColor3", aAny
);
412 xPropSet
->setPropertyValue("D3DSceneLightDirection3", aAny2
);
413 xPropSet
->setPropertyValue("D3DSceneLightOn3", aAny3
);
418 xPropSet
->setPropertyValue("D3DSceneLightColor4", aAny
);
419 xPropSet
->setPropertyValue("D3DSceneLightDirection4", aAny2
);
420 xPropSet
->setPropertyValue("D3DSceneLightOn4", aAny3
);
425 xPropSet
->setPropertyValue("D3DSceneLightColor5", aAny
);
426 xPropSet
->setPropertyValue("D3DSceneLightDirection5", aAny2
);
427 xPropSet
->setPropertyValue("D3DSceneLightOn5", aAny3
);
432 xPropSet
->setPropertyValue("D3DSceneLightColor6", aAny
);
433 xPropSet
->setPropertyValue("D3DSceneLightDirection6", aAny2
);
434 xPropSet
->setPropertyValue("D3DSceneLightOn6", aAny3
);
439 xPropSet
->setPropertyValue("D3DSceneLightColor7", aAny
);
440 xPropSet
->setPropertyValue("D3DSceneLightDirection7", aAny2
);
441 xPropSet
->setPropertyValue("D3DSceneLightOn7", aAny3
);
446 xPropSet
->setPropertyValue("D3DSceneLightColor8", aAny
);
447 xPropSet
->setPropertyValue("D3DSceneLightDirection8", aAny2
);
448 xPropSet
->setPropertyValue("D3DSceneLightOn8", aAny3
);
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();
467 xPropSet
->setPropertyValue("D3DCameraGeometry", aAny
);
469 // #91047# set drawing::ProjectionMode AFTER camera geometry is set
470 // projection "D3DScenePerspective" drawing::ProjectionMode
472 xPropSet
->setPropertyValue("D3DScenePerspective", aAny
);
475 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */