Line data Source code
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 : #ifndef INCLUDED_FILTER_SOURCE_SVG_GFXTYPES_HXX
10 : #define INCLUDED_FILTER_SOURCE_SVG_GFXTYPES_HXX
11 :
12 : #include <basegfx/range/b2drange.hxx>
13 : #include <basegfx/matrix/b2dhommatrix.hxx>
14 : #include <basegfx/polygon/b2dlinegeometry.hxx>
15 : #include <rtl/ustring.hxx>
16 : #include <unordered_set>
17 : #include <unordered_map>
18 :
19 : namespace svgi
20 : {
21 :
22 : struct ARGBColor
23 : {
24 0 : static double toDoubleColor( sal_uInt8 val ) { return val/255.0; }
25 :
26 0 : ARGBColor() : a(1.0), r(0.0), g(0.0), b(0.0)
27 0 : {}
28 0 : explicit ARGBColor(double fGrey) : a(1.0), r(fGrey), g(fGrey), b(fGrey)
29 0 : {}
30 : ARGBColor( double r_, double g_, double b_ ) :
31 : a(1.0), r(r_), g(g_), b(b_)
32 : {}
33 : ARGBColor( double a_, double r_, double g_, double b_ ) :
34 : a(a_), r(r_), g(g_), b(b_)
35 : {}
36 0 : ARGBColor( int r_, int g_, int b_ ) :
37 : a(1.0),
38 0 : r(toDoubleColor(sal::static_int_cast<sal_uInt8>(r_))),
39 0 : g(toDoubleColor(sal::static_int_cast<sal_uInt8>(g_))),
40 0 : b(toDoubleColor(sal::static_int_cast<sal_uInt8>(b_)))
41 0 : {}
42 : ARGBColor( int a_, int r_, int g_, int b_ ) :
43 : a(toDoubleColor(sal::static_int_cast<sal_uInt8>(a_))),
44 : r(toDoubleColor(sal::static_int_cast<sal_uInt8>(r_))),
45 : g(toDoubleColor(sal::static_int_cast<sal_uInt8>(g_))),
46 : b(toDoubleColor(sal::static_int_cast<sal_uInt8>(b_)))
47 : {}
48 : double a;
49 : double r;
50 : double g;
51 : double b;
52 : };
53 0 : inline bool operator==( const ARGBColor& rLHS, const ARGBColor& rRHS )
54 0 : { return rLHS.a==rRHS.a && rLHS.r==rRHS.r && rLHS.g==rRHS.g && rLHS.b==rRHS.b; }
55 0 : inline bool operator!=( const ARGBColor& rLHS, const ARGBColor& rRHS )
56 0 : { return !(rLHS==rRHS); }
57 :
58 : struct GradientStop
59 : {
60 0 : GradientStop() : maStopColor(), mnStopPosition(0.0)
61 0 : {}
62 : ARGBColor maStopColor;
63 : double mnStopPosition;
64 : };
65 : inline bool operator==( const GradientStop& rLHS, const GradientStop& rRHS )
66 : { return rLHS.mnStopPosition==rRHS.mnStopPosition && rLHS.maStopColor==rRHS.maStopColor; }
67 :
68 0 : struct Gradient
69 : {
70 : enum GradientType { LINEAR, RADIAL};
71 : std::vector<sal_Size> maStops;
72 : basegfx::B2DHomMatrix maTransform;
73 : GradientType meType;
74 : union
75 : {
76 : double test;
77 : struct
78 : {
79 : double mfX1;
80 : double mfX2;
81 : double mfY1;
82 : double mfY2;
83 : } linear;
84 : struct
85 : {
86 : double mfCX;
87 : double mfCY;
88 : double mfFX;
89 : double mfFY;
90 : double mfR;
91 : } radial;
92 : } maCoords;
93 : sal_Int32 mnId;
94 : bool mbBoundingBoxUnits;
95 :
96 : // explicit Gradient(GradientType eType) : maStops(), maTransform(), meType(eType), maCoords.mfCX(0.0), maCoords.mfCY(0.0), maCoords.mfFX(0.0), maCoords.mfFY(0.0), maCoords.mfR(0.0), mnId(0), mbBoundingBoxUnits(false)
97 0 : explicit Gradient(GradientType eType) : maStops(), maTransform(), meType(eType), mnId(0), mbBoundingBoxUnits(false)
98 : {
99 0 : maCoords.radial.mfCX = 0.0;
100 0 : maCoords.radial.mfCY = 0.0;
101 0 : maCoords.radial.mfFX = 0.0;
102 0 : maCoords.radial.mfFY = 0.0;
103 0 : maCoords.radial.mfR = 0.0;
104 0 : }
105 : };
106 :
107 0 : inline bool operator==( const Gradient& rLHS, const Gradient& rRHS )
108 : {
109 0 : if( rLHS.meType != rRHS.meType )
110 0 : return false;
111 0 : if( rLHS.meType == Gradient::LINEAR )
112 0 : return rLHS.mbBoundingBoxUnits==rRHS.mbBoundingBoxUnits && rLHS.maStops==rRHS.maStops &&
113 0 : rLHS.maCoords.linear.mfX1 == rRHS.maCoords.linear.mfX1 && rLHS.maCoords.linear.mfX2 == rRHS.maCoords.linear.mfX2 &&
114 0 : rLHS.maCoords.linear.mfY1 == rRHS.maCoords.linear.mfY1 && rLHS.maCoords.linear.mfY2 == rRHS.maCoords.linear.mfY2;
115 : else
116 0 : return rLHS.mbBoundingBoxUnits==rRHS.mbBoundingBoxUnits && rLHS.maStops==rRHS.maStops &&
117 0 : rLHS.maCoords.radial.mfCX == rRHS.maCoords.radial.mfCX && rLHS.maCoords.radial.mfCY == rRHS.maCoords.radial.mfCY &&
118 0 : rLHS.maCoords.radial.mfFX == rRHS.maCoords.radial.mfFX && rLHS.maCoords.radial.mfFY == rRHS.maCoords.radial.mfFY &&
119 0 : rLHS.maCoords.radial.mfR == rRHS.maCoords.radial.mfR;
120 : }
121 :
122 : enum PaintType
123 : {
124 : NONE,
125 : SOLID,
126 : GRADIENT,
127 : DASH
128 : };
129 :
130 : enum FillRule
131 : {
132 : NON_ZERO,
133 : EVEN_ODD
134 : };
135 :
136 : enum TextAlign
137 : {
138 : BEFORE,
139 : CENTER,
140 : AFTER
141 : };
142 :
143 : enum CapStyle
144 : {
145 : BUTT,
146 : RECT,
147 : ROUND
148 : };
149 :
150 0 : struct State
151 : {
152 0 : State() :
153 : maCTM(),
154 : maTransform(),
155 : maViewport(),
156 : maViewBox(),
157 : mbIsText(false),
158 : maFontFamily(), // app-default
159 : mnFontSize(12),
160 : maFontStyle("normal"),
161 : maFontVariant("normal"),
162 : mnFontWeight(400.0),
163 : meTextAnchor(BEFORE),
164 : meTextDisplayAlign(BEFORE),
165 : mnTextLineIncrement(0.0),
166 : maCurrentColor(1.0),
167 : mbVisibility(true),
168 : meFillType(SOLID),
169 : mnFillOpacity(1.0),
170 : mnOpacity(1.0),
171 : meStrokeType(NONE),
172 : mnStrokeOpacity(1.0),
173 : meViewportFillType(NONE),
174 : mnViewportFillOpacity(1.0),
175 : maFillColor(0.0),
176 : maFillGradient(Gradient::LINEAR),
177 : meFillRule(NON_ZERO),
178 : maStrokeColor(0.0),
179 : maStrokeGradient(Gradient::LINEAR),
180 : maDashArray(),
181 : mnDashOffset(0.0),
182 : meLineCap(BUTT),
183 : meLineJoin(basegfx::B2DLineJoin::Miter),
184 : mnMiterLimit(4.0),
185 : mnStrokeWidth(1.0),
186 : maViewportFillColor(1.0),
187 : maViewportFillGradient(Gradient::LINEAR),
188 0 : mnStyleId(0)
189 0 : {}
190 :
191 : basegfx::B2DHomMatrix maCTM;
192 : basegfx::B2DHomMatrix maTransform;
193 : basegfx::B2DRange maViewport;
194 : basegfx::B2DRange maViewBox;
195 :
196 : bool mbIsText;
197 : OUString maFontFamily;
198 : /** Absolute: xx-small=6.94 | x-small=8.33 | small=10 | medium=12 | large=14.4 | x-large=17.28 | xx-large=20.736
199 :
200 : Relative(to parent): larger (enlarge by 1.2)
201 : smaller (shrink by 1.2)
202 :
203 : */
204 : double mnFontSize;
205 : OUString maFontStyle;
206 : OUString maFontVariant;
207 : double mnFontWeight;
208 :
209 : TextAlign meTextAnchor; // text-anchor
210 : TextAlign meTextDisplayAlign; // display-align
211 : double mnTextLineIncrement; // 0.0 means auto
212 :
213 : ARGBColor maCurrentColor;
214 : bool mbVisibility;
215 :
216 : PaintType meFillType;
217 : double mnFillOpacity;
218 : double mnOpacity;
219 : PaintType meStrokeType;
220 : double mnStrokeOpacity;
221 : PaintType meViewportFillType;
222 : double mnViewportFillOpacity;
223 :
224 : ARGBColor maFillColor;
225 : Gradient maFillGradient;
226 : FillRule meFillRule;
227 :
228 : ARGBColor maStrokeColor;
229 : Gradient maStrokeGradient;
230 : std::vector<double> maDashArray;
231 : double mnDashOffset;
232 : CapStyle meLineCap;
233 : basegfx::B2DLineJoin meLineJoin;
234 : double mnMiterLimit;
235 : double mnStrokeWidth;
236 :
237 : ARGBColor maViewportFillColor;
238 : Gradient maViewportFillGradient;
239 :
240 : sal_Int32 mnStyleId;
241 : };
242 :
243 0 : inline bool operator==(const State& rLHS, const State& rRHS )
244 : {
245 0 : return rLHS.maCTM==rRHS.maCTM &&
246 0 : rLHS.maTransform==rRHS.maTransform &&
247 0 : rLHS.maViewport==rRHS.maViewport &&
248 0 : rLHS.maViewBox==rRHS.maViewBox &&
249 0 : rLHS.mbIsText==rRHS.mbIsText &&
250 0 : rLHS.maFontFamily==rRHS.maFontFamily &&
251 0 : rLHS.mnFontSize==rRHS.mnFontSize &&
252 0 : rLHS.maFontStyle==rRHS.maFontStyle &&
253 0 : rLHS.maFontVariant==rRHS.maFontVariant &&
254 0 : rLHS.mnFontWeight==rRHS.mnFontWeight &&
255 0 : rLHS.meTextAnchor==rRHS.meTextAnchor &&
256 0 : rLHS.meTextDisplayAlign==rRHS.meTextDisplayAlign &&
257 0 : rLHS.mnTextLineIncrement==rRHS.mnTextLineIncrement &&
258 0 : rLHS.maCurrentColor==rRHS.maCurrentColor &&
259 0 : rLHS.mbVisibility==rRHS.mbVisibility &&
260 0 : rLHS.meFillType==rRHS.meFillType &&
261 0 : rLHS.mnFillOpacity==rRHS.mnFillOpacity &&
262 0 : rLHS.mnOpacity==rRHS.mnOpacity &&
263 0 : rLHS.meStrokeType==rRHS.meStrokeType &&
264 0 : rLHS.mnStrokeOpacity==rRHS.mnStrokeOpacity &&
265 0 : rLHS.meViewportFillType==rRHS.meViewportFillType &&
266 0 : rLHS.mnViewportFillOpacity==rRHS.mnViewportFillOpacity &&
267 0 : rLHS.maFillColor==rRHS.maFillColor &&
268 0 : rLHS.maFillGradient==rRHS.maFillGradient &&
269 0 : rLHS.meFillRule==rRHS.meFillRule &&
270 0 : rLHS.maStrokeColor==rRHS.maStrokeColor &&
271 0 : rLHS.maStrokeGradient==rRHS.maStrokeGradient &&
272 0 : rLHS.maDashArray==rRHS.maDashArray &&
273 0 : rLHS.mnDashOffset==rRHS.mnDashOffset &&
274 0 : rLHS.meLineCap==rRHS.meLineCap &&
275 0 : rLHS.meLineJoin==rRHS.meLineJoin &&
276 0 : rLHS.mnMiterLimit==rRHS.mnMiterLimit &&
277 0 : rLHS.mnStrokeWidth==rRHS.mnStrokeWidth &&
278 0 : rLHS.maViewportFillColor==rRHS.maViewportFillColor &&
279 0 : rLHS.maViewportFillGradient==rRHS.maViewportFillGradient;
280 : }
281 :
282 : struct StateHash
283 : {
284 0 : size_t operator()(const State& rState ) const
285 : {
286 0 : return size_t(rState.maCTM.get( 0, 0 ))
287 0 : ^ size_t(rState.maCTM.get( 1, 0 ))
288 0 : ^ size_t(rState.maCTM.get( 0, 1 ))
289 0 : ^ size_t(rState.maCTM.get( 1, 1 ))
290 0 : ^ size_t(rState.maCTM.get( 0, 2 ))
291 0 : ^ size_t(rState.maCTM.get( 1, 2 ))
292 0 : ^ size_t(rState.maViewport.getWidth())
293 0 : ^ size_t(rState.maViewport.getHeight())
294 0 : ^ size_t(rState.maViewBox.getWidth())
295 0 : ^ size_t(rState.maViewBox.getHeight())
296 0 : ^ size_t(rState.mbIsText)
297 0 : ^ size_t(rState.maFontFamily.hashCode())
298 0 : ^ size_t(rState.mnFontSize)
299 0 : ^ size_t(rState.maFontStyle.hashCode())
300 0 : ^ size_t(rState.maFontVariant.hashCode())
301 0 : ^ size_t(rState.mnFontWeight)
302 0 : ^ size_t(rState.meTextAnchor)
303 0 : ^ size_t(rState.meTextDisplayAlign)
304 0 : ^ size_t(rState.mnTextLineIncrement)
305 0 : ^ size_t(rState.mbVisibility)
306 0 : ^ size_t(rState.meFillType)
307 0 : ^ size_t(rState.mnFillOpacity)
308 0 : ^ size_t(rState.mnOpacity)
309 0 : ^ size_t(rState.meStrokeType)
310 0 : ^ size_t(rState.mnStrokeOpacity)
311 0 : ^ size_t(rState.meViewportFillType)
312 0 : ^ size_t(rState.mnViewportFillOpacity)
313 0 : ^ size_t(rState.maFillColor.a)
314 0 : ^ size_t(rState.maFillColor.r)
315 0 : ^ size_t(rState.maFillColor.g)
316 0 : ^ size_t(rState.maFillColor.b)
317 0 : ^ size_t(rState.maFillGradient.maStops.size())
318 0 : ^ size_t(rState.meFillRule)
319 0 : ^ size_t(rState.maStrokeColor.a)
320 0 : ^ size_t(rState.maStrokeColor.r)
321 0 : ^ size_t(rState.maStrokeColor.g)
322 0 : ^ size_t(rState.maStrokeColor.b)
323 0 : ^ size_t(rState.maStrokeGradient.maStops.size())
324 0 : ^ size_t(rState.maDashArray.size())
325 0 : ^ size_t(rState.mnDashOffset)
326 0 : ^ size_t(rState.meLineCap)
327 0 : ^ size_t(rState.meLineJoin)
328 0 : ^ size_t(rState.mnMiterLimit)
329 0 : ^ size_t(rState.mnStrokeWidth)
330 0 : ^ size_t(rState.maViewportFillColor.a)
331 0 : ^ size_t(rState.maViewportFillColor.r)
332 0 : ^ size_t(rState.maViewportFillColor.g)
333 0 : ^ size_t(rState.maViewportFillColor.b)
334 0 : ^ size_t(rState.maViewportFillGradient.maStops.size());
335 : }
336 : };
337 :
338 : typedef std::unordered_set<State, StateHash> StatePool;
339 : typedef std::unordered_map<sal_Int32, State> StateMap;
340 :
341 : } // namespace svgi
342 :
343 : #endif
344 :
345 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|