Fix typo
[LibreOffice.git] / xmloff / source / draw / ximp3dscene.cxx
blob8c1648be4490fb1fa8c731094814a78697ab3664
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
21 #include <sal/log.hxx>
23 #include "ximp3dscene.hxx"
24 #include <xmloff/xmluconv.hxx>
25 #include <xexptran.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/xmlnamespace.hxx>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/drawing/Direction3D.hpp>
30 #include <com/sun/star/drawing/CameraGeometry.hpp>
31 #include "eventimp.hxx"
32 #include "descriptionimp.hxx"
34 using namespace ::com::sun::star;
35 using namespace ::xmloff::token;
37 // dr3d:3dlight context
39 SdXML3DLightContext::SdXML3DLightContext(
40 SvXMLImport& rImport,
41 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
42 : SvXMLImportContext( rImport ),
43 maDiffuseColor(0x00000000),
44 maDirection(0.0, 0.0, 1.0),
45 mbEnabled(false),
46 mbSpecular(false)
48 // read attributes for the 3DScene
49 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
51 switch(aIter.getToken())
53 case XML_ELEMENT(DR3D, XML_DIFFUSE_COLOR):
55 ::sax::Converter::convertColor(maDiffuseColor, aIter.toView());
56 break;
58 case XML_ELEMENT(DR3D, XML_DIRECTION):
60 ::basegfx::B3DVector aVal;
61 SvXMLUnitConverter::convertB3DVector(aVal, aIter.toView());
62 if (!std::isnan(aVal.getX()) && !std::isnan(aVal.getY()) && !std::isnan(aVal.getZ()))
64 maDirection = aVal;
66 else
68 SAL_WARN("xmloff", "NaNs found in light direction: " << aIter.toString());
70 break;
72 case XML_ELEMENT(DR3D, XML_ENABLED):
74 (void)::sax::Converter::convertBool(mbEnabled, aIter.toView());
75 break;
77 case XML_ELEMENT(DR3D, XML_SPECULAR):
79 (void)::sax::Converter::convertBool(mbSpecular, aIter.toView());
80 break;
82 default:
83 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
88 SdXML3DLightContext::~SdXML3DLightContext()
93 SdXML3DSceneShapeContext::SdXML3DSceneShapeContext(
94 SvXMLImport& rImport,
95 const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
96 uno::Reference< drawing::XShapes > const & rShapes,
97 bool bTemporaryShapes)
98 : SdXMLShapeContext( rImport, xAttrList, rShapes, bTemporaryShapes ), SdXML3DSceneAttributesHelper( rImport )
102 SdXML3DSceneShapeContext::~SdXML3DSceneShapeContext()
106 void SdXML3DSceneShapeContext::startFastElement(
107 sal_Int32 nElement,
108 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
110 // create new 3DScene shape and add it to rShapes, use it
111 // as base for the new 3DScene import
112 AddShape( u"com.sun.star.drawing.Shape3DSceneObject"_ustr );
113 if( mxShape.is() )
115 SetStyle();
117 mxChildren.set( mxShape, uno::UNO_QUERY );
118 if( mxChildren.is() )
119 GetImport().GetShapeImport()->pushGroupForPostProcessing( mxChildren );
121 SetLayer();
123 // set pos, size, shear and rotate
124 SetTransformation();
127 // read attributes for the 3DScene
128 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
129 processSceneAttribute( aIter );
131 // #91047# call parent function is missing here, added it
132 if(mxShape.is())
134 // call parent
135 SdXMLShapeContext::startFastElement(nElement, xAttrList);
139 void SdXML3DSceneShapeContext::endFastElement(sal_Int32 nElement)
141 if(!mxShape.is())
142 return;
144 uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
145 if(xPropSet.is())
147 setSceneAttributes( xPropSet );
150 if( mxChildren.is() )
151 GetImport().GetShapeImport()->popGroupAndPostProcess();
153 // call parent
154 SdXMLShapeContext::endFastElement(nElement);
157 css::uno::Reference< css::xml::sax::XFastContextHandler > SdXML3DSceneShapeContext::createFastChildContext(
158 sal_Int32 nElement,
159 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
161 SvXMLImportContextRef xContext;
162 switch (nElement)
164 // #i68101#
165 case XML_ELEMENT(SVG, XML_TITLE):
166 case XML_ELEMENT(SVG_COMPAT, XML_TITLE):
167 case XML_ELEMENT(SVG, XML_DESC):
168 case XML_ELEMENT(SVG_COMPAT, XML_DESC):
169 xContext = new SdXMLDescriptionContext( GetImport(), nElement, mxShape );
170 break;
171 case XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS):
172 xContext = new SdXMLEventsContext( GetImport(), mxShape );
173 break;
174 // look for local light context first
175 case XML_ELEMENT(DR3D, XML_LIGHT):
176 // dr3d:light inside dr3d:scene context
177 xContext = create3DLightContext( xAttrList );
178 break;
179 default:
180 // call GroupChildContext function at common ShapeImport
181 return XMLShapeImportHelper::Create3DSceneChildContext(
182 GetImport(), nElement, xAttrList, mxChildren);
184 return xContext;
187 SdXML3DSceneAttributesHelper::SdXML3DSceneAttributesHelper( SvXMLImport& rImporter )
188 : mrImport( rImporter ),
189 mbSetTransform( false ),
190 mxPrjMode(drawing::ProjectionMode_PERSPECTIVE),
191 mnDistance(1000),
192 mnFocalLength(1000),
193 mnShadowSlant(0),
194 mxShadeMode(drawing::ShadeMode_SMOOTH),
195 maAmbientColor(0x00666666),
196 mbLightingMode(false),
197 maVRP(0.0, 0.0, 1.0),
198 maVPN(0.0, 0.0, 1.0),
199 maVUP(0.0, 1.0, 0.0),
200 mbVRPUsed(false)
204 /** creates a 3d light context and adds it to the internal list for later processing */
205 SvXMLImportContext * SdXML3DSceneAttributesHelper::create3DLightContext( const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
207 const rtl::Reference<SdXML3DLightContext> xContext{new SdXML3DLightContext(mrImport, xAttrList)};
209 // remember SdXML3DLightContext for later evaluation
210 maList.push_back(xContext);
212 return xContext.get();
215 /** this should be called for each scene attribute */
216 void SdXML3DSceneAttributesHelper::processSceneAttribute( const sax_fastparser::FastAttributeList::FastAttributeIter & aIter )
218 auto nAttributeToken = aIter.getToken();
219 if( !IsTokenInNamespace(nAttributeToken, XML_NAMESPACE_DR3D) )
220 return;
222 switch(nAttributeToken & TOKEN_MASK)
224 case XML_TRANSFORM:
226 SdXMLImExTransform3D aTransform(aIter.toString(), mrImport.GetMM100UnitConverter());
227 if(aTransform.NeedsAction())
228 mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
229 return;
231 case XML_VRP:
233 ::basegfx::B3DVector aNewVec;
234 SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
236 if(aNewVec != maVRP)
238 maVRP = aNewVec;
239 mbVRPUsed = true;
241 return;
243 case XML_VPN:
245 ::basegfx::B3DVector aNewVec;
246 SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
248 if(aNewVec != maVPN)
250 maVPN = aNewVec;
252 return;
254 case XML_VUP:
256 ::basegfx::B3DVector aNewVec;
257 SvXMLUnitConverter::convertB3DVector(aNewVec, aIter.toView());
259 if(aNewVec != maVUP)
261 maVUP = aNewVec;
263 return;
265 case XML_PROJECTION:
267 if( IsXMLToken( aIter, XML_PARALLEL ) )
268 mxPrjMode = drawing::ProjectionMode_PARALLEL;
269 else
270 mxPrjMode = drawing::ProjectionMode_PERSPECTIVE;
271 return;
273 case XML_DISTANCE:
275 mrImport.GetMM100UnitConverter().convertMeasureToCore(mnDistance,
276 aIter.toView());
277 return;
279 case XML_FOCAL_LENGTH:
281 mrImport.GetMM100UnitConverter().convertMeasureToCore(mnFocalLength,
282 aIter.toView());
283 return;
285 case XML_SHADOW_SLANT:
287 double fAngle = 0.0;
288 if (::sax::Converter::convertAngle(fAngle, aIter.toView()))
289 mnShadowSlant = static_cast<sal_Int32>(basegfx::fround(fAngle));
290 else
291 mnShadowSlant = 0;
292 return;
294 case XML_SHADE_MODE:
296 if( IsXMLToken( aIter, XML_FLAT ) )
297 mxShadeMode = drawing::ShadeMode_FLAT;
298 else if( IsXMLToken( aIter, XML_PHONG ) )
299 mxShadeMode = drawing::ShadeMode_PHONG;
300 else if( IsXMLToken( aIter, XML_GOURAUD ) )
301 mxShadeMode = drawing::ShadeMode_SMOOTH;
302 else
303 mxShadeMode = drawing::ShadeMode_DRAFT;
304 return;
306 case XML_AMBIENT_COLOR:
308 ::sax::Converter::convertColor(maAmbientColor, aIter.toView());
309 return;
311 case XML_LIGHTING_MODE:
313 (void)::sax::Converter::convertBool(mbLightingMode, aIter.toView());
314 return;
316 default:
317 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
321 /** this sets the scene attributes at this propertyset */
322 void SdXML3DSceneAttributesHelper::setSceneAttributes( const css::uno::Reference< css::beans::XPropertySet >& xPropSet )
324 uno::Any aAny;
326 // world transformation
327 if(mbSetTransform)
329 xPropSet->setPropertyValue(u"D3DTransformMatrix"_ustr, uno::Any(mxHomMat));
332 // distance
333 xPropSet->setPropertyValue(u"D3DSceneDistance"_ustr, uno::Any(mnDistance));
334 // focalLength
335 xPropSet->setPropertyValue(u"D3DSceneFocalLength"_ustr, uno::Any(mnFocalLength));
336 // shadowSlant
337 xPropSet->setPropertyValue(u"D3DSceneShadowSlant"_ustr, uno::Any(static_cast<sal_Int16>(mnShadowSlant)));
338 // shadeMode
339 xPropSet->setPropertyValue(u"D3DSceneShadeMode"_ustr, uno::Any(mxShadeMode));
340 // ambientColor
341 xPropSet->setPropertyValue(u"D3DSceneAmbientColor"_ustr, uno::Any(maAmbientColor));
342 // lightingMode
343 xPropSet->setPropertyValue(u"D3DSceneTwoSidedLighting"_ustr, uno::Any(mbLightingMode));
345 if( !maList.empty() )
347 uno::Any aAny2;
348 uno::Any aAny3;
350 // set lights
351 for( size_t a = 0; a < maList.size(); a++)
353 SdXML3DLightContext* pCtx = maList[ a ].get();
355 // set anys
356 aAny <<= pCtx->GetDiffuseColor();
357 drawing::Direction3D aLightDir;
358 aLightDir.DirectionX = pCtx->GetDirection().getX();
359 aLightDir.DirectionY = pCtx->GetDirection().getY();
360 aLightDir.DirectionZ = pCtx->GetDirection().getZ();
361 aAny2 <<= aLightDir;
362 aAny3 <<= pCtx->GetEnabled();
364 switch(a)
366 case 0:
368 xPropSet->setPropertyValue(u"D3DSceneLightColor1"_ustr, aAny);
369 xPropSet->setPropertyValue(u"D3DSceneLightDirection1"_ustr, aAny2);
370 xPropSet->setPropertyValue(u"D3DSceneLightOn1"_ustr, aAny3);
371 break;
373 case 1:
375 xPropSet->setPropertyValue(u"D3DSceneLightColor2"_ustr, aAny);
376 xPropSet->setPropertyValue(u"D3DSceneLightDirection2"_ustr, aAny2);
377 xPropSet->setPropertyValue(u"D3DSceneLightOn2"_ustr, aAny3);
378 break;
380 case 2:
382 xPropSet->setPropertyValue(u"D3DSceneLightColor3"_ustr, aAny);
383 xPropSet->setPropertyValue(u"D3DSceneLightDirection3"_ustr, aAny2);
384 xPropSet->setPropertyValue(u"D3DSceneLightOn3"_ustr, aAny3);
385 break;
387 case 3:
389 xPropSet->setPropertyValue(u"D3DSceneLightColor4"_ustr, aAny);
390 xPropSet->setPropertyValue(u"D3DSceneLightDirection4"_ustr, aAny2);
391 xPropSet->setPropertyValue(u"D3DSceneLightOn4"_ustr, aAny3);
392 break;
394 case 4:
396 xPropSet->setPropertyValue(u"D3DSceneLightColor5"_ustr, aAny);
397 xPropSet->setPropertyValue(u"D3DSceneLightDirection5"_ustr, aAny2);
398 xPropSet->setPropertyValue(u"D3DSceneLightOn5"_ustr, aAny3);
399 break;
401 case 5:
403 xPropSet->setPropertyValue(u"D3DSceneLightColor6"_ustr, aAny);
404 xPropSet->setPropertyValue(u"D3DSceneLightDirection6"_ustr, aAny2);
405 xPropSet->setPropertyValue(u"D3DSceneLightOn6"_ustr, aAny3);
406 break;
408 case 6:
410 xPropSet->setPropertyValue(u"D3DSceneLightColor7"_ustr, aAny);
411 xPropSet->setPropertyValue(u"D3DSceneLightDirection7"_ustr, aAny2);
412 xPropSet->setPropertyValue(u"D3DSceneLightOn7"_ustr, aAny3);
413 break;
415 case 7:
417 xPropSet->setPropertyValue(u"D3DSceneLightColor8"_ustr, aAny);
418 xPropSet->setPropertyValue(u"D3DSceneLightDirection8"_ustr, aAny2);
419 xPropSet->setPropertyValue(u"D3DSceneLightOn8"_ustr, aAny3);
420 break;
426 // CameraGeometry and camera settings
427 drawing::CameraGeometry aCamGeo;
428 aCamGeo.vrp.PositionX = maVRP.getX();
429 aCamGeo.vrp.PositionY = maVRP.getY();
430 aCamGeo.vrp.PositionZ = maVRP.getZ();
431 aCamGeo.vpn.DirectionX = maVPN.getX();
432 aCamGeo.vpn.DirectionY = maVPN.getY();
433 aCamGeo.vpn.DirectionZ = maVPN.getZ();
434 aCamGeo.vup.DirectionX = maVUP.getX();
435 aCamGeo.vup.DirectionY = maVUP.getY();
436 aCamGeo.vup.DirectionZ = maVUP.getZ();
437 xPropSet->setPropertyValue(u"D3DCameraGeometry"_ustr, uno::Any(aCamGeo));
439 // #91047# set drawing::ProjectionMode AFTER camera geometry is set
440 // projection "D3DScenePerspective" drawing::ProjectionMode
441 xPropSet->setPropertyValue(u"D3DScenePerspective"_ustr, uno::Any(mxPrjMode));
444 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */