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 512 : 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 512 : mbSpecular(false)
47 : {
48 : // read attributes for the 3DScene
49 512 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
50 2560 : for(sal_Int16 i=0; i < nAttrCount; i++)
51 : {
52 2048 : OUString sAttrName = xAttrList->getNameByIndex( i );
53 4096 : OUString aLocalName;
54 2048 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
55 4096 : OUString sValue = xAttrList->getValueByIndex( i );
56 2048 : const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DLightAttrTokenMap();
57 :
58 2048 : switch(rAttrTokenMap.Get(nPrefix, aLocalName))
59 : {
60 : case XML_TOK_3DLIGHT_DIFFUSE_COLOR:
61 : {
62 512 : ::sax::Converter::convertColor(maDiffuseColor, sValue);
63 512 : break;
64 : }
65 : case XML_TOK_3DLIGHT_DIRECTION:
66 : {
67 512 : SvXMLUnitConverter::convertB3DVector(maDirection, sValue);
68 512 : break;
69 : }
70 : case XML_TOK_3DLIGHT_ENABLED:
71 : {
72 512 : ::sax::Converter::convertBool(mbEnabled, sValue);
73 512 : break;
74 : }
75 : case XML_TOK_3DLIGHT_SPECULAR:
76 : {
77 512 : ::sax::Converter::convertBool(mbSpecular, sValue);
78 512 : break;
79 : }
80 : }
81 2048 : }
82 512 : }
83 :
84 1024 : SdXML3DLightContext::~SdXML3DLightContext()
85 : {
86 1024 : }
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 244 : 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 244 : mbVUPUsed(false)
217 : {
218 244 : }
219 :
220 488 : SdXML3DSceneAttributesHelper::~SdXML3DSceneAttributesHelper()
221 : {
222 : // release remembered light contexts, they are no longer needed
223 1000 : for ( size_t i = maList.size(); i > 0; )
224 512 : maList[ --i ]->ReleaseRef();
225 244 : maList.clear();
226 244 : }
227 :
228 : /** creates a 3d ligth context and adds it to the internal list for later processing */
229 512 : SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( sal_uInt16 nPrfx, const OUString& rLName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList)
230 : {
231 512 : SvXMLImportContext* pContext = new SdXML3DLightContext(mrImport, nPrfx, rLName, xAttrList);
232 :
233 : // remember SdXML3DLightContext for later evaluation
234 512 : if(pContext)
235 : {
236 512 : pContext->AddFirstRef();
237 512 : maList.push_back( static_cast<SdXML3DLightContext*>(pContext) );
238 : }
239 :
240 512 : return pContext;
241 : }
242 :
243 : /** this should be called for each scene attribute */
244 704 : void SdXML3DSceneAttributesHelper::processSceneAttribute( sal_uInt16 nPrefix, const OUString& rLocalName, const OUString& rValue )
245 : {
246 704 : if( XML_NAMESPACE_DR3D == nPrefix )
247 : {
248 704 : if( IsXMLToken( rLocalName, XML_TRANSFORM ) )
249 : {
250 64 : SdXMLImExTransform3D aTransform(rValue, mrImport.GetMM100UnitConverter());
251 64 : if(aTransform.NeedsAction())
252 64 : mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
253 64 : return;
254 : }
255 640 : else if( IsXMLToken( rLocalName, XML_VRP ) )
256 : {
257 64 : ::basegfx::B3DVector aNewVec;
258 64 : SvXMLUnitConverter::convertB3DVector(aNewVec, rValue);
259 :
260 64 : if(aNewVec != maVRP)
261 : {
262 64 : maVRP = aNewVec;
263 64 : mbVRPUsed = true;
264 : }
265 64 : return;
266 : }
267 576 : else if( IsXMLToken( rLocalName, XML_VPN ) )
268 : {
269 64 : ::basegfx::B3DVector aNewVec;
270 64 : SvXMLUnitConverter::convertB3DVector(aNewVec, rValue);
271 :
272 64 : if(aNewVec != maVPN)
273 : {
274 64 : maVPN = aNewVec;
275 64 : mbVPNUsed = true;
276 : }
277 64 : return;
278 : }
279 512 : else if( IsXMLToken( rLocalName, XML_VUP ) )
280 : {
281 64 : ::basegfx::B3DVector aNewVec;
282 64 : SvXMLUnitConverter::convertB3DVector(aNewVec, rValue);
283 :
284 64 : if(aNewVec != maVUP)
285 : {
286 64 : maVUP = aNewVec;
287 64 : mbVUPUsed = true;
288 : }
289 64 : return;
290 : }
291 448 : else if( IsXMLToken( rLocalName, XML_PROJECTION ) )
292 : {
293 64 : if( IsXMLToken( rValue, XML_PARALLEL ) )
294 60 : mxPrjMode = drawing::ProjectionMode_PARALLEL;
295 : else
296 4 : mxPrjMode = drawing::ProjectionMode_PERSPECTIVE;
297 64 : return;
298 : }
299 384 : else if( IsXMLToken( rLocalName, XML_DISTANCE ) )
300 : {
301 64 : mrImport.GetMM100UnitConverter().convertMeasureToCore(mnDistance,
302 128 : rValue);
303 64 : return;
304 : }
305 320 : else if( IsXMLToken( rLocalName, XML_FOCAL_LENGTH ) )
306 : {
307 64 : mrImport.GetMM100UnitConverter().convertMeasureToCore(mnFocalLength,
308 128 : rValue);
309 64 : return;
310 : }
311 256 : else if( IsXMLToken( rLocalName, XML_SHADOW_SLANT ) )
312 : {
313 64 : ::sax::Converter::convertNumber(mnShadowSlant, rValue);
314 64 : return;
315 : }
316 192 : else if( IsXMLToken( rLocalName, XML_SHADE_MODE ) )
317 : {
318 64 : if( IsXMLToken( rValue, XML_FLAT ) )
319 64 : mxShadeMode = drawing::ShadeMode_FLAT;
320 0 : else if( IsXMLToken( rValue, XML_PHONG ) )
321 0 : mxShadeMode = drawing::ShadeMode_PHONG;
322 0 : else if( IsXMLToken( rValue, XML_GOURAUD ) )
323 0 : mxShadeMode = drawing::ShadeMode_SMOOTH;
324 : else
325 0 : mxShadeMode = drawing::ShadeMode_DRAFT;
326 64 : return;
327 : }
328 128 : else if( IsXMLToken( rLocalName, XML_AMBIENT_COLOR ) )
329 : {
330 64 : ::sax::Converter::convertColor(maAmbientColor, rValue);
331 64 : return;
332 : }
333 64 : else if( IsXMLToken( rLocalName, XML_LIGHTING_MODE ) )
334 : {
335 64 : ::sax::Converter::convertBool(mbLightingMode, rValue);
336 64 : return;
337 : }
338 : }
339 : }
340 :
341 : /** this sets the scene attributes at this propertyset */
342 64 : void SdXML3DSceneAttributesHelper::setSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
343 : {
344 64 : uno::Any aAny;
345 :
346 : // world transformation
347 64 : if(mbSetTransform)
348 : {
349 64 : aAny <<= mxHomMat;
350 64 : xPropSet->setPropertyValue("D3DTransformMatrix", aAny);
351 : }
352 :
353 : // distance
354 64 : aAny <<= mnDistance;
355 64 : xPropSet->setPropertyValue("D3DSceneDistance", aAny);
356 :
357 : // focalLength
358 64 : aAny <<= mnFocalLength;
359 64 : xPropSet->setPropertyValue("D3DSceneFocalLength", aAny);
360 :
361 : // shadowSlant
362 64 : aAny <<= (sal_Int16)mnShadowSlant;
363 64 : xPropSet->setPropertyValue("D3DSceneShadowSlant", aAny);
364 :
365 : // shadeMode
366 64 : aAny <<= mxShadeMode;
367 64 : xPropSet->setPropertyValue("D3DSceneShadeMode", aAny);
368 :
369 : // ambientColor
370 64 : aAny <<= maAmbientColor;
371 64 : xPropSet->setPropertyValue("D3DSceneAmbientColor", aAny);
372 :
373 : // lightingMode
374 64 : aAny <<= mbLightingMode;
375 64 : xPropSet->setPropertyValue("D3DSceneTwoSidedLighting", aAny);
376 :
377 64 : if( !maList.empty() )
378 : {
379 64 : uno::Any aAny2;
380 128 : uno::Any aAny3;
381 :
382 : // set lights
383 576 : for( size_t a = 0; a < maList.size(); a++)
384 : {
385 512 : SdXML3DLightContext* pCtx = (SdXML3DLightContext*)maList[ a ];
386 :
387 : // set anys
388 512 : aAny <<= pCtx->GetDiffuseColor();
389 512 : drawing::Direction3D xLightDir;
390 512 : xLightDir.DirectionX = pCtx->GetDirection().getX();
391 512 : xLightDir.DirectionY = pCtx->GetDirection().getY();
392 512 : xLightDir.DirectionZ = pCtx->GetDirection().getZ();
393 512 : aAny2 <<= xLightDir;
394 512 : aAny3 <<= pCtx->GetEnabled();
395 :
396 512 : switch(a)
397 : {
398 : case 0:
399 : {
400 64 : xPropSet->setPropertyValue("D3DSceneLightColor1", aAny);
401 64 : xPropSet->setPropertyValue("D3DSceneLightDirection1", aAny2);
402 64 : xPropSet->setPropertyValue("D3DSceneLightOn1", aAny3);
403 64 : break;
404 : }
405 : case 1:
406 : {
407 64 : xPropSet->setPropertyValue("D3DSceneLightColor2", aAny);
408 64 : xPropSet->setPropertyValue("D3DSceneLightDirection2", aAny2);
409 64 : xPropSet->setPropertyValue("D3DSceneLightOn2", aAny3);
410 64 : break;
411 : }
412 : case 2:
413 : {
414 64 : xPropSet->setPropertyValue("D3DSceneLightColor3", aAny);
415 64 : xPropSet->setPropertyValue("D3DSceneLightDirection3", aAny2);
416 64 : xPropSet->setPropertyValue("D3DSceneLightOn3", aAny3);
417 64 : break;
418 : }
419 : case 3:
420 : {
421 64 : xPropSet->setPropertyValue("D3DSceneLightColor4", aAny);
422 64 : xPropSet->setPropertyValue("D3DSceneLightDirection4", aAny2);
423 64 : xPropSet->setPropertyValue("D3DSceneLightOn4", aAny3);
424 64 : break;
425 : }
426 : case 4:
427 : {
428 64 : xPropSet->setPropertyValue("D3DSceneLightColor5", aAny);
429 64 : xPropSet->setPropertyValue("D3DSceneLightDirection5", aAny2);
430 64 : xPropSet->setPropertyValue("D3DSceneLightOn5", aAny3);
431 64 : break;
432 : }
433 : case 5:
434 : {
435 64 : xPropSet->setPropertyValue("D3DSceneLightColor6", aAny);
436 64 : xPropSet->setPropertyValue("D3DSceneLightDirection6", aAny2);
437 64 : xPropSet->setPropertyValue("D3DSceneLightOn6", aAny3);
438 64 : break;
439 : }
440 : case 6:
441 : {
442 64 : xPropSet->setPropertyValue("D3DSceneLightColor7", aAny);
443 64 : xPropSet->setPropertyValue("D3DSceneLightDirection7", aAny2);
444 64 : xPropSet->setPropertyValue("D3DSceneLightOn7", aAny3);
445 64 : break;
446 : }
447 : case 7:
448 : {
449 64 : xPropSet->setPropertyValue("D3DSceneLightColor8", aAny);
450 64 : xPropSet->setPropertyValue("D3DSceneLightDirection8", aAny2);
451 64 : xPropSet->setPropertyValue("D3DSceneLightOn8", aAny3);
452 64 : break;
453 : }
454 : }
455 64 : }
456 : }
457 :
458 : // CameraGeometry and camera settings
459 64 : drawing::CameraGeometry aCamGeo;
460 64 : aCamGeo.vrp.PositionX = maVRP.getX();
461 64 : aCamGeo.vrp.PositionY = maVRP.getY();
462 64 : aCamGeo.vrp.PositionZ = maVRP.getZ();
463 64 : aCamGeo.vpn.DirectionX = maVPN.getX();
464 64 : aCamGeo.vpn.DirectionY = maVPN.getY();
465 64 : aCamGeo.vpn.DirectionZ = maVPN.getZ();
466 64 : aCamGeo.vup.DirectionX = maVUP.getX();
467 64 : aCamGeo.vup.DirectionY = maVUP.getY();
468 64 : aCamGeo.vup.DirectionZ = maVUP.getZ();
469 64 : aAny <<= aCamGeo;
470 64 : xPropSet->setPropertyValue("D3DCameraGeometry", aAny);
471 :
472 : // #91047# set drawing::ProjectionMode AFTER camera geometry is set
473 : // projection "D3DScenePerspective" drawing::ProjectionMode
474 64 : aAny <<= mxPrjMode;
475 64 : xPropSet->setPropertyValue("D3DScenePerspective", aAny);
476 64 : }
477 :
478 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|