Coverage Report

Created: 2026-08-14 10:22

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