Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/customshapepresetdata.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
10
#include <config_folders.h>
11
#include <rtl/bootstrap.hxx>
12
#include <sal/log.hxx>
13
#include <tools/stream.hxx>
14
#include <comphelper/sequence.hxx>
15
16
#include <drawingml/customshapeproperties.hxx>
17
#include <oox/token/properties.hxx>
18
#include <oox/token/tokenmap.hxx>
19
#include <com/sun/star/awt/Rectangle.hpp>
20
#include <com/sun/star/beans/PropertyValue.hpp>
21
#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
22
#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
23
#include <o3tl/string_view.hxx>
24
25
using namespace ::com::sun::star;
26
27
namespace
28
{
29
// Parses a string like: Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj"
30
void lcl_parseAdjustmentValue(
31
    std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues,
32
    std::string_view rValue)
33
0
{
34
0
    sal_Int32 nIndex = 0;
35
0
    drawing::EnhancedCustomShapeAdjustmentValue aAdjustmentValue;
36
0
    do
37
0
    {
38
0
        std::string_view aToken(o3tl::trim(o3tl::getToken(rValue, 0, ',', nIndex)));
39
0
        static const char aNamePrefix[] = "Name = \"";
40
0
        static const char aValuePrefix[] = "Value = (any) { (long) ";
41
0
        if (o3tl::starts_with(aToken, aNamePrefix))
42
0
        {
43
0
            std::string_view aName = aToken.substr(
44
0
                strlen(aNamePrefix), aToken.size() - strlen(aNamePrefix) - strlen("\""));
45
0
            aAdjustmentValue.Name = OUString::fromUtf8(aName);
46
0
        }
47
0
        else if (o3tl::starts_with(aToken, aValuePrefix))
48
0
        {
49
0
            std::string_view aValue = aToken.substr(
50
0
                strlen(aValuePrefix), aToken.size() - strlen(aValuePrefix) - strlen(" }"));
51
0
            aAdjustmentValue.Value <<= o3tl::toInt32(aValue);
52
0
        }
53
0
        else if (!o3tl::starts_with(aToken, "State = "))
54
0
            SAL_WARN("oox", "lcl_parseAdjustmentValue: unexpected prefix: " << aToken);
55
0
    } while (nIndex >= 0);
56
0
    rAdjustmentValues.push_back(aAdjustmentValue);
57
0
}
58
59
// Parses a string like: { Value = (any) { (long) 19098 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE, Name = "adj" }, { Value = ..., State = ..., Name = ... }
60
void lcl_parseAdjustmentValues(
61
    std::vector<drawing::EnhancedCustomShapeAdjustmentValue>& rAdjustmentValues,
62
    std::string_view rValue)
63
0
{
64
0
    sal_Int32 nLevel = 0;
65
0
    sal_Int32 nStart = 0;
66
0
    for (size_t i = 0; i < rValue.size(); ++i)
67
0
    {
68
0
        if (rValue[i] == '{')
69
0
        {
70
0
            if (!nLevel)
71
0
                nStart = i;
72
0
            nLevel++;
73
0
        }
74
0
        else if (rValue[i] == '}')
75
0
        {
76
0
            nLevel--;
77
0
            if (!nLevel)
78
0
            {
79
0
                lcl_parseAdjustmentValue(
80
0
                    rAdjustmentValues,
81
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },")));
82
0
            }
83
0
        }
84
0
    }
85
0
}
86
87
drawing::EnhancedCustomShapeParameterPair
88
lcl_parseEnhancedCustomShapeParameterPair(std::string_view rValue)
89
0
{
90
0
    drawing::EnhancedCustomShapeParameterPair aPair;
91
    // We expect the following here: First.Value, First.Type, Second.Value, Second.Type
92
0
    static const char aExpectedFVPrefix[]
93
0
        = "First = (com.sun.star.drawing.EnhancedCustomShapeParameter) { Value = (any) { (long) ";
94
0
    assert(o3tl::starts_with(rValue, aExpectedFVPrefix));
95
0
    sal_Int32 nIndex = strlen(aExpectedFVPrefix);
96
0
    aPair.First.Value
97
0
        <<= static_cast<sal_uInt32>(o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex)));
98
99
0
    static const char aExpectedFTPrefix[] = ", Type = (short) ";
100
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedFTPrefix));
101
0
    nIndex += strlen(aExpectedFTPrefix);
102
0
    aPair.First.Type
103
0
        = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex)));
104
105
0
    static const char aExpectedSVPrefix[] = ", Second = "
106
0
                                            "(com.sun.star.drawing.EnhancedCustomShapeParameter) { "
107
0
                                            "Value = (any) { (long) ";
108
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedSVPrefix));
109
0
    nIndex += strlen(aExpectedSVPrefix);
110
0
    aPair.Second.Value
111
0
        <<= static_cast<sal_uInt32>(o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex)));
112
113
0
    static const char aExpectedSTPrefix[] = ", Type = (short) ";
114
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedSTPrefix));
115
0
    nIndex += strlen(aExpectedSTPrefix);
116
0
    aPair.Second.Type
117
0
        = static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex)));
118
0
    return aPair;
119
0
}
120
121
drawing::EnhancedCustomShapeSegment lcl_parseEnhancedCustomShapeSegment(std::string_view rValue)
122
0
{
123
0
    drawing::EnhancedCustomShapeSegment aSegment;
124
    // We expect the following here: Command, Count
125
0
    static const char aExpectedCommandPrefix[] = "Command = (short) ";
126
0
    assert(o3tl::starts_with(rValue, aExpectedCommandPrefix));
127
0
    sal_Int32 nIndex = strlen(aExpectedCommandPrefix);
128
0
    aSegment.Command
129
0
        = static_cast<sal_Int16>(o3tl::toInt32(o3tl::getToken(rValue, 0, ',', nIndex)));
130
131
0
    static const char aExpectedCountPrefix[] = " Count = (short) ";
132
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedCountPrefix));
133
0
    nIndex += strlen(aExpectedCountPrefix);
134
0
    aSegment.Count = static_cast<sal_Int16>(o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex)));
135
0
    return aSegment;
136
0
}
137
138
awt::Rectangle lcl_parseRectangle(std::string_view rValue)
139
0
{
140
0
    awt::Rectangle aRectangle;
141
    // We expect the following here: X, Y, Width, Height
142
0
    static const char aExpectedXPrefix[] = "X = (long) ";
143
0
    assert(o3tl::starts_with(rValue, aExpectedXPrefix));
144
0
    sal_Int32 nIndex = strlen(aExpectedXPrefix);
145
0
    aRectangle.X = o3tl::toInt32(o3tl::getToken(rValue, 0, ',', nIndex));
146
147
0
    static const char aExpectedYPrefix[] = " Y = (long) ";
148
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedYPrefix));
149
0
    nIndex += strlen(aExpectedYPrefix);
150
0
    aRectangle.Y = o3tl::toInt32(o3tl::getToken(rValue, 0, ',', nIndex));
151
152
0
    static const char aExpectedWidthPrefix[] = " Width = (long) ";
153
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedWidthPrefix));
154
0
    nIndex += strlen(aExpectedWidthPrefix);
155
0
    aRectangle.Width = o3tl::toInt32(o3tl::getToken(rValue, 0, ',', nIndex));
156
157
0
    static const char aExpectedHeightPrefix[] = " Height = (long) ";
158
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedHeightPrefix));
159
0
    nIndex += strlen(aExpectedHeightPrefix);
160
0
    aRectangle.Height = o3tl::toInt32(rValue.substr(nIndex));
161
162
0
    return aRectangle;
163
0
}
164
165
sal_Int32 lcl_parseDirection(std::string_view rValue)
166
0
{
167
0
    sal_Int32 aDirection;
168
    // We expect the following here: Direction
169
0
    static const char aExpectedWidthPrefix[] = "Dir = (long) ";
170
0
    assert(o3tl::starts_with(rValue, aExpectedWidthPrefix));
171
0
    sal_Int32 nIndex = strlen(aExpectedWidthPrefix);
172
0
    aDirection = o3tl::toInt32(rValue.substr(nIndex));
173
174
0
    return aDirection;
175
0
}
176
177
awt::Size lcl_parseSize(std::string_view rValue)
178
0
{
179
0
    awt::Size aSize;
180
    // We expect the following here: Width, Height
181
0
    static const char aExpectedWidthPrefix[] = "Width = (long) ";
182
0
    assert(o3tl::starts_with(rValue, aExpectedWidthPrefix));
183
0
    sal_Int32 nIndex = strlen(aExpectedWidthPrefix);
184
0
    aSize.Width = o3tl::toInt32(o3tl::getToken(rValue, 0, ',', nIndex));
185
186
0
    static const char aExpectedHeightPrefix[] = " Height = (long) ";
187
0
    assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedHeightPrefix));
188
0
    nIndex += strlen(aExpectedHeightPrefix);
189
0
    aSize.Height = o3tl::toInt32(rValue.substr(nIndex));
190
191
0
    return aSize;
192
0
}
193
194
drawing::EnhancedCustomShapeTextFrame lcl_parseEnhancedCustomShapeTextFrame(std::string_view rValue)
195
0
{
196
0
    drawing::EnhancedCustomShapeTextFrame aTextFrame;
197
0
    sal_Int32 nLevel = 0;
198
0
    bool bIgnore = false;
199
0
    sal_Int32 nStart = 0;
200
0
    for (size_t i = 0; i < rValue.size(); ++i)
201
0
    {
202
0
        if (rValue[i] == '{')
203
0
        {
204
0
            if (!nLevel)
205
0
                bIgnore = true;
206
0
            nLevel++;
207
0
        }
208
0
        else if (rValue[i] == '}')
209
0
        {
210
0
            nLevel--;
211
0
            if (!nLevel)
212
0
                bIgnore = false;
213
0
        }
214
0
        else if (rValue[i] == ',' && !bIgnore)
215
0
        {
216
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
217
0
            static const char aExpectedPrefix[]
218
0
                = "TopLeft = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
219
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
220
0
            {
221
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
222
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" }"));
223
0
                aTextFrame.TopLeft = lcl_parseEnhancedCustomShapeParameterPair(aToken);
224
0
            }
225
0
            else
226
0
                SAL_WARN("oox",
227
0
                         "lcl_parseEnhancedCustomShapeTextFrame: unexpected token: " << aToken);
228
0
            nStart = i + strlen(", ");
229
0
        }
230
0
    }
231
232
0
    std::string_view aToken = rValue.substr(nStart);
233
0
    static const char aExpectedPrefix[]
234
0
        = "BottomRight = (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
235
0
    if (o3tl::starts_with(aToken, aExpectedPrefix))
236
0
    {
237
0
        aToken = aToken.substr(strlen(aExpectedPrefix),
238
0
                               aToken.size() - strlen(aExpectedPrefix) - strlen(" }"));
239
0
        aTextFrame.BottomRight = lcl_parseEnhancedCustomShapeParameterPair(aToken);
240
0
    }
241
0
    else
242
0
        SAL_WARN("oox",
243
0
                 "lcl_parseEnhancedCustomShapeTextFrame: unexpected token at the end: " << aToken);
244
245
0
    return aTextFrame;
246
0
}
247
248
// Parses a string like: Name = "Position", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
249
// where "{ ... }" may contain "," as well.
250
void lcl_parseHandlePosition(std::vector<beans::PropertyValue>& rHandle, std::string_view rValue)
251
0
{
252
0
    sal_Int32 nLevel = 0;
253
0
    bool bIgnore = false;
254
0
    sal_Int32 nStart = 0;
255
0
    for (size_t i = 0; i < rValue.size(); ++i)
256
0
    {
257
0
        if (rValue[i] == '{')
258
0
        {
259
0
            if (!nLevel)
260
0
                bIgnore = true;
261
0
            nLevel++;
262
0
        }
263
0
        else if (rValue[i] == '}')
264
0
        {
265
0
            nLevel--;
266
0
            if (!nLevel)
267
0
                bIgnore = false;
268
0
        }
269
0
        else if (rValue[i] == ',' && !bIgnore)
270
0
        {
271
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
272
0
            static const char aExpectedPrefix[]
273
0
                = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
274
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
275
0
            {
276
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
277
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
278
279
0
                beans::PropertyValue aPropertyValue;
280
0
                aPropertyValue.Name = "Position";
281
0
                aPropertyValue.Value <<= lcl_parseEnhancedCustomShapeParameterPair(aToken);
282
0
                rHandle.push_back(aPropertyValue);
283
0
            }
284
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
285
0
                SAL_WARN("oox", "lcl_parseHandlePosition: unexpected token: " << aToken);
286
0
            nStart = i + strlen(", ");
287
0
        }
288
0
    }
289
0
}
290
291
// Parses a string like: Name = "RangeYMaximum", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
292
// where "{ ... }" may contain "," as well.
293
void lcl_parseHandleRange(std::vector<beans::PropertyValue>& rHandle, std::string_view rValue,
294
                          const OUString& rName)
295
0
{
296
0
    sal_Int32 nLevel = 0;
297
0
    bool bIgnore = false;
298
0
    sal_Int32 nStart = 0;
299
0
    for (size_t i = 0; i < rValue.size(); ++i)
300
0
    {
301
0
        if (rValue[i] == '{')
302
0
        {
303
0
            if (!nLevel)
304
0
                bIgnore = true;
305
0
            nLevel++;
306
0
        }
307
0
        else if (rValue[i] == '}')
308
0
        {
309
0
            nLevel--;
310
0
            if (!nLevel)
311
0
                bIgnore = false;
312
0
        }
313
0
        else if (rValue[i] == ',' && !bIgnore)
314
0
        {
315
0
            static const char aExpectedPrefix[]
316
0
                = "Value = (any) { (com.sun.star.drawing.EnhancedCustomShapeParameter) { ";
317
0
            if (o3tl::starts_with(rValue.substr(nStart), aExpectedPrefix))
318
0
            {
319
0
                drawing::EnhancedCustomShapeParameter aParameter;
320
0
                sal_Int32 nIndex{ nStart + static_cast<sal_Int32>(strlen(aExpectedPrefix)) };
321
                // We expect the following here: Value and Type
322
0
                static const char aExpectedVPrefix[] = "Value = (any) { (long) ";
323
0
                assert(o3tl::starts_with(rValue.substr(nIndex), aExpectedVPrefix));
324
0
                nIndex += strlen(aExpectedVPrefix);
325
0
                aParameter.Value <<= o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex));
326
327
0
                static const char aExpectedTPrefix[] = ", Type = (short) ";
328
0
                assert(nIndex >= 0 && o3tl::starts_with(rValue.substr(nIndex), aExpectedTPrefix));
329
0
                nIndex += strlen(aExpectedTPrefix);
330
0
                aParameter.Type
331
0
                    = static_cast<sal_Int16>(o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex)));
332
333
0
                beans::PropertyValue aPropertyValue;
334
0
                aPropertyValue.Name = rName;
335
0
                aPropertyValue.Value <<= aParameter;
336
0
                rHandle.push_back(aPropertyValue);
337
0
            }
338
0
            else if (!o3tl::starts_with(rValue.substr(nStart), "Name =")
339
0
                     && !o3tl::starts_with(rValue.substr(nStart), "Handle ="))
340
0
                SAL_WARN("oox", "lcl_parseHandleRange: unexpected token: "
341
0
                                    << rValue.substr(nStart, i - nStart));
342
0
            nStart = i + strlen(", ");
343
0
        }
344
0
    }
345
0
}
346
347
// Parses a string like: Name = "RefY", Handle = (long) 0, Value = (any) { (long) 0 }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
348
void lcl_parseHandleRef(std::vector<beans::PropertyValue>& rHandle, std::string_view rValue,
349
                        const OUString& rName)
350
0
{
351
0
    static constexpr std::string_view aPrefix = "\", Handle = (long) 0, Value = (any) { (long) ";
352
0
    const sal_Int32 nStart = SAL_N_ELEMENTS("Name = \"") - 1 + rName.getLength();
353
354
0
    if (rValue.substr(nStart, aPrefix.size()) == aPrefix)
355
0
    {
356
0
        sal_Int32 nIndex = nStart + aPrefix.size();
357
0
        beans::PropertyValue aPropertyValue;
358
0
        aPropertyValue.Name = rName;
359
        // We only expect a Value here
360
0
        aPropertyValue.Value <<= o3tl::toInt32(o3tl::getToken(rValue, 0, '}', nIndex));
361
0
        rHandle.push_back(aPropertyValue);
362
0
    }
363
0
    else
364
0
        SAL_WARN("oox", "lcl_parseHandleRef: unexpected value: " << rValue);
365
0
}
366
367
uno::Sequence<beans::PropertyValue> lcl_parseHandle(std::string_view rValue)
368
0
{
369
0
    std::vector<beans::PropertyValue> aRet;
370
0
    sal_Int32 nLevel = 0;
371
0
    sal_Int32 nStart = 0;
372
0
    for (size_t i = 0; i < rValue.size(); ++i)
373
0
    {
374
0
        if (rValue[i] == '{')
375
0
        {
376
0
            if (!nLevel)
377
0
                nStart = i;
378
0
            nLevel++;
379
0
        }
380
0
        else if (rValue[i] == '}')
381
0
        {
382
0
            nLevel--;
383
0
            if (!nLevel)
384
0
            {
385
0
                std::string_view aToken
386
0
                    = rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"));
387
0
                if (o3tl::starts_with(aToken, "Name = \"Position\""))
388
0
                    lcl_parseHandlePosition(aRet, aToken);
389
0
                else if (o3tl::starts_with(aToken, "Name = \"RangeXMaximum\""))
390
0
                    lcl_parseHandleRange(aRet, aToken, u"RangeXMaximum"_ustr);
391
0
                else if (o3tl::starts_with(aToken, "Name = \"RangeXMinimum\""))
392
0
                    lcl_parseHandleRange(aRet, aToken, u"RangeXMinimum"_ustr);
393
0
                else if (o3tl::starts_with(aToken, "Name = \"RangeYMaximum\""))
394
0
                    lcl_parseHandleRange(aRet, aToken, u"RangeYMaximum"_ustr);
395
0
                else if (o3tl::starts_with(aToken, "Name = \"RangeYMinimum\""))
396
0
                    lcl_parseHandleRange(aRet, aToken, u"RangeYMinimum"_ustr);
397
0
                else if (o3tl::starts_with(aToken, "Name = \"RadiusRangeMaximum\""))
398
0
                    lcl_parseHandleRange(aRet, aToken, u"RadiusRangeMaximum"_ustr);
399
0
                else if (o3tl::starts_with(aToken, "Name = \"RadiusRangeMinimum\""))
400
0
                    lcl_parseHandleRange(aRet, aToken, u"RadiusRangeMinimum"_ustr);
401
0
                else if (o3tl::starts_with(aToken, "Name = \"RefX\""))
402
0
                    lcl_parseHandleRef(aRet, aToken, u"RefX"_ustr);
403
0
                else if (o3tl::starts_with(aToken, "Name = \"RefY\""))
404
0
                    lcl_parseHandleRef(aRet, aToken, u"RefY"_ustr);
405
0
                else if (o3tl::starts_with(aToken, "Name = \"RefR\""))
406
0
                    lcl_parseHandleRef(aRet, aToken, u"RefR"_ustr);
407
0
                else if (o3tl::starts_with(aToken, "Name = \"RefAngle\""))
408
0
                    lcl_parseHandleRef(aRet, aToken, u"RefAngle"_ustr);
409
0
                else
410
0
                    SAL_WARN("oox", "lcl_parseHandle: unexpected token: " << aToken);
411
0
            }
412
0
        }
413
0
    }
414
0
    return comphelper::containerToSequence(aRet);
415
0
}
416
417
void lcl_parseHandles(std::vector<uno::Sequence<beans::PropertyValue>>& rHandles,
418
                      std::string_view rValue)
419
0
{
420
0
    sal_Int32 nLevel = 0;
421
0
    sal_Int32 nStart = 0;
422
0
    for (size_t i = 0; i < rValue.size(); ++i)
423
0
    {
424
0
        if (rValue[i] == '{')
425
0
        {
426
0
            if (!nLevel)
427
0
                nStart = i;
428
0
            nLevel++;
429
0
        }
430
0
        else if (rValue[i] == '}')
431
0
        {
432
0
            nLevel--;
433
0
            if (!nLevel)
434
0
            {
435
0
                uno::Sequence<beans::PropertyValue> aHandle = lcl_parseHandle(
436
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },")));
437
0
                rHandles.push_back(aHandle);
438
0
            }
439
0
        }
440
0
    }
441
0
}
442
443
void lcl_parseEquations(std::vector<OUString>& rEquations, std::string_view rValue)
444
0
{
445
0
    bool bInString = false;
446
0
    sal_Int32 nStart = 0;
447
0
    for (size_t i = 0; i < rValue.size(); ++i)
448
0
    {
449
0
        if (rValue[i] == '"' && !bInString)
450
0
        {
451
0
            nStart = i;
452
0
            bInString = true;
453
0
        }
454
0
        else if (rValue[i] == '"' && bInString)
455
0
        {
456
0
            bInString = false;
457
0
            rEquations.push_back(OUString::fromUtf8(
458
0
                rValue.substr(nStart + strlen("\""), i - nStart - strlen("\""))));
459
0
        }
460
0
    }
461
0
}
462
463
void lcl_parsePathCoordinateValues(std::vector<beans::PropertyValue>& rPath,
464
                                   std::string_view rValue)
465
0
{
466
0
    std::vector<drawing::EnhancedCustomShapeParameterPair> aPairs;
467
0
    sal_Int32 nLevel = 0;
468
0
    sal_Int32 nStart = 0;
469
0
    for (size_t i = 0; i < rValue.size(); ++i)
470
0
    {
471
0
        if (rValue[i] == '{')
472
0
        {
473
0
            if (!nLevel)
474
0
                nStart = i;
475
0
            nLevel++;
476
0
        }
477
0
        else if (rValue[i] == '}')
478
0
        {
479
0
            nLevel--;
480
0
            if (!nLevel)
481
0
                aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(
482
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"))));
483
0
        }
484
0
    }
485
486
0
    beans::PropertyValue aPropertyValue;
487
0
    aPropertyValue.Name = "Coordinates";
488
0
    aPropertyValue.Value <<= comphelper::containerToSequence(aPairs);
489
0
    rPath.push_back(aPropertyValue);
490
0
}
491
492
// Parses a string like: Name = "Coordinates", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
493
// where "{ ... }" may contain "," as well.
494
void lcl_parsePathCoordinates(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
495
0
{
496
0
    sal_Int32 nLevel = 0;
497
0
    bool bIgnore = false;
498
0
    sal_Int32 nStart = 0;
499
0
    for (size_t i = 0; i < rValue.size(); ++i)
500
0
    {
501
0
        if (rValue[i] == '{')
502
0
        {
503
0
            if (!nLevel)
504
0
                bIgnore = true;
505
0
            nLevel++;
506
0
        }
507
0
        else if (rValue[i] == '}')
508
0
        {
509
0
            nLevel--;
510
0
            if (!nLevel)
511
0
                bIgnore = false;
512
0
        }
513
0
        else if (rValue[i] == ',' && !bIgnore)
514
0
        {
515
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
516
0
            static const char aExpectedPrefix[]
517
0
                = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
518
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
519
0
            {
520
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
521
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
522
0
                lcl_parsePathCoordinateValues(rPath, aToken);
523
0
            }
524
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
525
0
                SAL_WARN("oox", "lcl_parsePathCoordinates: unexpected token: " << aToken);
526
0
            nStart = i + strlen(", ");
527
0
        }
528
0
    }
529
0
}
530
531
void lcl_parsePathGluePointsValues(std::vector<beans::PropertyValue>& rPath,
532
                                   std::string_view rValue)
533
0
{
534
0
    std::vector<drawing::EnhancedCustomShapeParameterPair> aPairs;
535
0
    sal_Int32 nLevel = 0;
536
0
    sal_Int32 nStart = 0;
537
0
    for (size_t i = 0; i < rValue.size(); ++i)
538
0
    {
539
0
        if (rValue[i] == '{')
540
0
        {
541
0
            if (!nLevel)
542
0
                nStart = i;
543
0
            nLevel++;
544
0
        }
545
0
        else if (rValue[i] == '}')
546
0
        {
547
0
            nLevel--;
548
0
            if (!nLevel)
549
0
                aPairs.push_back(lcl_parseEnhancedCustomShapeParameterPair(
550
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"))));
551
0
        }
552
0
    }
553
554
0
    beans::PropertyValue aPropertyValue;
555
0
    aPropertyValue.Name = "GluePoints";
556
0
    aPropertyValue.Value <<= comphelper::containerToSequence(aPairs);
557
0
    rPath.push_back(aPropertyValue);
558
0
}
559
560
void lcl_parsePathGluePoints(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
561
0
{
562
0
    sal_Int32 nLevel = 0;
563
0
    bool bIgnore = false;
564
0
    sal_Int32 nStart = 0;
565
0
    for (size_t i = 0; i < rValue.size(); ++i)
566
0
    {
567
0
        if (rValue[i] == '{')
568
0
        {
569
0
            if (!nLevel)
570
0
                bIgnore = true;
571
0
            nLevel++;
572
0
        }
573
0
        else if (rValue[i] == '}')
574
0
        {
575
0
            nLevel--;
576
0
            if (!nLevel)
577
0
                bIgnore = false;
578
0
        }
579
0
        else if (rValue[i] == ',' && !bIgnore)
580
0
        {
581
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
582
0
            static const char aExpectedPrefix[]
583
0
                = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeParameterPair) { ";
584
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
585
0
            {
586
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
587
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
588
0
                lcl_parsePathGluePointsValues(rPath, aToken);
589
0
            }
590
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
591
0
                SAL_WARN("oox", "lcl_parsePathGluePoints: unexpected token: " << aToken);
592
0
            nStart = i + strlen(", ");
593
0
        }
594
0
    }
595
0
}
596
597
void lcl_parsePathGluePointLeavingDirectionsValues(std::vector<beans::PropertyValue>& rPath,
598
                                                   std::string_view rValue)
599
0
{
600
0
    std::vector<double> aDirection;
601
0
    sal_Int32 nLevel = 0;
602
0
    sal_Int32 nStart = 0;
603
0
    for (size_t i = 0; i < rValue.size(); ++i)
604
0
    {
605
0
        if (rValue[i] == '{')
606
0
        {
607
0
            if (!nLevel)
608
0
                nStart = i;
609
0
            nLevel++;
610
0
        }
611
0
        else if (rValue[i] == '}')
612
0
        {
613
0
            nLevel--;
614
0
            if (!nLevel)
615
0
                aDirection.push_back(lcl_parseDirection(
616
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"))));
617
0
        }
618
0
    }
619
620
0
    beans::PropertyValue aPropertyValue;
621
0
    aPropertyValue.Name = "GluePointLeavingDirections";
622
0
    aPropertyValue.Value <<= comphelper::containerToSequence(aDirection);
623
0
    rPath.push_back(aPropertyValue);
624
0
}
625
626
void lcl_parsePathGluePointLeavingDirections(std::vector<beans::PropertyValue>& rPath,
627
                                             std::string_view rValue)
628
0
{
629
0
    sal_Int32 nLevel = 0;
630
0
    bool bIgnore = false;
631
0
    sal_Int32 nStart = 0;
632
0
    for (size_t i = 0; i < rValue.size(); ++i)
633
0
    {
634
0
        if (rValue[i] == '{')
635
0
        {
636
0
            if (!nLevel)
637
0
                bIgnore = true;
638
0
            nLevel++;
639
0
        }
640
0
        else if (rValue[i] == '}')
641
0
        {
642
0
            nLevel--;
643
0
            if (!nLevel)
644
0
                bIgnore = false;
645
0
        }
646
0
        else if (rValue[i] == ',' && !bIgnore)
647
0
        {
648
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
649
0
            static const char aExpectedPrefix[] = "Value = (any) { ([]long) { ";
650
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
651
0
            {
652
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
653
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
654
0
                lcl_parsePathGluePointLeavingDirectionsValues(rPath, aToken);
655
0
            }
656
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
657
0
                SAL_WARN("oox",
658
0
                         "lcl_parsePathGluePointLeavingDirections: unexpected token: " << aToken);
659
0
            nStart = i + strlen(", ");
660
0
        }
661
0
    }
662
0
}
663
664
void lcl_parsePathSegmentValues(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
665
0
{
666
0
    std::vector<drawing::EnhancedCustomShapeSegment> aSegments;
667
0
    sal_Int32 nLevel = 0;
668
0
    sal_Int32 nStart = 0;
669
0
    for (size_t i = 0; i < rValue.size(); ++i)
670
0
    {
671
0
        if (rValue[i] == '{')
672
0
        {
673
0
            if (!nLevel)
674
0
                nStart = i;
675
0
            nLevel++;
676
0
        }
677
0
        else if (rValue[i] == '}')
678
0
        {
679
0
            nLevel--;
680
0
            if (!nLevel)
681
0
                aSegments.push_back(lcl_parseEnhancedCustomShapeSegment(
682
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"))));
683
0
        }
684
0
    }
685
686
0
    beans::PropertyValue aPropertyValue;
687
0
    aPropertyValue.Name = "Segments";
688
0
    aPropertyValue.Value <<= comphelper::containerToSequence(aSegments);
689
0
    rPath.push_back(aPropertyValue);
690
0
}
691
692
// Parses a string like: Name = "Segments", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
693
// where "{ ... }" may contain "," as well.
694
void lcl_parsePathSegments(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
695
0
{
696
0
    sal_Int32 nLevel = 0;
697
0
    bool bIgnore = false;
698
0
    sal_Int32 nStart = 0;
699
0
    for (size_t i = 0; i < rValue.size(); ++i)
700
0
    {
701
0
        if (rValue[i] == '{')
702
0
        {
703
0
            if (!nLevel)
704
0
                bIgnore = true;
705
0
            nLevel++;
706
0
        }
707
0
        else if (rValue[i] == '}')
708
0
        {
709
0
            nLevel--;
710
0
            if (!nLevel)
711
0
                bIgnore = false;
712
0
        }
713
0
        else if (rValue[i] == ',' && !bIgnore)
714
0
        {
715
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
716
0
            static const char aExpectedPrefix[]
717
0
                = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeSegment) { ";
718
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
719
0
            {
720
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
721
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
722
0
                lcl_parsePathSegmentValues(rPath, aToken);
723
0
            }
724
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
725
0
                SAL_WARN("oox", "lcl_parsePathSegments: unexpected token: " << aToken);
726
0
            nStart = i + strlen(", ");
727
0
        }
728
0
    }
729
0
}
730
731
void lcl_parsePathTextFrameValues(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
732
0
{
733
0
    std::vector<drawing::EnhancedCustomShapeTextFrame> aTextFrames;
734
0
    sal_Int32 nLevel = 0;
735
0
    sal_Int32 nStart = 0;
736
0
    for (size_t i = 0; i < rValue.size(); ++i)
737
0
    {
738
0
        if (rValue[i] == '{')
739
0
        {
740
0
            if (!nLevel)
741
0
                nStart = i;
742
0
            nLevel++;
743
0
        }
744
0
        else if (rValue[i] == '}')
745
0
        {
746
0
            nLevel--;
747
0
            if (!nLevel)
748
0
                aTextFrames.push_back(lcl_parseEnhancedCustomShapeTextFrame(
749
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"))));
750
0
        }
751
0
    }
752
753
0
    beans::PropertyValue aPropertyValue;
754
0
    aPropertyValue.Name = "TextFrames";
755
0
    aPropertyValue.Value <<= comphelper::containerToSequence(aTextFrames);
756
0
    rPath.push_back(aPropertyValue);
757
0
}
758
759
// Parses a string like: Name = "TextFrames", Handle = (long) 0, Value = (any) { ... }, State = (com.sun.star.beans.PropertyState) DIRECT_VALUE
760
// where "{ ... }" may contain "," as well.
761
void lcl_parsePathTextFrames(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
762
0
{
763
0
    sal_Int32 nLevel = 0;
764
0
    bool bIgnore = false;
765
0
    sal_Int32 nStart = 0;
766
0
    for (size_t i = 0; i < rValue.size(); ++i)
767
0
    {
768
0
        if (rValue[i] == '{')
769
0
        {
770
0
            if (!nLevel)
771
0
                bIgnore = true;
772
0
            nLevel++;
773
0
        }
774
0
        else if (rValue[i] == '}')
775
0
        {
776
0
            nLevel--;
777
0
            if (!nLevel)
778
0
                bIgnore = false;
779
0
        }
780
0
        else if (rValue[i] == ',' && !bIgnore)
781
0
        {
782
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
783
0
            static const char aExpectedPrefix[]
784
0
                = "Value = (any) { ([]com.sun.star.drawing.EnhancedCustomShapeTextFrame) { ";
785
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
786
0
            {
787
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
788
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
789
0
                lcl_parsePathTextFrameValues(rPath, aToken);
790
0
            }
791
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
792
0
                SAL_WARN("oox", "lcl_parsePathTextFrames: unexpected token: " << aToken);
793
0
            nStart = i + strlen(", ");
794
0
        }
795
0
    }
796
0
}
797
798
void lcl_parsePathSubViewSizeValues(std::vector<beans::PropertyValue>& rPath,
799
                                    std::string_view rValue)
800
0
{
801
0
    std::vector<awt::Size> aSizes;
802
0
    sal_Int32 nLevel = 0;
803
0
    sal_Int32 nStart = 0;
804
0
    for (size_t i = 0; i < rValue.size(); ++i)
805
0
    {
806
0
        if (rValue[i] == '{')
807
0
        {
808
0
            if (!nLevel)
809
0
                nStart = i;
810
0
            nLevel++;
811
0
        }
812
0
        else if (rValue[i] == '}')
813
0
        {
814
0
            nLevel--;
815
0
            if (!nLevel)
816
0
                aSizes.push_back(lcl_parseSize(
817
0
                    rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"))));
818
0
        }
819
0
    }
820
821
0
    beans::PropertyValue aPropertyValue;
822
0
    aPropertyValue.Name = "SubViewSize";
823
0
    aPropertyValue.Value <<= comphelper::containerToSequence(aSizes);
824
0
    rPath.push_back(aPropertyValue);
825
0
}
826
827
void lcl_parsePathSubViewSize(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
828
0
{
829
0
    sal_Int32 nLevel = 0;
830
0
    bool bIgnore = false;
831
0
    sal_Int32 nStart = 0;
832
0
    for (size_t i = 0; i < rValue.size(); ++i)
833
0
    {
834
0
        if (rValue[i] == '{')
835
0
        {
836
0
            if (!nLevel)
837
0
                bIgnore = true;
838
0
            nLevel++;
839
0
        }
840
0
        else if (rValue[i] == '}')
841
0
        {
842
0
            nLevel--;
843
0
            if (!nLevel)
844
0
                bIgnore = false;
845
0
        }
846
0
        else if (rValue[i] == ',' && !bIgnore)
847
0
        {
848
0
            std::string_view aToken = rValue.substr(nStart, i - nStart);
849
0
            static const char aExpectedPrefix[] = "Value = (any) { ([]com.sun.star.awt.Size) { ";
850
0
            if (o3tl::starts_with(aToken, aExpectedPrefix))
851
0
            {
852
0
                aToken = aToken.substr(strlen(aExpectedPrefix),
853
0
                                       aToken.size() - strlen(aExpectedPrefix) - strlen(" } }"));
854
0
                lcl_parsePathSubViewSizeValues(rPath, aToken);
855
0
            }
856
0
            else if (!o3tl::starts_with(aToken, "Name =") && !o3tl::starts_with(aToken, "Handle ="))
857
0
                SAL_WARN("oox", "lcl_parsePathSubViewSize: unexpected token: " << aToken);
858
0
            nStart = i + strlen(", ");
859
0
        }
860
0
    }
861
0
}
862
863
void lcl_parsePath(std::vector<beans::PropertyValue>& rPath, std::string_view rValue)
864
0
{
865
0
    sal_Int32 nLevel = 0;
866
0
    sal_Int32 nStart = 0;
867
0
    for (size_t i = 0; i < rValue.size(); ++i)
868
0
    {
869
0
        if (rValue[i] == '{')
870
0
        {
871
0
            if (!nLevel)
872
0
                nStart = i;
873
0
            nLevel++;
874
0
        }
875
0
        else if (rValue[i] == '}')
876
0
        {
877
0
            nLevel--;
878
0
            if (!nLevel)
879
0
            {
880
0
                std::string_view aToken
881
0
                    = rValue.substr(nStart + strlen("{ "), i - nStart - strlen(" },"));
882
0
                if (o3tl::starts_with(aToken, "Name = \"Coordinates\""))
883
0
                    lcl_parsePathCoordinates(rPath, aToken);
884
0
                else if (o3tl::starts_with(aToken, "Name = \"GluePoints\""))
885
0
                    lcl_parsePathGluePoints(rPath, aToken);
886
0
                else if (o3tl::starts_with(aToken, "Name = \"GluePointLeavingDirections\""))
887
0
                    lcl_parsePathGluePointLeavingDirections(rPath, aToken);
888
0
                else if (o3tl::starts_with(aToken, "Name = \"Segments\""))
889
0
                    lcl_parsePathSegments(rPath, aToken);
890
0
                else if (o3tl::starts_with(aToken, "Name = \"TextFrames\""))
891
0
                    lcl_parsePathTextFrames(rPath, aToken);
892
0
                else if (o3tl::starts_with(aToken, "Name = \"SubViewSize\""))
893
0
                    lcl_parsePathSubViewSize(rPath, aToken);
894
0
                else
895
0
                    SAL_WARN("oox", "lcl_parsePath: unexpected token: " << aToken);
896
0
            }
897
0
        }
898
0
    }
899
0
}
900
}
901
902
namespace oox::drawingml
903
{
904
void CustomShapeProperties::initializePresetDataMap()
905
3
{
906
3
    OUString aPath(u"$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/oox-drawingml-cs-presets"_ustr);
907
3
    rtl::Bootstrap::expandMacros(aPath);
908
3
    SvFileStream aStream(aPath, StreamMode::READ);
909
3
    if (aStream.GetError() != ERRCODE_NONE)
910
3
        SAL_WARN("oox", "failed to open oox-drawingml-cs-presets");
911
3
    OStringBuffer aLine;
912
3
    OUString aName;
913
3
    bool bNotDone = aStream.ReadLine(aLine);
914
3
    PropertyMap aPropertyMap;
915
3
    bool bFirst = true;
916
3
    while (bNotDone)
917
0
    {
918
0
        static const char aCommentPrefix[] = "/* ";
919
0
        if (o3tl::starts_with(aLine, aCommentPrefix))
920
0
        {
921
0
            if (bFirst)
922
0
                bFirst = false;
923
0
            else
924
0
                maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = aPropertyMap;
925
0
            aName = OUString::fromUtf8(std::string_view(aLine).substr(
926
0
                strlen(aCommentPrefix),
927
0
                aLine.getLength() - strlen(aCommentPrefix) - strlen(" */")));
928
0
        }
929
0
        else
930
0
        {
931
0
            if (std::string_view(aLine) == "AdjustmentValues")
932
0
            {
933
0
                aStream.ReadLine(aLine);
934
0
                if (std::string_view(aLine)
935
0
                    != "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) {}")
936
0
                {
937
0
                    std::vector<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustmentValues;
938
0
                    static constexpr std::string_view aExpectedPrefix(
939
0
                        "([]com.sun.star.drawing.EnhancedCustomShapeAdjustmentValue) { ");
940
0
                    assert(o3tl::starts_with(aLine, aExpectedPrefix));
941
942
0
                    std::string_view aValue = std::string_view(aLine).substr(
943
0
                        aExpectedPrefix.size(),
944
0
                        aLine.getLength() - aExpectedPrefix.size() - strlen(" }"));
945
0
                    lcl_parseAdjustmentValues(aAdjustmentValues, aValue);
946
0
                    aPropertyMap.setProperty(PROP_AdjustmentValues,
947
0
                                             comphelper::containerToSequence(aAdjustmentValues));
948
0
                }
949
0
                else
950
0
                    aPropertyMap.setProperty(PROP_AdjustmentValues, uno::Sequence<OUString>(0));
951
0
            }
952
0
            else if (std::string_view(aLine) == "Equations")
953
0
            {
954
0
                aStream.ReadLine(aLine);
955
0
                if (std::string_view(aLine) != "([]string) {}")
956
0
                {
957
0
                    std::vector<OUString> aEquations;
958
0
                    static constexpr std::string_view aExpectedPrefix("([]string) { ");
959
0
                    assert(o3tl::starts_with(aLine, aExpectedPrefix));
960
961
0
                    std::string_view aValue = std::string_view(aLine).substr(
962
0
                        aExpectedPrefix.size(),
963
0
                        aLine.getLength() - aExpectedPrefix.size() - strlen(" }"));
964
0
                    lcl_parseEquations(aEquations, aValue);
965
0
                    aPropertyMap.setProperty(PROP_Equations,
966
0
                                             comphelper::containerToSequence(aEquations));
967
0
                }
968
0
                else
969
0
                    aPropertyMap.setProperty(PROP_Equations, uno::Sequence<OUString>(0));
970
0
            }
971
0
            else if (std::string_view(aLine) == "Handles")
972
0
            {
973
0
                aStream.ReadLine(aLine);
974
0
                if (std::string_view(aLine) != "([][]com.sun.star.beans.PropertyValue) {}")
975
0
                {
976
0
                    std::vector<uno::Sequence<beans::PropertyValue>> aHandles;
977
0
                    static constexpr std::string_view aExpectedPrefix(
978
0
                        "([][]com.sun.star.beans.PropertyValue) { ");
979
0
                    assert(o3tl::starts_with(aLine, aExpectedPrefix));
980
981
0
                    std::string_view aValue = std::string_view(aLine).substr(
982
0
                        aExpectedPrefix.size(),
983
0
                        aLine.getLength() - aExpectedPrefix.size() - strlen(" }"));
984
0
                    lcl_parseHandles(aHandles, aValue);
985
0
                    aPropertyMap.setProperty(PROP_Handles,
986
0
                                             comphelper::containerToSequence(aHandles));
987
0
                }
988
0
                else
989
0
                    aPropertyMap.setProperty(PROP_Handles, uno::Sequence<OUString>(0));
990
0
            }
991
0
            else if (std::string_view(aLine) == "MirroredX")
992
0
            {
993
0
                aStream.ReadLine(aLine);
994
0
                if (std::string_view(aLine) == "true" || std::string_view(aLine) == "false")
995
0
                {
996
0
                    aPropertyMap.setProperty(PROP_MirroredX, std::string_view(aLine) == "true");
997
0
                }
998
0
                else
999
0
                    SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected "
1000
0
                                    "MirroredX parameter");
1001
0
            }
1002
0
            else if (std::string_view(aLine) == "MirroredY")
1003
0
            {
1004
0
                aStream.ReadLine(aLine);
1005
0
                if (std::string_view(aLine) == "true" || std::string_view(aLine) == "false")
1006
0
                {
1007
0
                    aPropertyMap.setProperty(PROP_MirroredY, std::string_view(aLine) == "true");
1008
0
                }
1009
0
                else
1010
0
                    SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unexpected "
1011
0
                                    "MirroredY parameter");
1012
0
            }
1013
0
            else if (std::string_view(aLine) == "Path")
1014
0
            {
1015
0
                aStream.ReadLine(aLine);
1016
0
                static constexpr std::string_view aExpectedPrefix(
1017
0
                    "([]com.sun.star.beans.PropertyValue) { ");
1018
0
                assert(o3tl::starts_with(aLine, aExpectedPrefix));
1019
1020
0
                std::vector<beans::PropertyValue> aPathValue;
1021
0
                std::string_view aValue = std::string_view(aLine).substr(
1022
0
                    aExpectedPrefix.size(),
1023
0
                    aLine.getLength() - aExpectedPrefix.size() - strlen(" }"));
1024
0
                lcl_parsePath(aPathValue, aValue);
1025
0
                aPropertyMap.setProperty(PROP_Path, comphelper::containerToSequence(aPathValue));
1026
0
            }
1027
0
            else if (std::string_view(aLine) == "Type")
1028
0
            {
1029
                // Just ignore the line here, we already know the correct type.
1030
0
                aStream.ReadLine(aLine);
1031
0
                aPropertyMap.setProperty(PROP_Type, "ooxml-" + aName);
1032
0
            }
1033
0
            else if (std::string_view(aLine) == "ViewBox")
1034
0
            {
1035
0
                aStream.ReadLine(aLine);
1036
0
                static constexpr std::string_view aExpectedPrefix(
1037
0
                    "(com.sun.star.awt.Rectangle) { ");
1038
0
                assert(o3tl::starts_with(aLine, aExpectedPrefix));
1039
1040
0
                std::string_view aValue = std::string_view(aLine).substr(
1041
0
                    aExpectedPrefix.size(),
1042
0
                    aLine.getLength() - aExpectedPrefix.size() - strlen(" }"));
1043
0
                aPropertyMap.setProperty(PROP_ViewBox, lcl_parseRectangle(aValue));
1044
0
            }
1045
0
            else
1046
0
                SAL_WARN("oox", "CustomShapeProperties::initializePresetDataMap: unhandled line: "
1047
0
                                    << std::string_view(aLine));
1048
0
        }
1049
0
        bNotDone = aStream.ReadLine(aLine);
1050
0
    }
1051
3
    maPresetDataMap[TokenMap::getTokenFromUnicode(aName)] = std::move(aPropertyMap);
1052
3
}
1053
}
1054
1055
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */