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