Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svgio/source/svgreader/svgusenode.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 <svgusenode.hxx>
21
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
22
#include <svgdocument.hxx>
23
24
namespace svgio::svgreader
25
{
26
        SvgUseNode::SvgUseNode(
27
            SvgDocument& rDocument,
28
            SvgNode* pParent)
29
0
        :   SvgNode(SVGToken::Use, rDocument, pParent),
30
0
            maSvgStyleAttributes(*this),
31
0
            mbDecomposingSvgNode(false)
32
0
        {
33
0
        }
34
35
        SvgUseNode::~SvgUseNode()
36
0
        {
37
0
        }
38
39
        const SvgStyleAttributes* SvgUseNode::getSvgStyleAttributes() const
40
0
        {
41
0
            return checkForCssStyle(maSvgStyleAttributes);
42
0
        }
43
44
        void SvgUseNode::parseAttribute(SVGToken aSVGToken, const OUString& aContent)
45
0
        {
46
            // call parent
47
0
            SvgNode::parseAttribute(aSVGToken, aContent);
48
49
            // read style attributes
50
0
            maSvgStyleAttributes.parseStyleAttribute(aSVGToken, aContent);
51
52
            // parse own
53
0
            switch(aSVGToken)
54
0
            {
55
0
                case SVGToken::Style:
56
0
                {
57
0
                    readLocalCssStyle(aContent);
58
0
                    break;
59
0
                }
60
0
                case SVGToken::Transform:
61
0
                {
62
0
                    const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
63
64
0
                    if(!aMatrix.isIdentity())
65
0
                    {
66
0
                        setTransform(aMatrix);
67
0
                    }
68
0
                    break;
69
0
                }
70
0
                case SVGToken::X:
71
0
                {
72
0
                    SvgNumber aNum;
73
74
0
                    if(readSingleNumber(aContent, aNum))
75
0
                    {
76
0
                        maX = aNum;
77
0
                    }
78
0
                    break;
79
0
                }
80
0
                case SVGToken::Y:
81
0
                {
82
0
                    SvgNumber aNum;
83
84
0
                    if(readSingleNumber(aContent, aNum))
85
0
                    {
86
0
                        maY = aNum;
87
0
                    }
88
0
                    break;
89
0
                }
90
0
                case SVGToken::Width:
91
0
                {
92
0
                    SvgNumber aNum;
93
94
0
                    if(readSingleNumber(aContent, aNum))
95
0
                    {
96
0
                        if(aNum.isPositive())
97
0
                        {
98
0
                            maWidth = aNum;
99
0
                        }
100
0
                    }
101
0
                    break;
102
0
                }
103
0
                case SVGToken::Height:
104
0
                {
105
0
                    SvgNumber aNum;
106
107
0
                    if(readSingleNumber(aContent, aNum))
108
0
                    {
109
0
                        if(aNum.isPositive())
110
0
                        {
111
0
                            maHeight = aNum;
112
0
                        }
113
0
                    }
114
0
                    break;
115
0
                }
116
0
                case SVGToken::Href:
117
0
                case SVGToken::XlinkHref:
118
0
                {
119
0
                    readLocalLink(aContent, maXLink);
120
0
                    break;
121
0
                }
122
0
                default:
123
0
                {
124
0
                    break;
125
0
                }
126
0
            }
127
0
        }
128
129
        void SvgUseNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DContainer& rTarget, bool /*bReferenced*/) const
130
0
        {
131
0
            drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
132
0
            basegfx::B2DHomMatrix aTransform;
133
134
            // try to access link to content
135
0
            const SvgNode* pXLink = getDocument().findSvgNodeById(maXLink);
136
137
0
            if (pXLink)
138
0
            {
139
0
                if (Display::None == pXLink->getDisplay() || mbDecomposingSvgNode)
140
0
                    return;
141
142
                // todo: in case mpXLink is a SVGToken::Svg or SVGToken::Symbol the
143
                // SVG docs want the getWidth() and getHeight() from this node
144
                // to be valid for the subtree.
145
0
                mbDecomposingSvgNode = true;
146
0
                const_cast< SvgNode* >(pXLink)->setAlternativeParent(this);
147
0
                pXLink->decomposeSvgNode(aNewTarget, true);
148
0
                const_cast< SvgNode* >(pXLink)->setAlternativeParent();
149
0
                mbDecomposingSvgNode = false;
150
151
0
                if(aNewTarget.empty())
152
0
                    return;
153
154
0
                if(getX().isSet() || getY().isSet())
155
0
                {
156
0
                    aTransform.translate(
157
0
                        getX().solve(*this, NumberType::xcoordinate),
158
0
                        getY().solve(*this, NumberType::ycoordinate));
159
0
                }
160
161
0
                if(getTransform())
162
0
                {
163
0
                    aTransform = *getTransform() * aTransform;
164
0
                }
165
0
            }
166
167
0
            const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
168
169
0
            if(pStyle)
170
0
            {
171
0
                if(Display::None != getDisplay())
172
0
                {
173
0
                    pStyle->add_postProcess(rTarget, std::move(aNewTarget), aTransform);
174
0
                }
175
0
            }
176
0
        }
177
178
} // end of namespace svgio::svgreader
179
180
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */