Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/xmloff/source/draw/xexptran.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 <sal/config.h>
21
22
#include <string_view>
23
24
#include <utility>
25
#include <xexptran.hxx>
26
#include <rtl/ustrbuf.hxx>
27
#include <osl/diagnose.h>
28
#include <sax/tools/converter.hxx>
29
#include <xmloff/xmluconv.hxx>
30
#include <basegfx/matrix/b2dhommatrix.hxx>
31
#include <basegfx/tuple/b2dtuple.hxx>
32
#include <basegfx/tuple/b3dtuple.hxx>
33
#include <basegfx/matrix/b3dhommatrix.hxx>
34
#include <basegfx/numeric/ftools.hxx>
35
#include <basegfx/matrix/b3dhommatrixtools.hxx>
36
37
using namespace ::com::sun::star;
38
39
// parsing help functions for simple chars
40
static void Imp_SkipSpaces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
41
22.6k
{
42
22.9k
    while(rPos < nLen
43
22.9k
        && ' ' == rStr[rPos])
44
261
        rPos++;
45
22.6k
}
46
47
static void Imp_SkipSpacesAndOpeningBraces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
48
102
{
49
203
    while(rPos < nLen
50
203
        && (' ' == rStr[rPos] || '(' == rStr[rPos]))
51
101
        rPos++;
52
102
}
53
54
static void Imp_SkipSpacesAndCommas(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
55
67.3k
{
56
102k
    while(rPos < nLen
57
81.4k
        && (' ' == rStr[rPos] || ',' == rStr[rPos]))
58
35.0k
        rPos++;
59
67.3k
}
60
61
static void Imp_SkipSpacesAndClosingBraces(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen)
62
102
{
63
203
    while(rPos < nLen
64
102
        && (' ' == rStr[rPos] || ')' == rStr[rPos]))
65
101
        rPos++;
66
102
}
67
68
// parsing help functions for integer numbers
69
70
static bool Imp_IsOnUnitChar(std::u16string_view rStr, const sal_Int32 nPos)
71
0
{
72
0
    sal_Unicode aChar(rStr[nPos]);
73
74
0
    return ('a' <= aChar && 'z' >= aChar)
75
0
        || ('A' <= aChar && 'Z' >= aChar)
76
0
        || '%' == aChar;
77
0
}
78
79
static double Imp_GetDoubleChar(std::u16string_view rStr, sal_Int32& rPos, const sal_Int32 nLen,
80
    const SvXMLUnitConverter& rConv, double fRetval, bool bLookForUnits = false)
81
89.8k
{
82
89.8k
    sal_Unicode aChar(rStr[rPos]);
83
89.8k
    OUStringBuffer sNumberString(32);
84
85
89.8k
    if('+' == aChar || '-' == aChar)
86
5.60k
    {
87
5.60k
        sNumberString.append(rStr[rPos]);
88
5.60k
        ++rPos;
89
5.60k
        aChar = rPos >= nLen ? 0 : rStr[rPos];
90
5.60k
    }
91
92
254k
    while(('0' <= aChar && '9' >= aChar)
93
89.9k
        || '.' == aChar)
94
164k
    {
95
164k
        sNumberString.append(rStr[rPos]);
96
164k
        ++rPos;
97
164k
        aChar = rPos >= nLen ? 0 : rStr[rPos];
98
164k
    }
99
100
89.8k
    if('e' == aChar || 'E' == aChar)
101
224
    {
102
224
        sNumberString.append(rStr[rPos]);
103
224
        ++rPos;
104
224
        aChar = rPos >= nLen ? 0 : rStr[rPos];
105
106
224
        if('+' == aChar || '-' == aChar)
107
0
        {
108
0
            sNumberString.append(rStr[rPos]);
109
0
            ++rPos;
110
0
            aChar = rPos >= nLen ? 0 : rStr[rPos];
111
0
        }
112
113
260
        while('0' <= aChar && '9' >= aChar)
114
36
        {
115
36
            sNumberString.append(rStr[rPos]);
116
36
            ++rPos;
117
36
            aChar = rPos >= nLen ? 0 : rStr[rPos];
118
36
        }
119
224
    }
120
121
89.8k
    if(bLookForUnits)
122
0
    {
123
0
        Imp_SkipSpaces(rStr, rPos, nLen);
124
0
        while(rPos < nLen && Imp_IsOnUnitChar(rStr, rPos))
125
0
            sNumberString.append(rStr[rPos++]);
126
0
    }
127
128
89.8k
    if(!sNumberString.isEmpty())
129
52.3k
    {
130
52.3k
        if(bLookForUnits)
131
0
            rConv.convertDouble(fRetval, sNumberString);
132
52.3k
        else
133
52.3k
        {
134
52.3k
            ::sax::Converter::convertDouble(fRetval, sNumberString);
135
52.3k
        }
136
52.3k
    }
137
138
89.8k
    return fRetval;
139
89.8k
}
140
141
static void Imp_PutDoubleChar(OUString& rStr, double fValue)
142
0
{
143
0
    OUStringBuffer sStringBuffer;
144
0
    ::sax::Converter::convertDouble(sStringBuffer, fValue);
145
0
    rStr += sStringBuffer;
146
0
}
147
148
static void Imp_PutDoubleChar(OUStringBuffer& rStr, const SvXMLUnitConverter& rConv, double fValue,
149
    bool bConvertUnits = false)
150
0
{
151
0
    OUStringBuffer sStringBuffer;
152
153
0
    if(bConvertUnits)
154
0
        rConv.convertDouble(sStringBuffer, fValue);
155
0
    else
156
0
    {
157
0
        ::sax::Converter::convertDouble(sStringBuffer, fValue);
158
0
    }
159
160
0
    rStr.append(sStringBuffer);
161
0
}
162
163
// base class of all 2D transform objects
164
165
struct ImpSdXMLExpTransObj2DBase
166
{
167
    sal_uInt16                  mnType;
168
    explicit ImpSdXMLExpTransObj2DBase(sal_uInt16 nType)
169
102
    :   mnType(nType) {}
170
};
171
172
// possible object types for 2D
173
174
204
#define IMP_SDXMLEXP_TRANSOBJ2D_ROTATE          0x0000
175
0
#define IMP_SDXMLEXP_TRANSOBJ2D_SCALE           0x0001
176
0
#define IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE       0x0002
177
0
#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWX           0x0003
178
0
#define IMP_SDXMLEXP_TRANSOBJ2D_SKEWY           0x0004
179
0
#define IMP_SDXMLEXP_TRANSOBJ2D_MATRIX          0x0005
180
181
// classes of objects, different sizes
182
183
namespace {
184
185
struct ImpSdXMLExpTransObj2DRotate : public ImpSdXMLExpTransObj2DBase
186
{
187
    double                      mfRotate;
188
    explicit ImpSdXMLExpTransObj2DRotate(double fVal)
189
102
    :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_ROTATE), mfRotate(fVal) {}
190
};
191
struct ImpSdXMLExpTransObj2DScale : public ImpSdXMLExpTransObj2DBase
192
{
193
    ::basegfx::B2DTuple         maScale;
194
    explicit ImpSdXMLExpTransObj2DScale(const ::basegfx::B2DTuple& rNew)
195
0
    :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SCALE), maScale(rNew) {}
196
};
197
struct ImpSdXMLExpTransObj2DTranslate : public ImpSdXMLExpTransObj2DBase
198
{
199
    ::basegfx::B2DTuple         maTranslate;
200
    explicit ImpSdXMLExpTransObj2DTranslate(const ::basegfx::B2DTuple& rNew)
201
0
    :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE), maTranslate(rNew) {}
202
};
203
struct ImpSdXMLExpTransObj2DSkewX : public ImpSdXMLExpTransObj2DBase
204
{
205
    double                      mfSkewX;
206
    explicit ImpSdXMLExpTransObj2DSkewX(double fVal)
207
0
    :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWX), mfSkewX(fVal) {}
208
};
209
struct ImpSdXMLExpTransObj2DSkewY : public ImpSdXMLExpTransObj2DBase
210
{
211
    double                      mfSkewY;
212
    explicit ImpSdXMLExpTransObj2DSkewY(double fVal)
213
0
    :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_SKEWY), mfSkewY(fVal) {}
214
};
215
struct ImpSdXMLExpTransObj2DMatrix : public ImpSdXMLExpTransObj2DBase
216
{
217
    ::basegfx::B2DHomMatrix     maMatrix;
218
    explicit ImpSdXMLExpTransObj2DMatrix(::basegfx::B2DHomMatrix aNew)
219
0
    :   ImpSdXMLExpTransObj2DBase(IMP_SDXMLEXP_TRANSOBJ2D_MATRIX), maMatrix(std::move(aNew)) {}
220
};
221
222
}
223
224
// add members
225
226
void SdXMLImExTransform2D::AddRotate(double fNew)
227
0
{
228
0
    if(fNew != 0.0)
229
0
        maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DRotate>(fNew));
230
0
}
231
232
void SdXMLImExTransform2D::AddTranslate(const ::basegfx::B2DTuple& rNew)
233
0
{
234
0
    if(!rNew.equalZero())
235
0
        maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DTranslate>(rNew));
236
0
}
237
238
void SdXMLImExTransform2D::AddSkewX(double fNew)
239
0
{
240
0
    if(fNew != 0.0)
241
0
        maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewX>(fNew));
242
0
}
243
244
// gen string for export
245
const OUString& SdXMLImExTransform2D::GetExportString(const SvXMLUnitConverter& rConv)
246
0
{
247
0
    OUStringBuffer aNewString;
248
0
    OUString aClosingBrace(u")"_ustr);
249
0
    OUString aEmptySpace(u" "_ustr);
250
251
0
    const sal_uInt32 nCount = maList.size();
252
0
    for(sal_uInt32 a(0); a < nCount; a++)
253
0
    {
254
0
        ImpSdXMLExpTransObj2DBase* pObj = maList[a].get();
255
0
        switch(pObj->mnType)
256
0
        {
257
0
            case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE :
258
0
            {
259
0
                aNewString.append("rotate (");
260
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DRotate*>(pObj)->mfRotate);
261
0
                aNewString.append(aClosingBrace);
262
0
                break;
263
0
            }
264
0
            case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
265
0
            {
266
0
                aNewString.append("scale (");
267
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale.getX());
268
0
                aNewString.append(aEmptySpace);
269
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale.getY());
270
0
                aNewString.append(aClosingBrace);
271
0
                break;
272
0
            }
273
0
            case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
274
0
            {
275
0
                aNewString.append("translate (");
276
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate.getX(), true);
277
0
                aNewString.append(aEmptySpace);
278
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate.getY(), true);
279
0
                aNewString.append(aClosingBrace);
280
0
                break;
281
0
            }
282
0
            case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
283
0
            {
284
0
                aNewString.append("skewX (");
285
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX);
286
0
                aNewString.append(aClosingBrace);
287
0
                break;
288
0
            }
289
0
            case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
290
0
            {
291
0
                aNewString.append("skewY (");
292
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY);
293
0
                aNewString.append(aClosingBrace);
294
0
                break;
295
0
            }
296
0
            case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX :
297
0
            {
298
0
                aNewString.append("matrix (");
299
300
                // a
301
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 0));
302
0
                aNewString.append(aEmptySpace);
303
304
                // b
305
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 0));
306
0
                aNewString.append(aEmptySpace);
307
308
                // c
309
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 1));
310
0
                aNewString.append(aEmptySpace);
311
312
                // d
313
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 1));
314
0
                aNewString.append(aEmptySpace);
315
316
                // e
317
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(0, 2), true);
318
0
                aNewString.append(aEmptySpace);
319
320
                // f
321
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix.get(1, 2), true);
322
323
0
                aNewString.append(aClosingBrace);
324
0
                break;
325
0
            }
326
0
            default :
327
0
            {
328
0
                OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
329
0
                break;
330
0
            }
331
0
        }
332
333
        // if not the last entry, add one space to next tag
334
0
        if(a + 1 != maList.size())
335
0
        {
336
0
            aNewString.append(aEmptySpace);
337
0
        }
338
0
    }
339
340
    // fill string form OUString
341
0
    msString = aNewString.makeStringAndClear();
342
343
0
    return msString;
344
0
}
345
346
// sets new string, parses it and generates entries
347
void SdXMLImExTransform2D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
348
106
{
349
106
    msString = rNew;
350
106
    maList.clear();
351
352
106
    if(msString.isEmpty())
353
0
        return;
354
355
106
    const OUString aStr = msString;
356
106
    const sal_Int32 nLen(aStr.getLength());
357
358
106
    static constexpr OUStringLiteral aString_rotate( u"rotate" );
359
106
    static constexpr OUStringLiteral aString_scale( u"scale" );
360
106
    static constexpr OUStringLiteral aString_translate( u"translate" );
361
106
    static constexpr OUStringLiteral aString_skewX( u"skewX" );
362
106
    static constexpr OUStringLiteral aString_skewY( u"skewY" );
363
106
    static constexpr OUStringLiteral aString_matrix( u"matrix" );
364
365
106
    sal_Int32 nPos(0);
366
367
325
    while(nPos < nLen)
368
219
    {
369
        // skip spaces
370
219
        Imp_SkipSpaces(aStr, nPos, nLen);
371
372
        // look for tag
373
219
        if(nPos < nLen)
374
219
        {
375
219
            if(nPos == aStr.indexOf(aString_rotate, nPos))
376
102
            {
377
102
                double fValue(0.0);
378
102
                nPos += 6;
379
102
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
380
102
                fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
381
102
                if(fValue != 0.0)
382
102
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DRotate>(fValue));
383
384
102
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
385
102
            }
386
117
            else if(nPos == aStr.indexOf(aString_scale, nPos))
387
0
            {
388
0
                ::basegfx::B2DTuple aValue(1.0, 1.0);
389
0
                nPos += 5;
390
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
391
0
                aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
392
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
393
0
                aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
394
395
0
                if(aValue.getX() != 1.0 || aValue.getY() != 1.0)
396
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DScale>(aValue));
397
398
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
399
0
            }
400
117
            else if(nPos == aStr.indexOf(aString_translate, nPos))
401
0
            {
402
0
                ::basegfx::B2DTuple aValue;
403
0
                nPos += 9;
404
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
405
0
                aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
406
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
407
0
                aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
408
409
0
                if(!aValue.equalZero())
410
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DTranslate>(aValue));
411
412
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
413
0
            }
414
117
            else if(nPos == aStr.indexOf(aString_skewX, nPos))
415
0
            {
416
0
                double fValue(0.0);
417
0
                nPos += 5;
418
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
419
0
                fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
420
0
                if(fValue != 0.0)
421
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewX>(fValue));
422
423
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
424
0
            }
425
117
            else if(nPos == aStr.indexOf(aString_skewY, nPos))
426
0
            {
427
0
                double fValue(0.0);
428
0
                nPos += 5;
429
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
430
0
                fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
431
0
                if(fValue != 0.0)
432
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DSkewY>(fValue));
433
434
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
435
0
            }
436
117
            else if(nPos == aStr.indexOf(aString_matrix, nPos))
437
0
            {
438
0
                ::basegfx::B2DHomMatrix aValue;
439
440
0
                nPos += 6;
441
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
442
443
                // a
444
0
                aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
445
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
446
447
                // b
448
0
                aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
449
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
450
451
                // c
452
0
                aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
453
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
454
455
                // d
456
0
                aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
457
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
458
459
                // e
460
0
                aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2), true));
461
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
462
463
                // f
464
0
                aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2), true));
465
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
466
467
0
                if(!aValue.isIdentity())
468
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj2DMatrix>(aValue));
469
470
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
471
0
            }
472
117
            else
473
117
            {
474
117
                nPos++;
475
117
            }
476
219
        }
477
219
    }
478
106
}
479
480
void SdXMLImExTransform2D::GetFullTransform(::basegfx::B2DHomMatrix& rFullTrans)
481
102
{
482
102
    rFullTrans.identity();
483
484
102
    const sal_uInt32 nCount = maList.size();
485
204
    for(sal_uInt32 a(0); a < nCount; a++)
486
102
    {
487
102
        ImpSdXMLExpTransObj2DBase* pObj = maList[a].get();
488
102
        switch(pObj->mnType)
489
102
        {
490
102
            case IMP_SDXMLEXP_TRANSOBJ2D_ROTATE     :
491
102
            {
492
                // #i78696#
493
                // mfRotate is mathematically wrong oriented since we export/import the angle
494
                // values mirrored. This error is fixed in the API, but not yet in the FileFormat.
495
                // For the FileFormat there is a follow-up task (#i78698#) to fix this in the next
496
                // ODF FileFormat version. For now - to emulate the old behaviour - it is necessary
497
                // to mirror the value here
498
102
                rFullTrans.rotate(static_cast<ImpSdXMLExpTransObj2DRotate*>(pObj)->mfRotate * -1.0);
499
102
                break;
500
0
            }
501
0
            case IMP_SDXMLEXP_TRANSOBJ2D_SCALE      :
502
0
            {
503
0
                const ::basegfx::B2DTuple& rScale = static_cast<ImpSdXMLExpTransObj2DScale*>(pObj)->maScale;
504
0
                rFullTrans.scale(rScale.getX(), rScale.getY());
505
0
                break;
506
0
            }
507
0
            case IMP_SDXMLEXP_TRANSOBJ2D_TRANSLATE  :
508
0
            {
509
0
                const ::basegfx::B2DTuple& rTranslate = static_cast<ImpSdXMLExpTransObj2DTranslate*>(pObj)->maTranslate;
510
0
                rFullTrans.translate(rTranslate.getX(), rTranslate.getY());
511
0
                break;
512
0
            }
513
0
            case IMP_SDXMLEXP_TRANSOBJ2D_SKEWX      :
514
0
            {
515
                // For to get a mathematical correct matrix from already existing documents,
516
                // mirror the value here. ODF spec is unclear about direction.
517
0
                rFullTrans.shearX(-tan(static_cast<ImpSdXMLExpTransObj2DSkewX*>(pObj)->mfSkewX));
518
0
                break;
519
0
            }
520
0
            case IMP_SDXMLEXP_TRANSOBJ2D_SKEWY      :
521
0
            {
522
                // LibreOffice does not write skewY, OOo neither. Such files are foreign documents
523
                // or manually set transformations. OOo had used the value as -tan(value) before
524
                // errors were introduced, Scribus 1.5.4 uses it as -tan(value) too, MS Office does
525
                // not shear at all. ODF spec is unclear about direction.
526
0
                rFullTrans.shearY(-tan(static_cast<ImpSdXMLExpTransObj2DSkewY*>(pObj)->mfSkewY));
527
0
                break;
528
0
            }
529
0
            case IMP_SDXMLEXP_TRANSOBJ2D_MATRIX     :
530
0
            {
531
0
                rFullTrans *= static_cast<ImpSdXMLExpTransObj2DMatrix*>(pObj)->maMatrix;
532
0
                break;
533
0
            }
534
0
            default :
535
0
            {
536
0
                OSL_FAIL("SdXMLImExTransform2D: impossible entry!");
537
0
                break;
538
0
            }
539
102
        }
540
102
    }
541
102
}
542
543
// base class of all 3D transform objects
544
545
struct ImpSdXMLExpTransObj3DBase
546
{
547
    sal_uInt16                  mnType;
548
    explicit ImpSdXMLExpTransObj3DBase(sal_uInt16 nType)
549
0
    :   mnType(nType) {}
550
};
551
552
// possible object types for 3D
553
554
0
#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X        0x0000
555
0
#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y        0x0001
556
0
#define IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z        0x0002
557
0
#define IMP_SDXMLEXP_TRANSOBJ3D_SCALE           0x0003
558
0
#define IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE       0x0004
559
0
#define IMP_SDXMLEXP_TRANSOBJ3D_MATRIX          0x0005
560
561
// classes of objects, different sizes
562
563
namespace {
564
565
struct ImpSdXMLExpTransObj3DRotateX : public ImpSdXMLExpTransObj3DBase
566
{
567
    double                      mfRotateX;
568
    explicit ImpSdXMLExpTransObj3DRotateX(double fVal)
569
0
    :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X), mfRotateX(fVal) {}
570
};
571
struct ImpSdXMLExpTransObj3DRotateY : public ImpSdXMLExpTransObj3DBase
572
{
573
    double                      mfRotateY;
574
    explicit ImpSdXMLExpTransObj3DRotateY(double fVal)
575
0
    :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y), mfRotateY(fVal) {}
576
};
577
struct ImpSdXMLExpTransObj3DRotateZ : public ImpSdXMLExpTransObj3DBase
578
{
579
    double                      mfRotateZ;
580
    explicit ImpSdXMLExpTransObj3DRotateZ(double fVal)
581
0
    :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z), mfRotateZ(fVal) {}
582
};
583
struct ImpSdXMLExpTransObj3DScale : public ImpSdXMLExpTransObj3DBase
584
{
585
    ::basegfx::B3DTuple         maScale;
586
    explicit ImpSdXMLExpTransObj3DScale(const ::basegfx::B3DTuple& rNew)
587
0
    :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_SCALE), maScale(rNew) {}
588
};
589
struct ImpSdXMLExpTransObj3DTranslate : public ImpSdXMLExpTransObj3DBase
590
{
591
    ::basegfx::B3DTuple         maTranslate;
592
    explicit ImpSdXMLExpTransObj3DTranslate(const ::basegfx::B3DTuple& rNew)
593
0
    :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE), maTranslate(rNew) {}
594
};
595
struct ImpSdXMLExpTransObj3DMatrix : public ImpSdXMLExpTransObj3DBase
596
{
597
    ::basegfx::B3DHomMatrix     maMatrix;
598
    explicit ImpSdXMLExpTransObj3DMatrix(::basegfx::B3DHomMatrix aNew)
599
0
    :   ImpSdXMLExpTransObj3DBase(IMP_SDXMLEXP_TRANSOBJ3D_MATRIX), maMatrix(std::move(aNew)) {}
600
};
601
602
}
603
604
// add members
605
606
void SdXMLImExTransform3D::AddMatrix(const ::basegfx::B3DHomMatrix& rNew)
607
0
{
608
0
    if(!rNew.isIdentity())
609
0
        maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DMatrix>(rNew));
610
0
}
611
612
void SdXMLImExTransform3D::AddHomogenMatrix(const drawing::HomogenMatrix& xHomMat)
613
0
{
614
0
    AddMatrix(basegfx::utils::UnoHomogenMatrixToB3DHomMatrix(xHomMat));
615
0
}
616
617
// gen string for export
618
const OUString& SdXMLImExTransform3D::GetExportString(const SvXMLUnitConverter& rConv)
619
0
{
620
0
    OUStringBuffer aNewString;
621
0
    OUString aClosingBrace(u")"_ustr);
622
0
    OUString aEmptySpace(u" "_ustr);
623
624
0
    const sal_uInt32 nCount = maList.size();
625
0
    for(sal_uInt32 a(0); a < nCount; a++)
626
0
    {
627
0
        ImpSdXMLExpTransObj3DBase* pObj = maList[a].get();
628
0
        switch(pObj->mnType)
629
0
        {
630
0
            case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
631
0
            {
632
0
                aNewString.append("rotatex (");
633
0
                Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateX*>(pObj)->mfRotateX) );
634
0
                aNewString.append(aClosingBrace);
635
0
                break;
636
0
            }
637
0
            case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
638
0
            {
639
0
                aNewString.append("rotatey (");
640
0
                Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateY*>(pObj)->mfRotateY) );
641
0
                aNewString.append(aClosingBrace);
642
0
                break;
643
0
            }
644
0
            case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
645
0
            {
646
0
                aNewString.append("rotatez (");
647
0
                Imp_PutDoubleChar(aNewString, rConv, basegfx::rad2deg( static_cast<ImpSdXMLExpTransObj3DRotateZ*>(pObj)->mfRotateZ) );
648
0
                aNewString.append(aClosingBrace);
649
0
                break;
650
0
            }
651
0
            case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
652
0
            {
653
0
                aNewString.append("scale (");
654
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getX());
655
0
                aNewString.append(aEmptySpace);
656
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getY());
657
0
                aNewString.append(aEmptySpace);
658
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale.getZ());
659
0
                aNewString.append(aClosingBrace);
660
0
                break;
661
0
            }
662
0
            case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
663
0
            {
664
0
                aNewString.append("translate (");
665
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getX(), true);
666
0
                aNewString.append(aEmptySpace);
667
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getY(), true);
668
0
                aNewString.append(aEmptySpace);
669
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate.getZ(), true);
670
0
                aNewString.append(aClosingBrace);
671
0
                break;
672
0
            }
673
0
            case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX :
674
0
            {
675
0
                aNewString.append("matrix (");
676
677
                // a
678
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 0));
679
0
                aNewString.append(aEmptySpace);
680
681
                // b
682
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 0));
683
0
                aNewString.append(aEmptySpace);
684
685
                // c
686
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 0));
687
0
                aNewString.append(aEmptySpace);
688
689
                // d
690
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 1));
691
0
                aNewString.append(aEmptySpace);
692
693
                // e
694
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 1));
695
0
                aNewString.append(aEmptySpace);
696
697
                // f
698
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 1));
699
0
                aNewString.append(aEmptySpace);
700
701
                // g
702
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 2));
703
0
                aNewString.append(aEmptySpace);
704
705
                // h
706
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 2));
707
0
                aNewString.append(aEmptySpace);
708
709
                // i
710
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 2));
711
0
                aNewString.append(aEmptySpace);
712
713
                // j
714
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(0, 3), true);
715
0
                aNewString.append(aEmptySpace);
716
717
                // k
718
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(1, 3), true);
719
0
                aNewString.append(aEmptySpace);
720
721
                // l
722
0
                Imp_PutDoubleChar(aNewString, rConv, static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix.get(2, 3), true);
723
724
0
                aNewString.append(aClosingBrace);
725
0
                break;
726
0
            }
727
0
            default :
728
0
            {
729
0
                OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
730
0
                break;
731
0
            }
732
0
        }
733
734
        // if not the last entry, add one space to next tag
735
0
        if(a + 1 != maList.size())
736
0
        {
737
0
            aNewString.append(aEmptySpace);
738
0
        }
739
0
    }
740
741
    // fill string form OUString
742
0
    msString = aNewString.makeStringAndClear();
743
744
0
    return msString;
745
0
}
746
747
// for Import: constructor with string, parses it and generates entries
748
SdXMLImExTransform3D::SdXMLImExTransform3D(const OUString& rNew, const SvXMLUnitConverter& rConv)
749
0
{
750
0
    SetString(rNew, rConv);
751
0
}
752
753
// sets new string, parses it and generates entries
754
void SdXMLImExTransform3D::SetString(const OUString& rNew, const SvXMLUnitConverter& rConv)
755
0
{
756
0
    msString = rNew;
757
0
    maList.clear();
758
759
0
    if(msString.isEmpty())
760
0
        return;
761
762
0
    const OUString aStr = msString;
763
0
    const sal_Int32 nLen(aStr.getLength());
764
765
0
    static constexpr OUStringLiteral aString_rotatex( u"rotatex" );
766
0
    static constexpr OUStringLiteral aString_rotatey( u"rotatey" );
767
0
    static constexpr OUStringLiteral aString_rotatez( u"rotatez" );
768
0
    static constexpr OUStringLiteral aString_scale( u"scale" );
769
0
    static constexpr OUStringLiteral aString_translate( u"translate" );
770
0
    static constexpr OUStringLiteral aString_matrix( u"matrix" );
771
772
0
    sal_Int32 nPos(0);
773
774
0
    while(nPos < nLen)
775
0
    {
776
        // skip spaces
777
0
        Imp_SkipSpaces(aStr, nPos, nLen);
778
779
        // look for tag
780
0
        if(nPos < nLen)
781
0
        {
782
0
            if(nPos == aStr.indexOf(aString_rotatex, nPos))
783
0
            {
784
0
                double fValue(0.0);
785
786
0
                nPos += 7;
787
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
788
0
                fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
789
0
                if(fValue != 0.0)
790
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateX>(basegfx::deg2rad(fValue)));
791
792
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
793
0
            }
794
0
            else if(nPos == aStr.indexOf(aString_rotatey, nPos))
795
0
            {
796
0
                double fValue(0.0);
797
798
0
                nPos += 7;
799
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
800
0
                fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
801
0
                if(fValue != 0.0)
802
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateY>(basegfx::deg2rad(fValue)));
803
804
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
805
0
            }
806
0
            else if(nPos == aStr.indexOf(aString_rotatez, nPos))
807
0
            {
808
0
                double fValue(0.0);
809
810
0
                nPos += 7;
811
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
812
0
                fValue = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, fValue);
813
0
                if(fValue != 0.0)
814
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DRotateZ>(basegfx::deg2rad(fValue)));
815
816
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
817
0
            }
818
0
            else if(nPos == aStr.indexOf(aString_scale, nPos))
819
0
            {
820
0
                ::basegfx::B3DTuple aValue(1.0, 1.0, 1.0);
821
822
0
                nPos += 5;
823
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
824
0
                aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX()));
825
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
826
0
                aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY()));
827
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
828
0
                aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ()));
829
830
0
                if(1.0 != aValue.getX() || 1.0 != aValue.getY() || 1.0 != aValue.getZ())
831
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DScale>(aValue));
832
833
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
834
0
            }
835
0
            else if(nPos == aStr.indexOf(aString_translate, nPos))
836
0
            {
837
0
                ::basegfx::B3DTuple aValue;
838
839
0
                nPos += 9;
840
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
841
0
                aValue.setX(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getX(), true));
842
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
843
0
                aValue.setY(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getY(), true));
844
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
845
0
                aValue.setZ(Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.getZ(), true));
846
847
0
                if(!aValue.equalZero())
848
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DTranslate>(aValue));
849
850
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
851
0
            }
852
0
            else if(nPos == aStr.indexOf(aString_matrix, nPos))
853
0
            {
854
0
                ::basegfx::B3DHomMatrix aValue;
855
856
0
                nPos += 6;
857
0
                Imp_SkipSpacesAndOpeningBraces(aStr, nPos, nLen);
858
859
                // a
860
0
                aValue.set(0, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 0)));
861
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
862
863
                // b
864
0
                aValue.set(1, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 0)));
865
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
866
867
                // c
868
0
                aValue.set(2, 0, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 0)));
869
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
870
871
                // d
872
0
                aValue.set(0, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 1)));
873
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
874
875
                // e
876
0
                aValue.set(1, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 1)));
877
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
878
879
                // f
880
0
                aValue.set(2, 1, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 1)));
881
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
882
883
                // g
884
0
                aValue.set(0, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 2)));
885
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
886
887
                // h
888
0
                aValue.set(1, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 2)));
889
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
890
891
                // i
892
0
                aValue.set(2, 2, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 2)));
893
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
894
895
                // j
896
0
                aValue.set(0, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(0, 3), true));
897
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
898
899
                // k
900
0
                aValue.set(1, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(1, 3), true));
901
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
902
903
                // l
904
0
                aValue.set(2, 3, Imp_GetDoubleChar(aStr, nPos, nLen, rConv, aValue.get(2, 3), true));
905
0
                Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
906
907
0
                if(!aValue.isIdentity())
908
0
                    maList.push_back(std::make_shared<ImpSdXMLExpTransObj3DMatrix>(aValue));
909
910
0
                Imp_SkipSpacesAndClosingBraces(aStr, nPos, nLen);
911
0
            }
912
0
            else
913
0
            {
914
0
                nPos++;
915
0
            }
916
0
        }
917
0
    }
918
0
}
919
920
bool SdXMLImExTransform3D::GetFullHomogenTransform(css::drawing::HomogenMatrix& xHomMat)
921
0
{
922
0
    ::basegfx::B3DHomMatrix aFullTransform;
923
0
    GetFullTransform(aFullTransform);
924
925
0
    if(!aFullTransform.isIdentity())
926
0
    {
927
0
        basegfx::utils::B3DHomMatrixToUnoHomogenMatrix(aFullTransform, xHomMat);
928
0
        return true;
929
0
    }
930
931
0
    return false;
932
0
}
933
934
void SdXMLImExTransform3D::GetFullTransform(::basegfx::B3DHomMatrix& rFullTrans)
935
0
{
936
0
    rFullTrans.identity();
937
938
0
    const sal_uInt32 nCount = maList.size();
939
0
    for(sal_uInt32 a(0); a < nCount; a++)
940
0
    {
941
0
        ImpSdXMLExpTransObj3DBase* pObj = maList[a].get();
942
0
        switch(pObj->mnType)
943
0
        {
944
0
            case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_X   :
945
0
            {
946
0
                rFullTrans.rotate(static_cast<ImpSdXMLExpTransObj3DRotateX*>(pObj)->mfRotateX, 0.0, 0.0);
947
0
                break;
948
0
            }
949
0
            case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Y   :
950
0
            {
951
0
                rFullTrans.rotate(0.0, static_cast<ImpSdXMLExpTransObj3DRotateY*>(pObj)->mfRotateY, 0.0);
952
0
                break;
953
0
            }
954
0
            case IMP_SDXMLEXP_TRANSOBJ3D_ROTATE_Z   :
955
0
            {
956
0
                rFullTrans.rotate(0.0, 0.0, static_cast<ImpSdXMLExpTransObj3DRotateZ*>(pObj)->mfRotateZ);
957
0
                break;
958
0
            }
959
0
            case IMP_SDXMLEXP_TRANSOBJ3D_SCALE      :
960
0
            {
961
0
                const ::basegfx::B3DTuple& rScale = static_cast<ImpSdXMLExpTransObj3DScale*>(pObj)->maScale;
962
0
                rFullTrans.scale(rScale.getX(), rScale.getY(), rScale.getZ());
963
0
                break;
964
0
            }
965
0
            case IMP_SDXMLEXP_TRANSOBJ3D_TRANSLATE  :
966
0
            {
967
0
                const ::basegfx::B3DTuple& rTranslate = static_cast<ImpSdXMLExpTransObj3DTranslate*>(pObj)->maTranslate;
968
0
                rFullTrans.translate(rTranslate.getX(), rTranslate.getY(), rTranslate.getZ());
969
0
                break;
970
0
            }
971
0
            case IMP_SDXMLEXP_TRANSOBJ3D_MATRIX     :
972
0
            {
973
0
                rFullTrans *= static_cast<ImpSdXMLExpTransObj3DMatrix*>(pObj)->maMatrix;
974
0
                break;
975
0
            }
976
0
            default :
977
0
            {
978
0
                OSL_FAIL("SdXMLImExTransform3D: impossible entry!");
979
0
                break;
980
0
            }
981
0
        }
982
0
    }
983
0
}
984
985
SdXMLImExViewBox::SdXMLImExViewBox(double fX, double fY, double fW, double fH)
986
0
:   mfX( fX ),
987
0
    mfY( fY ),
988
0
    mfW( fW ),
989
0
    mfH( fH )
990
0
{
991
0
}
992
993
// #100617# Asked vincent hardy: svg:viewBox values may be double precision.
994
SdXMLImExViewBox::SdXMLImExViewBox(OUString aNew, const SvXMLUnitConverter& rConv)
995
22.4k
:   msString(std::move(aNew)),
996
22.4k
    mfX( 0.0 ),
997
22.4k
    mfY( 0.0 ),
998
22.4k
    mfW( 1000.0 ),
999
22.4k
    mfH( 1000.0 )
1000
22.4k
{
1001
22.4k
    if(msString.isEmpty())
1002
5
        return;
1003
1004
22.4k
    const OUString aStr = msString;
1005
22.4k
    const sal_Int32 nLen(aStr.getLength());
1006
22.4k
    sal_Int32 nPos(0);
1007
1008
    // skip starting spaces
1009
22.4k
    Imp_SkipSpaces(aStr, nPos, nLen);
1010
1011
    // get mX, #100617# be prepared for doubles
1012
22.4k
    mfX = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfX);
1013
1014
    // skip spaces and commas
1015
22.4k
    Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1016
1017
    // get mY, #100617# be prepared for doubles
1018
22.4k
    mfY = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfY);
1019
1020
    // skip spaces and commas
1021
22.4k
    Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1022
1023
    // get mW, #100617# be prepared for doubles
1024
22.4k
    mfW = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfW);
1025
1026
    // skip spaces and commas
1027
22.4k
    Imp_SkipSpacesAndCommas(aStr, nPos, nLen);
1028
1029
    // get mH, #100617# be prepared for doubles
1030
22.4k
    mfH = Imp_GetDoubleChar(aStr, nPos, nLen, rConv, mfH);
1031
1032
22.4k
}
1033
1034
const OUString& SdXMLImExViewBox::GetExportString()
1035
0
{
1036
0
    OUString aNewString;
1037
0
    OUString aEmptySpace(u" "_ustr);
1038
1039
0
    Imp_PutDoubleChar(aNewString, mfX);
1040
0
    aNewString += aEmptySpace;
1041
1042
0
    Imp_PutDoubleChar(aNewString, mfY);
1043
0
    aNewString += aEmptySpace;
1044
1045
0
    Imp_PutDoubleChar(aNewString, mfW);
1046
0
    aNewString += aEmptySpace;
1047
1048
0
    Imp_PutDoubleChar(aNewString, mfH);
1049
1050
    // set new string
1051
0
    msString = aNewString;
1052
1053
0
    return msString;
1054
0
}
1055
1056
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */