1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkSVGTypes_DEFINED
9#define SkSVGTypes_DEFINED
10
11#include "SkColor.h"
12#include "SkMatrix.h"
13#include "SkPath.h"
14#include "SkPoint.h"
15#include "SkRect.h"
16#include "SkScalar.h"
17#include "SkString.h"
18#include "SkTDArray.h"
19#include "SkTypes.h"
20
21template <typename T>
22class SkSVGPrimitiveTypeWrapper {
23public:
24    SkSVGPrimitiveTypeWrapper() = default;
25    explicit constexpr SkSVGPrimitiveTypeWrapper(T v) : fValue(v) {}
26
27    SkSVGPrimitiveTypeWrapper(const SkSVGPrimitiveTypeWrapper&)            = default;
28    SkSVGPrimitiveTypeWrapper& operator=(const SkSVGPrimitiveTypeWrapper&) = default;
29    SkSVGPrimitiveTypeWrapper& operator=(const T& v) { fValue = v; return *this; }
30
31    bool operator==(const SkSVGPrimitiveTypeWrapper<T>& other) const {
32        return fValue == other.fValue;
33    }
34    bool operator!=(const SkSVGPrimitiveTypeWrapper<T>& other) const {
35        return !(*this == other);
36    }
37
38    const T& value() const { return fValue; }
39    operator const T&() const { return fValue; }
40
41private:
42    T fValue;
43};
44
45using SkSVGColorType      = SkSVGPrimitiveTypeWrapper<SkColor >;
46using SkSVGNumberType     = SkSVGPrimitiveTypeWrapper<SkScalar>;
47using SkSVGStringType     = SkSVGPrimitiveTypeWrapper<SkString>;
48using SkSVGViewBoxType    = SkSVGPrimitiveTypeWrapper<SkRect  >;
49using SkSVGTransformType  = SkSVGPrimitiveTypeWrapper<SkMatrix>;
50using SkSVGPointsType     = SkSVGPrimitiveTypeWrapper<SkTDArray<SkPoint>>;
51
52class SkSVGLength {
53public:
54    enum class Unit {
55        kUnknown,
56        kNumber,
57        kPercentage,
58        kEMS,
59        kEXS,
60        kPX,
61        kCM,
62        kMM,
63        kIN,
64        kPT,
65        kPC,
66    };
67
68    constexpr SkSVGLength()                    : fValue(0), fUnit(Unit::kUnknown) {}
69    explicit constexpr SkSVGLength(SkScalar v, Unit u = Unit::kNumber)
70        : fValue(v), fUnit(u) {}
71    SkSVGLength(const SkSVGLength&)            = default;
72    SkSVGLength& operator=(const SkSVGLength&) = default;
73
74    bool operator==(const SkSVGLength& other) const {
75        return fUnit == other.fUnit && fValue == other.fValue;
76    }
77    bool operator!=(const SkSVGLength& other) const { return !(*this == other); }
78
79    const SkScalar& value() const { return fValue; }
80    const Unit&     unit()  const { return fUnit;  }
81
82private:
83    SkScalar fValue;
84    Unit     fUnit;
85};
86
87class SkSVGPaint {
88public:
89    enum class Type {
90        kNone,
91        kCurrentColor,
92        kColor,
93        kInherit,
94        kIRI,
95    };
96
97    SkSVGPaint() : fType(Type::kInherit), fColor(SK_ColorBLACK) {}
98    explicit SkSVGPaint(Type t) : fType(t), fColor(SK_ColorBLACK) {}
99    explicit SkSVGPaint(const SkSVGColorType& c) : fType(Type::kColor), fColor(c) {}
100    explicit SkSVGPaint(const SkString& iri)
101        : fType(Type::kIRI), fColor(SK_ColorBLACK), fIRI(iri) {}
102
103    SkSVGPaint(const SkSVGPaint&)            = default;
104    SkSVGPaint& operator=(const SkSVGPaint&) = default;
105
106    bool operator==(const SkSVGPaint& other) const {
107        return fType == other.fType && fColor == other.fColor && fIRI == other.fIRI;
108    }
109    bool operator!=(const SkSVGPaint& other) const { return !(*this == other); }
110
111    Type type() const { return fType; }
112    const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
113    const SkString& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
114
115private:
116    Type fType;
117
118    // Logical union.
119    SkSVGColorType fColor;
120    SkString       fIRI;
121};
122
123class SkSVGClip {
124public:
125    enum class Type {
126        kNone,
127        kInherit,
128        kIRI,
129    };
130
131    SkSVGClip() : fType(Type::kNone) {}
132    explicit SkSVGClip(Type t) : fType(t)           {}
133    explicit SkSVGClip(const SkString& iri) : fType(Type::kIRI), fIRI(iri) {}
134
135    SkSVGClip(const SkSVGClip&)            = default;
136    SkSVGClip& operator=(const SkSVGClip&) = default;
137
138    bool operator==(const SkSVGClip& other) const {
139        return fType == other.fType && fIRI == other.fIRI;
140    }
141    bool operator!=(const SkSVGClip& other) const { return !(*this == other); }
142
143    Type type() const { return fType; }
144    const SkString& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
145
146private:
147    Type           fType;
148    SkString       fIRI;
149};
150
151class SkSVGLineCap {
152public:
153    enum class Type {
154        kButt,
155        kRound,
156        kSquare,
157        kInherit,
158    };
159
160    constexpr SkSVGLineCap() : fType(Type::kInherit) {}
161    constexpr explicit SkSVGLineCap(Type t) : fType(t) {}
162
163    SkSVGLineCap(const SkSVGLineCap&)            = default;
164    SkSVGLineCap& operator=(const SkSVGLineCap&) = default;
165
166    bool operator==(const SkSVGLineCap& other) const { return fType == other.fType; }
167    bool operator!=(const SkSVGLineCap& other) const { return !(*this == other); }
168
169    Type type() const { return fType; }
170
171private:
172    Type fType;
173};
174
175class SkSVGLineJoin {
176public:
177    enum class Type {
178        kMiter,
179        kRound,
180        kBevel,
181        kInherit,
182    };
183
184    constexpr SkSVGLineJoin() : fType(Type::kInherit) {}
185    constexpr explicit SkSVGLineJoin(Type t) : fType(t) {}
186
187    SkSVGLineJoin(const SkSVGLineJoin&)            = default;
188    SkSVGLineJoin& operator=(const SkSVGLineJoin&) = default;
189
190    bool operator==(const SkSVGLineJoin& other) const { return fType == other.fType; }
191    bool operator!=(const SkSVGLineJoin& other) const { return !(*this == other); }
192
193    Type type() const { return fType; }
194
195private:
196    Type fType;
197};
198
199class SkSVGSpreadMethod {
200public:
201    // These values must match Skia's SkShader::TileMode enum.
202    enum class Type {
203        kPad,       // kClamp_TileMode
204        kRepeat,    // kRepeat_TileMode
205        kReflect,   // kMirror_TileMode
206    };
207
208    constexpr SkSVGSpreadMethod() : fType(Type::kPad) {}
209    constexpr explicit SkSVGSpreadMethod(Type t) : fType(t) {}
210
211    SkSVGSpreadMethod(const SkSVGSpreadMethod&)            = default;
212    SkSVGSpreadMethod& operator=(const SkSVGSpreadMethod&) = default;
213
214    bool operator==(const SkSVGSpreadMethod& other) const { return fType == other.fType; }
215    bool operator!=(const SkSVGSpreadMethod& other) const { return !(*this == other); }
216
217    Type type() const { return fType; }
218
219private:
220    Type fType;
221};
222
223class SkSVGFillRule {
224public:
225    enum class Type {
226        kNonZero,
227        kEvenOdd,
228        kInherit,
229    };
230
231    constexpr SkSVGFillRule() : fType(Type::kInherit) {}
232    constexpr explicit SkSVGFillRule(Type t) : fType(t) {}
233
234    SkSVGFillRule(const SkSVGFillRule&)            = default;
235    SkSVGFillRule& operator=(const SkSVGFillRule&) = default;
236
237    bool operator==(const SkSVGFillRule& other) const { return fType == other.fType; }
238    bool operator!=(const SkSVGFillRule& other) const { return !(*this == other); }
239
240    Type type() const { return fType; }
241
242    SkPath::FillType asFillType() const {
243        SkASSERT(fType != Type::kInherit); // should never be called for unresolved values.
244        return fType == Type::kEvenOdd ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
245    }
246
247private:
248    Type fType;
249};
250
251class SkSVGVisibility {
252public:
253    enum class Type {
254        kVisible,
255        kHidden,
256        kCollapse,
257        kInherit,
258    };
259
260    constexpr SkSVGVisibility() : fType(Type::kVisible) {}
261    constexpr explicit SkSVGVisibility(Type t) : fType(t) {}
262
263    SkSVGVisibility(const SkSVGVisibility&)            = default;
264    SkSVGVisibility& operator=(const SkSVGVisibility&) = default;
265
266    bool operator==(const SkSVGVisibility& other) const { return fType == other.fType; }
267    bool operator!=(const SkSVGVisibility& other) const { return !(*this == other); }
268
269    Type type() const { return fType; }
270
271private:
272    Type fType;
273};
274
275class SkSVGDashArray {
276public:
277    enum class Type {
278        kNone,
279        kDashArray,
280        kInherit,
281    };
282
283    SkSVGDashArray()                : fType(Type::kNone) {}
284    explicit SkSVGDashArray(Type t) : fType(t) {}
285    explicit SkSVGDashArray(SkTDArray<SkSVGLength>&& dashArray)
286        : fType(Type::kDashArray)
287        , fDashArray(std::move(dashArray)) {}
288
289    SkSVGDashArray(const SkSVGDashArray&)            = default;
290    SkSVGDashArray& operator=(const SkSVGDashArray&) = default;
291
292    bool operator==(const SkSVGDashArray& other) const {
293        return fType == other.fType && fDashArray == other.fDashArray;
294    }
295    bool operator!=(const SkSVGDashArray& other) const { return !(*this == other); }
296
297    Type type() const { return fType; }
298
299    const SkTDArray<SkSVGLength>& dashArray() const { return fDashArray; }
300
301private:
302    Type fType;
303    SkTDArray<SkSVGLength> fDashArray;
304};
305
306#endif // SkSVGTypes_DEFINED
307