Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/shape3dproperties.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 <drawingml/shape3dproperties.hxx>
21
#include <com/sun/star/drawing/BitmapMode.hpp>
22
#include <com/sun/star/graphic/XGraphicTransformer.hpp>
23
24
#include <comphelper/propertyvalue.hxx>
25
#include <oox/token/tokens.hxx>
26
#include <sal/log.hxx>
27
28
using namespace ::com::sun::star;
29
30
31
namespace oox::drawingml {
32
33
OUString Generic3DProperties::getCameraPrstName( sal_Int32 nElement )
34
40
{
35
40
    switch( nElement )
36
40
    {
37
0
        case XML_legacyObliqueTopLeft:          return u"legacyObliqueTopLeft"_ustr;
38
0
        case XML_legacyObliqueTop:              return u"legacyObliqueTop"_ustr;
39
6
        case XML_legacyObliqueTopRight:         return u"legacyObliqueTopRight"_ustr;
40
0
        case XML_legacyObliqueLeft:             return u"legacyObliqueLeft"_ustr;
41
0
        case XML_legacyObliqueFront:            return u"legacyObliqueFront"_ustr;
42
0
        case XML_legacyObliqueRight:            return u"legacyObliqueRight"_ustr;
43
0
        case XML_legacyObliqueBottomLeft:       return u"legacyObliqueBottomLeft"_ustr;
44
0
        case XML_legacyObliqueBottom:           return u"legacyObliqueBottom"_ustr;
45
0
        case XML_legacyObliqueBottomRight:      return u"legacyObliqueBottomRight"_ustr;
46
0
        case XML_legacyPerspectiveTopLeft:      return u"legacyPerspectiveTopLeft"_ustr;
47
0
        case XML_legacyPerspectiveTop:          return u"legacyPerspectiveTop"_ustr;
48
0
        case XML_legacyPerspectiveTopRight:     return u"legacyPerspectiveTopRight"_ustr;
49
0
        case XML_legacyPerspectiveLeft:         return u"legacyPerspectiveLeft"_ustr;
50
0
        case XML_legacyPerspectiveFront:        return u"legacyPerspectiveFront"_ustr;
51
0
        case XML_legacyPerspectiveRight:        return u"legacyPerspectiveRight"_ustr;
52
0
        case XML_legacyPerspectiveBottomLeft:   return u"legacyPerspectiveBottomLeft"_ustr;
53
0
        case XML_legacyPerspectiveBottom:       return u"legacyPerspectiveBottom"_ustr;
54
0
        case XML_legacyPerspectiveBottomRight:  return u"legacyPerspectiveBottomRight"_ustr;
55
18
        case XML_orthographicFront:             return u"orthographicFront"_ustr;
56
0
        case XML_isometricTopUp:                return u"isometricTopUp"_ustr;
57
0
        case XML_isometricTopDown:              return u"isometricTopDown"_ustr;
58
0
        case XML_isometricBottomUp:             return u"isometricBottomUp"_ustr;
59
0
        case XML_isometricBottomDown:           return u"isometricBottomDown"_ustr;
60
0
        case XML_isometricLeftUp:               return u"isometricLeftUp"_ustr;
61
16
        case XML_isometricLeftDown:             return u"isometricLeftDown"_ustr;
62
0
        case XML_isometricRightUp:              return u"isometricRightUp"_ustr;
63
0
        case XML_isometricRightDown:            return u"isometricRightDown"_ustr;
64
0
        case XML_isometricOffAxis1Left:         return u"isometricOffAxis1Left"_ustr;
65
0
        case XML_isometricOffAxis1Right:        return u"isometricOffAxis1Right"_ustr;
66
0
        case XML_isometricOffAxis1Top:          return u"isometricOffAxis1Top"_ustr;
67
0
        case XML_isometricOffAxis2Left:         return u"isometricOffAxis2Left"_ustr;
68
0
        case XML_isometricOffAxis2Right:        return u"isometricOffAxis2Right"_ustr;
69
0
        case XML_isometricOffAxis2Top:          return u"isometricOffAxis2Top"_ustr;
70
0
        case XML_isometricOffAxis3Left:         return u"isometricOffAxis3Left"_ustr;
71
0
        case XML_isometricOffAxis3Right:        return u"isometricOffAxis3Right"_ustr;
72
0
        case XML_isometricOffAxis3Bottom:       return u"isometricOffAxis3Bottom"_ustr;
73
0
        case XML_isometricOffAxis4Left:         return u"isometricOffAxis4Left"_ustr;
74
0
        case XML_isometricOffAxis4Right:        return u"isometricOffAxis4Right"_ustr;
75
0
        case XML_isometricOffAxis4Bottom:       return u"isometricOffAxis4Bottom"_ustr;
76
0
        case XML_obliqueTopLeft:                return u"obliqueTopLeft"_ustr;
77
0
        case XML_obliqueTop:                    return u"obliqueTop"_ustr;
78
0
        case XML_obliqueTopRight:               return u"obliqueTopRight"_ustr;
79
0
        case XML_obliqueLeft:                   return u"obliqueLeft"_ustr;
80
0
        case XML_obliqueRight:                  return u"obliqueRight"_ustr;
81
0
        case XML_obliqueBottomLeft:             return u"obliqueBottomLeft"_ustr;
82
0
        case XML_obliqueBottom:                 return u"obliqueBottom"_ustr;
83
0
        case XML_obliqueBottomRight:            return u"obliqueBottomRight"_ustr;
84
0
        case XML_perspectiveFront:              return u"perspectiveFront"_ustr;
85
0
        case XML_perspectiveLeft:               return u"perspectiveLeft"_ustr;
86
0
        case XML_perspectiveRight:              return u"perspectiveRight"_ustr;
87
0
        case XML_perspectiveAbove:              return u"perspectiveAbove"_ustr;
88
0
        case XML_perspectiveBelow:              return u"perspectiveBelow"_ustr;
89
0
        case XML_perspectiveAboveLeftFacing:        return u"perspectiveAboveLeftFacing"_ustr;
90
0
        case XML_perspectiveAboveRightFacing:       return u"perspectiveAboveRightFacing"_ustr;
91
0
        case XML_perspectiveContrastingLeftFacing:  return u"perspectiveContrastingLeftFacing"_ustr;
92
0
        case XML_perspectiveContrastingRightFacing: return u"perspectiveContrastingRightFacing"_ustr;
93
0
        case XML_perspectiveHeroicLeftFacing:       return u"perspectiveHeroicLeftFacing"_ustr;
94
0
        case XML_perspectiveHeroicRightFacing:      return u"perspectiveHeroicRightFacing"_ustr;
95
0
        case XML_perspectiveHeroicExtremeLeftFacing:    return u"perspectiveHeroicExtremeLeftFacing"_ustr;
96
0
        case XML_perspectiveHeroicExtremeRightFacing:   return u"perspectiveHeroicExtremeRightFacing"_ustr;
97
0
        case XML_perspectiveRelaxed:                    return u"perspectiveRelaxed"_ustr;
98
0
        case XML_perspectiveRelaxedModerately:          return u"perspectiveRelaxedModerately"_ustr;
99
40
    }
100
0
    SAL_WARN( "oox.drawingml", "Generic3DProperties::getCameraPrstName - unexpected prst type" );
101
0
    return OUString();
102
0
}
103
104
OUString Generic3DProperties::getLightRigName( sal_Int32 nElement )
105
23
{
106
23
    switch( nElement )
107
23
    {
108
6
        case XML_legacyFlat1:       return u"legacyFlat1"_ustr;
109
0
        case XML_legacyFlat2:       return u"legacyFlat2"_ustr;
110
0
        case XML_legacyFlat3:       return u"legacyFlat3"_ustr;
111
0
        case XML_legacyFlat4:       return u"legacyFlat4"_ustr;
112
0
        case XML_legacyNormal1:     return u"legacyNormal1"_ustr;
113
0
        case XML_legacyNormal2:     return u"legacyNormal2"_ustr;
114
0
        case XML_legacyNormal3:     return u"legacyNormal3"_ustr;
115
0
        case XML_legacyNormal4:     return u"legacyNormal4"_ustr;
116
0
        case XML_legacyHarsh1:      return u"legacyHarsh1"_ustr;
117
0
        case XML_legacyHarsh2:      return u"legacyHarsh2"_ustr;
118
0
        case XML_legacyHarsh3:      return u"legacyHarsh3"_ustr;
119
0
        case XML_legacyHarsh4:      return u"legacyHarsh4"_ustr;
120
14
        case XML_threePt:           return u"threePt"_ustr;
121
0
        case XML_balanced:          return u"balanced"_ustr;
122
0
        case XML_soft:              return u"soft"_ustr;
123
0
        case XML_harsh:             return u"harsh"_ustr;
124
0
        case XML_flood:             return u"flood"_ustr;
125
0
        case XML_contrasting:       return u"contrasting"_ustr;
126
0
        case XML_morning:           return u"morning"_ustr;
127
0
        case XML_sunrise:           return u"sunrise"_ustr;
128
0
        case XML_sunset:            return u"sunset"_ustr;
129
0
        case XML_chilly:            return u"chilly"_ustr;
130
0
        case XML_freezing:          return u"freezing"_ustr;
131
0
        case XML_flat:              return u"flat"_ustr;
132
0
        case XML_twoPt:             return u"twoPt"_ustr;
133
3
        case XML_glow:              return u"glow"_ustr;
134
0
        case XML_brightRoom:        return u"brightRoom"_ustr;
135
23
    }
136
0
    SAL_WARN( "oox.drawingml", "Generic3DProperties::getLightRigName - unexpected token" );
137
0
    return OUString();
138
0
}
139
140
OUString Generic3DProperties::getLightRigDirName( sal_Int32 nElement )
141
20
{
142
20
    switch( nElement )
143
20
    {
144
0
        case XML_tl:    return u"tl"_ustr;
145
20
        case XML_t:     return u"t"_ustr;
146
0
        case XML_tr:    return u"tr"_ustr;
147
0
        case XML_l:     return u"l"_ustr;
148
0
        case XML_r:     return u"r"_ustr;
149
0
        case XML_bl:    return u"bl"_ustr;
150
0
        case XML_b:     return u"b"_ustr;
151
0
        case XML_br:    return u"br"_ustr;
152
20
    }
153
0
    SAL_WARN( "oox.drawingml", "Generic3DProperties::getLightRigDirName - unexpected token" );
154
0
    return OUString();
155
0
}
156
157
OUString Generic3DProperties::getBevelPresetTypeString( sal_Int32 nType )
158
0
{
159
0
    switch (nType)
160
0
    {
161
0
        case XML_relaxedInset:  return u"relaxedInset"_ustr;
162
0
        case XML_circle:        return u"circle"_ustr;
163
0
        case XML_slope:         return u"slope"_ustr;
164
0
        case XML_cross:         return u"cross"_ustr;
165
0
        case XML_angle:         return u"angle"_ustr;
166
0
        case XML_softRound:     return u"softRound"_ustr;
167
0
        case XML_convex:        return u"convex"_ustr;
168
0
        case XML_coolSlant:     return u"coolSlant"_ustr;
169
0
        case XML_divot:         return u"divot"_ustr;
170
0
        case XML_riblet:        return u"riblet"_ustr;
171
0
        case XML_hardEdge:      return u"hardEdge"_ustr;
172
0
        case XML_artDeco:       return u"artDeco"_ustr;
173
0
    }
174
0
    SAL_WARN( "oox.drawingml", "Generic3DProperties::getBevelPresetTypeString - unexpected token" );
175
0
    return OUString();
176
0
}
177
178
OUString Generic3DProperties::getPresetMaterialTypeString( sal_Int32 nType )
179
15
{
180
15
    switch (nType)
181
15
    {
182
15
        case XML_legacyMatte:       return u"legacyMatte"_ustr;
183
0
        case XML_legacyPlastic:     return u"legacyPlastic"_ustr;
184
0
        case XML_legacyMetal:       return u"legacyMetal"_ustr;
185
0
        case XML_legacyWireframe:   return u"legacyWireframe"_ustr;
186
0
        case XML_matte:             return u"matte"_ustr;
187
0
        case XML_plastic:           return u"plastic"_ustr;
188
0
        case XML_metal:             return u"metal"_ustr;
189
0
        case XML_warmMatte:         return u"warmMatte"_ustr;
190
0
        case XML_translucentPowder: return u"translucentPowder"_ustr;
191
0
        case XML_powder:            return u"powder"_ustr;
192
0
        case XML_dkEdge:            return u"dkEdge"_ustr;
193
0
        case XML_softEdge:          return u"softEdge"_ustr;
194
0
        case XML_clear:             return u"clear"_ustr;
195
0
        case XML_flat:              return u"flat"_ustr;
196
0
        case XML_softmetal:         return u"softmetal"_ustr;
197
0
        case XML_none:              return u"none"_ustr;
198
15
    }
199
0
    SAL_WARN( "oox.drawingml", "Generic3DProperties::getPresetMaterialTypeString - unexpected token" );
200
0
    return OUString();
201
0
}
202
203
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getCameraAttributes()
204
67.4k
{
205
67.4k
    css::uno::Sequence<css::beans::PropertyValue> aSeq(6);
206
67.4k
    auto pSeq = aSeq.getArray();
207
67.4k
    sal_Int32 nSize = 0;
208
67.4k
    if( mfFieldOfVision.has_value() )
209
0
    {
210
0
        pSeq[nSize].Name = "fov";
211
0
        pSeq[nSize].Value <<= *mfFieldOfVision;
212
0
        nSize++;
213
0
    }
214
67.4k
    if( mfZoom.has_value() )
215
0
    {
216
0
        pSeq[nSize].Name = "zoom";
217
0
        pSeq[nSize].Value <<= *mfZoom;
218
0
        nSize++;
219
0
    }
220
67.4k
    if( mnPreset.has_value() )
221
20
    {
222
20
        pSeq[nSize].Name = "prst";
223
20
        pSeq[nSize].Value <<= getCameraPrstName( *mnPreset );
224
20
        nSize++;
225
20
    }
226
67.4k
    if( maCameraRotation.mnLatitude.has_value() )
227
12
    {
228
12
        pSeq[nSize].Name = "rotLat";
229
12
        pSeq[nSize].Value <<= *maCameraRotation.mnLatitude;
230
12
        nSize++;
231
12
    }
232
67.4k
    if( maCameraRotation.mnLongitude.has_value() )
233
12
    {
234
12
        pSeq[nSize].Name = "rotLon";
235
12
        pSeq[nSize].Value <<= *maCameraRotation.mnLongitude;
236
12
        nSize++;
237
12
    }
238
67.4k
    if( maCameraRotation.mnRevolution.has_value() )
239
12
    {
240
12
        pSeq[nSize].Name = "rotRev";
241
12
        pSeq[nSize].Value <<= *maCameraRotation.mnRevolution;
242
12
        nSize++;
243
12
    }
244
67.4k
    aSeq.realloc( nSize );
245
67.4k
    return aSeq;
246
67.4k
}
247
248
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getLightRigAttributes()
249
67.4k
{
250
67.4k
    css::uno::Sequence<css::beans::PropertyValue> aSeq(5);
251
67.4k
    auto pSeq = aSeq.getArray();
252
67.4k
    sal_Int32 nSize = 0;
253
67.4k
    if( mnLightRigDirection.has_value() )
254
20
    {
255
20
        pSeq[nSize].Name = "dir";
256
20
        pSeq[nSize].Value <<= getLightRigDirName( *mnLightRigDirection );
257
20
        nSize++;
258
20
    }
259
67.4k
    if( mnLightRigType.has_value() )
260
20
    {
261
20
        pSeq[nSize].Name = "rig";
262
20
        pSeq[nSize].Value <<= getLightRigName( *mnLightRigType );
263
20
        nSize++;
264
20
    }
265
67.4k
    if( maLightRigRotation.mnLatitude.has_value() )
266
3
    {
267
3
        pSeq[nSize].Name = "rotLat";
268
3
        pSeq[nSize].Value <<= *maLightRigRotation.mnLatitude;
269
3
        nSize++;
270
3
    }
271
67.4k
    if( maLightRigRotation.mnLongitude.has_value() )
272
3
    {
273
3
        pSeq[nSize].Name = "rotLon";
274
3
        pSeq[nSize].Value <<= *maLightRigRotation.mnLongitude;
275
3
        nSize++;
276
3
    }
277
67.4k
    if( maLightRigRotation.mnRevolution.has_value() )
278
3
    {
279
3
        pSeq[nSize].Name = "rotRev";
280
3
        pSeq[nSize].Value <<= *maLightRigRotation.mnRevolution;
281
3
        nSize++;
282
3
    }
283
67.4k
    aSeq.realloc( nSize );
284
67.4k
    return aSeq;
285
67.4k
}
286
287
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getBevelAttributes( BevelProperties rProps )
288
0
{
289
0
    css::uno::Sequence<css::beans::PropertyValue> aSeq(3);
290
0
    auto pSeq = aSeq.getArray();
291
0
    sal_Int32 nSize = 0;
292
0
    if( rProps.mnPreset.has_value() )
293
0
    {
294
0
        pSeq[nSize].Name = "prst";
295
0
        pSeq[nSize].Value <<= getBevelPresetTypeString( *rProps.mnPreset );
296
0
        nSize++;
297
0
    }
298
0
    if( rProps.mnWidth.has_value() )
299
0
    {
300
0
        pSeq[nSize].Name = "w";
301
0
        pSeq[nSize].Value <<= *rProps.mnWidth;
302
0
        nSize++;
303
0
    }
304
0
    if( rProps.mnHeight.has_value() )
305
0
    {
306
0
        pSeq[nSize].Name = "h";
307
0
        pSeq[nSize].Value <<= *rProps.mnHeight;
308
0
        nSize++;
309
0
    }
310
0
    aSeq.realloc( nSize );
311
0
    return aSeq;
312
0
}
313
314
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getColorAttributes(
315
        const Color& rColor, const GraphicHelper& rGraphicHelper, ::Color rPhClr )
316
3
{
317
3
    const OUString& sColorScheme = rColor.getSchemeColorName();
318
3
    if( sColorScheme.isEmpty() )
319
3
    {
320
        // RGB color and transparency value
321
3
        return { comphelper::makePropertyValue(u"rgbClr"_ustr, rColor.getColor( rGraphicHelper, rPhClr )),
322
3
                 comphelper::makePropertyValue(u"rgbClrTransparency"_ustr, rColor.getTransparency()) };
323
3
    }
324
    // scheme color with name and transformations
325
0
    return { comphelper::makePropertyValue(u"schemeClr"_ustr, sColorScheme),
326
0
             comphelper::makePropertyValue(u"schemeClrTransformations"_ustr,
327
0
                                           rColor.getTransformations()) };
328
3
}
329
330
css::uno::Sequence< css::beans::PropertyValue > Generic3DProperties::getShape3DAttributes(
331
        const GraphicHelper& rGraphicHelper, ::Color rPhClr )
332
67.4k
{
333
67.4k
    css::uno::Sequence<css::beans::PropertyValue> aSeq(8);
334
67.4k
    auto pSeq = aSeq.getArray();
335
67.4k
    sal_Int32 nSize = 0;
336
67.4k
    if( mnExtrusionH.has_value() )
337
3
    {
338
3
        pSeq[nSize].Name = "extrusionH";
339
3
        pSeq[nSize].Value <<= *mnExtrusionH;
340
3
        nSize++;
341
3
    }
342
67.4k
    if( mnContourW.has_value() )
343
3
    {
344
3
        pSeq[nSize].Name = "contourW";
345
3
        pSeq[nSize].Value <<= *mnContourW;
346
3
        nSize++;
347
3
    }
348
67.4k
    if( mnShapeZ.has_value() )
349
0
    {
350
0
        pSeq[nSize].Name = "z";
351
0
        pSeq[nSize].Value <<= *mnShapeZ;
352
0
        nSize++;
353
0
    }
354
67.4k
    if( mnMaterial.has_value() )
355
3
    {
356
3
        pSeq[nSize].Name = "prstMaterial";
357
3
        pSeq[nSize].Value <<= getPresetMaterialTypeString( *mnMaterial );
358
3
        nSize++;
359
3
    }
360
67.4k
    if( maTopBevelProperties.has_value() )
361
0
    {
362
0
        pSeq[nSize].Name = "bevelT";
363
0
        pSeq[nSize].Value <<= getBevelAttributes( *maTopBevelProperties );
364
0
        nSize++;
365
0
    }
366
67.4k
    if( maBottomBevelProperties.has_value() )
367
0
    {
368
0
        pSeq[nSize].Name = "bevelB";
369
0
        pSeq[nSize].Value <<= getBevelAttributes( *maBottomBevelProperties );
370
0
        nSize++;
371
0
    }
372
67.4k
    if( maExtrusionColor.isUsed() )
373
3
    {
374
3
        pSeq[nSize].Name = "extrusionClr";
375
3
        pSeq[nSize].Value <<= getColorAttributes( maExtrusionColor, rGraphicHelper, rPhClr );
376
3
        nSize++;
377
3
    }
378
67.4k
    if( maContourColor.isUsed() )
379
0
    {
380
0
        pSeq[nSize].Name = "contourClr";
381
0
        pSeq[nSize].Value <<= getColorAttributes( maContourColor, rGraphicHelper, rPhClr );
382
0
        nSize++;
383
0
    }
384
67.4k
    aSeq.realloc( nSize );
385
67.4k
    return aSeq;
386
67.4k
}
387
388
} // namespace oox
389
390
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */