/src/libreoffice/svgio/source/svgreader/svgvisitor.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 | | |
11 | | #include <sal/config.h> |
12 | | |
13 | | #include <svgrectnode.hxx> |
14 | | #include <svgsvgnode.hxx> |
15 | | #include <svgpathnode.hxx> |
16 | | #include <svggradientnode.hxx> |
17 | | |
18 | | #include <svgvisitor.hxx> |
19 | | |
20 | | namespace svgio::svgreader |
21 | | { |
22 | | SvgDrawVisitor::SvgDrawVisitor() |
23 | 0 | : mpDrawRoot(std::make_shared<gfx::DrawRoot>()) |
24 | 0 | , mpCurrent(mpDrawRoot) |
25 | 0 | { |
26 | 0 | } |
27 | | |
28 | | void SvgDrawVisitor::visit(svgio::svgreader::SvgNode const& rNode) |
29 | 0 | { |
30 | 0 | switch (rNode.getType()) |
31 | 0 | { |
32 | 0 | case svgio::svgreader::SVGToken::Svg: |
33 | 0 | { |
34 | 0 | auto const& rSvgNode = static_cast<svgio::svgreader::SvgSvgNode const&>(rNode); |
35 | |
|
36 | 0 | basegfx::B2DRange aRange = rSvgNode.getCurrentViewPort(); |
37 | |
|
38 | 0 | static_cast<gfx::DrawRoot*>(mpCurrent.get())->maRectangle = aRange; |
39 | 0 | } |
40 | 0 | break; |
41 | 0 | case svgio::svgreader::SVGToken::Rect: |
42 | 0 | { |
43 | 0 | auto const& rRectNode = static_cast<svgio::svgreader::SvgRectNode const&>(rNode); |
44 | |
|
45 | 0 | double x = rRectNode.getX().getNumber(); |
46 | 0 | double y = rRectNode.getY().getNumber(); |
47 | 0 | double w = rRectNode.getWidth().getNumber(); |
48 | 0 | double h = rRectNode.getHeight().getNumber(); |
49 | |
|
50 | 0 | auto pRectangle |
51 | 0 | = std::make_shared<gfx::DrawRectangle>(basegfx::B2DRange(x, y, x + w, y + h)); |
52 | 0 | pRectangle->mnRx = rRectNode.getRx().getNumber(); |
53 | 0 | pRectangle->mnRy = rRectNode.getRy().getNumber(); |
54 | |
|
55 | 0 | pRectangle->mnStrokeWidth |
56 | 0 | = rRectNode.getSvgStyleAttributes()->getStrokeWidth().getNumber(); |
57 | |
|
58 | 0 | pRectangle->mnOpacity = rRectNode.getSvgStyleAttributes()->getOpacity().getNumber(); |
59 | |
|
60 | 0 | const basegfx::BColor* pFillColor = rRectNode.getSvgStyleAttributes()->getFill(); |
61 | 0 | const SvgGradientNode* pFillGradient |
62 | 0 | = rRectNode.getSvgStyleAttributes()->getSvgGradientNodeFill(); |
63 | 0 | if (pFillColor) |
64 | 0 | { |
65 | 0 | pRectangle->mpFillColor = std::make_shared<basegfx::BColor>(*pFillColor); |
66 | 0 | } |
67 | 0 | else if (pFillGradient) |
68 | 0 | { |
69 | 0 | drawinglayer::primitive2d::SvgGradientEntryVector aSvgGradientEntryVector; |
70 | 0 | pFillGradient->collectGradientEntries(aSvgGradientEntryVector); |
71 | 0 | if (!aSvgGradientEntryVector.empty()) |
72 | 0 | { |
73 | 0 | auto aGradientInfo = std::make_shared<gfx::LinearGradientInfo>(); |
74 | |
|
75 | 0 | aGradientInfo->x1 = pFillGradient->getX1().getNumber(); |
76 | 0 | aGradientInfo->y1 = pFillGradient->getY1().getNumber(); |
77 | 0 | aGradientInfo->x2 = pFillGradient->getX2().getNumber(); |
78 | 0 | aGradientInfo->y2 = pFillGradient->getY2().getNumber(); |
79 | |
|
80 | 0 | std::optional<basegfx::B2DHomMatrix> pGradientTransform |
81 | 0 | = pFillGradient->getGradientTransform(); |
82 | 0 | if (pGradientTransform) |
83 | 0 | { |
84 | 0 | aGradientInfo->maMatrix = *pGradientTransform; |
85 | 0 | } |
86 | |
|
87 | 0 | pRectangle->mpFillGradient = aGradientInfo; |
88 | |
|
89 | 0 | for (auto const& rEntry : aSvgGradientEntryVector) |
90 | 0 | { |
91 | 0 | gfx::GradientStop aStop; |
92 | 0 | aStop.maColor = rEntry.getColor(); |
93 | 0 | aStop.mfOffset = rEntry.getOffset(); |
94 | 0 | aStop.mfOpacity = rEntry.getOpacity(); |
95 | 0 | pRectangle->mpFillGradient->maGradientStops.push_back(aStop); |
96 | 0 | } |
97 | 0 | } |
98 | 0 | } |
99 | |
|
100 | 0 | const basegfx::BColor* pStrokeColor = rRectNode.getSvgStyleAttributes()->getStroke(); |
101 | 0 | if (pStrokeColor) |
102 | 0 | pRectangle->mpStrokeColor = std::make_shared<basegfx::BColor>(*pStrokeColor); |
103 | |
|
104 | 0 | mpCurrent->maChildren.push_back(pRectangle); |
105 | 0 | } |
106 | 0 | break; |
107 | 0 | case svgio::svgreader::SVGToken::Path: |
108 | 0 | { |
109 | 0 | auto const& rPathNode = static_cast<svgio::svgreader::SvgPathNode const&>(rNode); |
110 | |
|
111 | 0 | auto pPath = rPathNode.getPath(); |
112 | 0 | if (pPath) |
113 | 0 | { |
114 | 0 | auto pDrawPath = std::make_shared<gfx::DrawPath>(*pPath); |
115 | |
|
116 | 0 | pDrawPath->mnStrokeWidth |
117 | 0 | = rPathNode.getSvgStyleAttributes()->getStrokeWidth().getNumber(); |
118 | |
|
119 | 0 | pDrawPath->mnOpacity = rPathNode.getSvgStyleAttributes()->getOpacity().getNumber(); |
120 | |
|
121 | 0 | const basegfx::BColor* pFillColor = rPathNode.getSvgStyleAttributes()->getFill(); |
122 | 0 | if (pFillColor) |
123 | 0 | pDrawPath->mpFillColor = std::make_shared<basegfx::BColor>(*pFillColor); |
124 | |
|
125 | 0 | const basegfx::BColor* pStrokeColor |
126 | 0 | = rPathNode.getSvgStyleAttributes()->getStroke(); |
127 | 0 | if (pStrokeColor) |
128 | 0 | pDrawPath->mpStrokeColor = std::make_shared<basegfx::BColor>(*pStrokeColor); |
129 | |
|
130 | 0 | mpCurrent->maChildren.push_back(pDrawPath); |
131 | 0 | } |
132 | 0 | } |
133 | 0 | break; |
134 | | |
135 | 0 | default: |
136 | 0 | break; |
137 | 0 | } |
138 | 0 | goToChildren(rNode); |
139 | 0 | } |
140 | | |
141 | | void SvgDrawVisitor::goToChildren(svgio::svgreader::SvgNode const& rNode) |
142 | 0 | { |
143 | 0 | for (auto& rChild : rNode.getChildren()) |
144 | 0 | { |
145 | 0 | rChild->accept(*this); |
146 | 0 | } |
147 | 0 | } |
148 | | } // end of namespace svgio::svgreader |
149 | | |
150 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |