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 "ximp3dobject.hxx"
21 #include <xmloff/xmluconv.hxx>
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <xexptran.hxx>
24 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
25 #include <com/sun/star/drawing/Direction3D.hpp>
26 #include <com/sun/star/drawing/Position3D.hpp>
27 #include <osl/diagnose.h>
28 #include <basegfx/polygon/b2dpolypolygon.hxx>
29 #include <basegfx/polygon/b2dpolypolygontools.hxx>
30 #include <basegfx/polygon/b3dpolypolygontools.hxx>
31 
32 using namespace ::com::sun::star;
33 
34 
SdXML3DObjectContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const css::uno::Reference<css::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> const & rShapes)35 SdXML3DObjectContext::SdXML3DObjectContext(
36     SvXMLImport& rImport,
37     sal_uInt16 nPrfx,
38     const OUString& rLocalName,
39     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
40     uno::Reference< drawing::XShapes > const & rShapes)
41 :   SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, false/*bTemporaryShape*/ ),
42     mbSetTransform( false )
43 {
44     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
45     for(sal_Int16 i=0; i < nAttrCount; i++)
46     {
47         OUString sAttrName = xAttrList->getNameByIndex( i );
48         OUString aLocalName;
49         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
50         OUString sValue = xAttrList->getValueByIndex( i );
51         const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DObjectAttrTokenMap();
52 
53         switch(rAttrTokenMap.Get(nPrefix, aLocalName))
54         {
55             case XML_TOK_3DOBJECT_DRAWSTYLE_NAME:
56             {
57                 maDrawStyleName = sValue;
58                 break;
59             }
60             case XML_TOK_3DOBJECT_TRANSFORM:
61             {
62                 SdXMLImExTransform3D aTransform(sValue, GetImport().GetMM100UnitConverter());
63                 if(aTransform.NeedsAction())
64                     mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
65                 break;
66             }
67         }
68     }
69 }
70 
~SdXML3DObjectContext()71 SdXML3DObjectContext::~SdXML3DObjectContext()
72 {
73 }
74 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)75 void SdXML3DObjectContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
76 {
77     uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
78     if(xPropSet.is())
79     {
80         // set parameters
81         if(mbSetTransform)
82         {
83             xPropSet->setPropertyValue("D3DTransformMatrix", uno::Any(mxHomMat));
84         }
85 
86         // call parent
87         SdXMLShapeContext::StartElement(xAttrList);
88     }
89 }
90 
SdXML3DCubeObjectShapeContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const css::uno::Reference<css::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> const & rShapes)91 SdXML3DCubeObjectShapeContext::SdXML3DCubeObjectShapeContext(
92     SvXMLImport& rImport,
93     sal_uInt16 nPrfx,
94     const OUString& rLocalName,
95     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
96     uno::Reference< drawing::XShapes > const & rShapes)
97 :   SdXML3DObjectContext( rImport, nPrfx, rLocalName, xAttrList, rShapes ),
98     maMinEdge(-2500.0, -2500.0, -2500.0),
99     maMaxEdge(2500.0, 2500.0, 2500.0)
100 {
101     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
102     for(sal_Int16 i=0; i < nAttrCount; i++)
103     {
104         OUString sAttrName = xAttrList->getNameByIndex( i );
105         OUString aLocalName;
106         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
107         OUString sValue = xAttrList->getValueByIndex( i );
108         const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DCubeObjectAttrTokenMap();
109 
110         switch(rAttrTokenMap.Get(nPrefix, aLocalName))
111         {
112             case XML_TOK_3DCUBEOBJ_MINEDGE:
113             {
114                 ::basegfx::B3DVector aNewVec;
115                 SvXMLUnitConverter::convertB3DVector(aNewVec, sValue);
116 
117                 if(aNewVec != maMinEdge)
118                     maMinEdge = aNewVec;
119                 break;
120             }
121             case XML_TOK_3DCUBEOBJ_MAXEDGE:
122             {
123                 ::basegfx::B3DVector aNewVec;
124                 SvXMLUnitConverter::convertB3DVector(aNewVec, sValue);
125 
126                 if(aNewVec != maMaxEdge)
127                     maMaxEdge = aNewVec;
128                 break;
129             }
130         }
131     }
132 }
133 
~SdXML3DCubeObjectShapeContext()134 SdXML3DCubeObjectShapeContext::~SdXML3DCubeObjectShapeContext()
135 {
136 }
137 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)138 void SdXML3DCubeObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
139 {
140     // create shape
141     AddShape( "com.sun.star.drawing.Shape3DCubeObject" );
142     if(mxShape.is())
143     {
144         // add, set style and properties from base shape
145         SetStyle();
146         SdXML3DObjectContext::StartElement(xAttrList);
147 
148         // set local parameters on shape
149         uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
150         if(xPropSet.is())
151         {
152             // set parameters
153             drawing::Position3D aPosition3D;
154             drawing::Direction3D aDirection3D;
155 
156             // convert from min, max to size to be set
157             maMaxEdge = maMaxEdge - maMinEdge;
158 
159             aPosition3D.PositionX = maMinEdge.getX();
160             aPosition3D.PositionY = maMinEdge.getY();
161             aPosition3D.PositionZ = maMinEdge.getZ();
162 
163             aDirection3D.DirectionX = maMaxEdge.getX();
164             aDirection3D.DirectionY = maMaxEdge.getY();
165             aDirection3D.DirectionZ = maMaxEdge.getZ();
166 
167             xPropSet->setPropertyValue("D3DPosition", uno::Any(aPosition3D));
168             xPropSet->setPropertyValue("D3DSize", uno::Any(aDirection3D));
169         }
170     }
171 }
172 
SdXML3DSphereObjectShapeContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const css::uno::Reference<css::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> const & rShapes)173 SdXML3DSphereObjectShapeContext::SdXML3DSphereObjectShapeContext(
174     SvXMLImport& rImport,
175     sal_uInt16 nPrfx,
176     const OUString& rLocalName,
177     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
178     uno::Reference< drawing::XShapes > const & rShapes)
179 :   SdXML3DObjectContext( rImport, nPrfx, rLocalName, xAttrList, rShapes ),
180     maCenter(0.0, 0.0, 0.0),
181     maSphereSize(5000.0, 5000.0, 5000.0)
182 {
183     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
184     for(sal_Int16 i=0; i < nAttrCount; i++)
185     {
186         OUString sAttrName = xAttrList->getNameByIndex( i );
187         OUString aLocalName;
188         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
189         OUString sValue = xAttrList->getValueByIndex( i );
190         const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DSphereObjectAttrTokenMap();
191 
192         switch(rAttrTokenMap.Get(nPrefix, aLocalName))
193         {
194             case XML_TOK_3DSPHEREOBJ_CENTER:
195             {
196                 ::basegfx::B3DVector aNewVec;
197                 SvXMLUnitConverter::convertB3DVector(aNewVec, sValue);
198 
199                 if(aNewVec != maCenter)
200                     maCenter = aNewVec;
201                 break;
202             }
203             case XML_TOK_3DSPHEREOBJ_SIZE:
204             {
205                 ::basegfx::B3DVector aNewVec;
206                 SvXMLUnitConverter::convertB3DVector(aNewVec, sValue);
207 
208                 if(aNewVec != maSphereSize)
209                     maSphereSize = aNewVec;
210                 break;
211             }
212         }
213     }
214 }
215 
~SdXML3DSphereObjectShapeContext()216 SdXML3DSphereObjectShapeContext::~SdXML3DSphereObjectShapeContext()
217 {
218 }
219 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)220 void SdXML3DSphereObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
221 {
222     // create shape
223     AddShape( "com.sun.star.drawing.Shape3DSphereObject" );
224     if(mxShape.is())
225     {
226         // add, set style and properties from base shape
227         SetStyle();
228         SdXML3DObjectContext::StartElement(xAttrList);
229 
230         // set local parameters on shape
231         uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
232         if(xPropSet.is())
233         {
234             // set parameters
235             drawing::Position3D aPosition3D;
236             drawing::Direction3D aDirection3D;
237 
238             aPosition3D.PositionX = maCenter.getX();
239             aPosition3D.PositionY = maCenter.getY();
240             aPosition3D.PositionZ = maCenter.getZ();
241 
242             aDirection3D.DirectionX = maSphereSize.getX();
243             aDirection3D.DirectionY = maSphereSize.getY();
244             aDirection3D.DirectionZ = maSphereSize.getZ();
245 
246             xPropSet->setPropertyValue("D3DPosition", uno::Any(aPosition3D));
247             xPropSet->setPropertyValue("D3DSize", uno::Any(aDirection3D));
248         }
249     }
250 }
251 
SdXML3DPolygonBasedShapeContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const css::uno::Reference<css::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> const & rShapes)252 SdXML3DPolygonBasedShapeContext::SdXML3DPolygonBasedShapeContext(
253     SvXMLImport& rImport,
254     sal_uInt16 nPrfx,
255     const OUString& rLocalName,
256     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
257     uno::Reference< drawing::XShapes > const & rShapes)
258 :   SdXML3DObjectContext( rImport, nPrfx, rLocalName, xAttrList, rShapes )
259 {
260     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
261     for(sal_Int16 i=0; i < nAttrCount; i++)
262     {
263         OUString sAttrName = xAttrList->getNameByIndex( i );
264         OUString aLocalName;
265         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
266         OUString sValue = xAttrList->getValueByIndex( i );
267         const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DPolygonBasedAttrTokenMap();
268 
269         switch(rAttrTokenMap.Get(nPrefix, aLocalName))
270         {
271             case XML_TOK_3DPOLYGONBASED_VIEWBOX:
272             {
273                 maViewBox = sValue;
274                 break;
275             }
276             case XML_TOK_3DPOLYGONBASED_D:
277             {
278                 maPoints = sValue;
279                 break;
280             }
281         }
282     }
283 }
284 
~SdXML3DPolygonBasedShapeContext()285 SdXML3DPolygonBasedShapeContext::~SdXML3DPolygonBasedShapeContext()
286 {
287 }
288 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)289 void SdXML3DPolygonBasedShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
290 {
291     uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
292 
293     if(xPropSet.is())
294     {
295         // set parameters
296         if(!maPoints.isEmpty() && !maViewBox.isEmpty())
297         {
298             // import 2d tools::PolyPolygon from svg:d
299             basegfx::B2DPolyPolygon aPolyPolygon;
300 
301             if(basegfx::utils::importFromSvgD(aPolyPolygon, maPoints, GetImport().needFixPositionAfterZ(), nullptr))
302             {
303                 // convert to 3D PolyPolygon
304                 const basegfx::B3DPolyPolygon aB3DPolyPolygon(
305                     basegfx::utils::createB3DPolyPolygonFromB2DPolyPolygon(
306                         aPolyPolygon));
307 
308                 // convert to UNO API class PolyPolygonShape3D
309                 drawing::PolyPolygonShape3D aPolyPolygon3D;
310                 basegfx::utils::B3DPolyPolygonToUnoPolyPolygonShape3D(
311                     aB3DPolyPolygon,
312                     aPolyPolygon3D);
313 
314                 // set polygon data
315                 xPropSet->setPropertyValue("D3DPolyPolygon3D", uno::Any(aPolyPolygon3D));
316             }
317             else
318             {
319                 OSL_ENSURE(false, "Error on importing svg:d for 3D tools::PolyPolygon (!)");
320             }
321         }
322 
323         // call parent
324         SdXML3DObjectContext::StartElement(xAttrList);
325     }
326 }
327 
328 
SdXML3DLatheObjectShapeContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const css::uno::Reference<css::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> const & rShapes)329 SdXML3DLatheObjectShapeContext::SdXML3DLatheObjectShapeContext(
330     SvXMLImport& rImport,
331     sal_uInt16 nPrfx,
332     const OUString& rLocalName,
333     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
334     uno::Reference< drawing::XShapes > const & rShapes)
335 :   SdXML3DPolygonBasedShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes )
336 {
337 }
338 
~SdXML3DLatheObjectShapeContext()339 SdXML3DLatheObjectShapeContext::~SdXML3DLatheObjectShapeContext()
340 {
341 }
342 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)343 void SdXML3DLatheObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
344 {
345     // create shape
346     AddShape( "com.sun.star.drawing.Shape3DLatheObject" );
347     if(mxShape.is())
348     {
349         // add, set style and properties from base shape
350         SetStyle();
351         SdXML3DPolygonBasedShapeContext::StartElement(xAttrList);
352     }
353 }
354 
SdXML3DExtrudeObjectShapeContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLocalName,const css::uno::Reference<css::xml::sax::XAttributeList> & xAttrList,uno::Reference<drawing::XShapes> const & rShapes)355 SdXML3DExtrudeObjectShapeContext::SdXML3DExtrudeObjectShapeContext(
356     SvXMLImport& rImport,
357     sal_uInt16 nPrfx,
358     const OUString& rLocalName,
359     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
360     uno::Reference< drawing::XShapes > const & rShapes)
361 :   SdXML3DPolygonBasedShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes )
362 {
363 }
364 
~SdXML3DExtrudeObjectShapeContext()365 SdXML3DExtrudeObjectShapeContext::~SdXML3DExtrudeObjectShapeContext()
366 {
367 }
368 
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)369 void SdXML3DExtrudeObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
370 {
371     AddShape( "com.sun.star.drawing.Shape3DExtrudeObject" );
372     if(mxShape.is())
373     {
374         // add, set style and properties from base shape
375         SetStyle();
376         SdXML3DPolygonBasedShapeContext::StartElement(xAttrList);
377     }
378 }
379 
380 
381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
382