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 "include/core/SkColor.h"
12 #include "include/core/SkMatrix.h"
13 #include "include/core/SkPath.h"
14 #include "include/core/SkPoint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkScalar.h"
17 #include "include/core/SkString.h"
18 #include "include/core/SkTypes.h"
19 #include "include/private/SkTDArray.h"
20 #include "src/core/SkTLazy.h"
21 
22 using SkSVGColorType     = SkColor;
23 using SkSVGIntegerType   = int;
24 using SkSVGNumberType    = SkScalar;
25 using SkSVGStringType    = SkString;
26 using SkSVGViewBoxType   = SkRect;
27 using SkSVGTransformType = SkMatrix;
28 using SkSVGPointsType    = SkTDArray<SkPoint>;
29 
30 enum class SkSVGPropertyState {
31     kUnspecified,
32     kInherit,
33     kValue,
34 };
35 
36 // https://www.w3.org/TR/SVG11/intro.html#TermProperty
37 template <typename T, bool kInheritable> class SkSVGProperty {
38 public:
39     using ValueT = T;
40 
SkSVGProperty()41     SkSVGProperty() : fState(SkSVGPropertyState::kUnspecified) {}
42 
SkSVGProperty(SkSVGPropertyState state)43     explicit SkSVGProperty(SkSVGPropertyState state) : fState(state) {}
44 
SkSVGProperty(const T & value)45     explicit SkSVGProperty(const T& value) : fState(SkSVGPropertyState::kValue) {
46         fValue.set(value);
47     }
48 
SkSVGProperty(T && value)49     explicit SkSVGProperty(T&& value) : fState(SkSVGPropertyState::kValue) {
50         fValue.set(std::move(value));
51     }
52 
53     template <typename... Args>
init(Args &&...args)54     void init(Args&&... args) {
55         fState = SkSVGPropertyState::kValue;
56         fValue.init(std::forward<Args>(args)...);
57     }
58 
isInheritable()59     constexpr bool isInheritable() const { return kInheritable; }
60 
isValue()61     bool isValue() const { return fState == SkSVGPropertyState::kValue; }
62 
getMaybeNull()63     T* getMaybeNull() const {
64         return fValue.getMaybeNull();
65     }
66 
set(SkSVGPropertyState state)67     void set(SkSVGPropertyState state) {
68         fState = state;
69         if (fState != SkSVGPropertyState::kValue) {
70             fValue.reset();
71         }
72     }
73 
set(const T & value)74     void set(const T& value) {
75         fState = SkSVGPropertyState::kValue;
76         fValue.set(value);
77     }
78 
set(T && value)79     void set(T&& value) {
80         fState = SkSVGPropertyState::kValue;
81         fValue.set(std::move(value));
82     }
83 
84     T* operator->() const {
85         SkASSERT(fState == SkSVGPropertyState::kValue);
86         SkASSERT(fValue.isValid());
87         return fValue.get();
88     }
89 
90     T& operator*() const {
91         SkASSERT(fState == SkSVGPropertyState::kValue);
92         SkASSERT(fValue.isValid());
93         return *fValue;
94     }
95 
96 private:
97     SkSVGPropertyState fState;
98     SkTLazy<T> fValue;
99 };
100 
101 class SkSVGLength {
102 public:
103     enum class Unit {
104         kUnknown,
105         kNumber,
106         kPercentage,
107         kEMS,
108         kEXS,
109         kPX,
110         kCM,
111         kMM,
112         kIN,
113         kPT,
114         kPC,
115     };
116 
SkSVGLength()117     constexpr SkSVGLength()                    : fValue(0), fUnit(Unit::kUnknown) {}
118     explicit constexpr SkSVGLength(SkScalar v, Unit u = Unit::kNumber)
fValue(v)119         : fValue(v), fUnit(u) {}
120     SkSVGLength(const SkSVGLength&)            = default;
121     SkSVGLength& operator=(const SkSVGLength&) = default;
122 
123     bool operator==(const SkSVGLength& other) const {
124         return fUnit == other.fUnit && fValue == other.fValue;
125     }
126     bool operator!=(const SkSVGLength& other) const { return !(*this == other); }
127 
value()128     const SkScalar& value() const { return fValue; }
unit()129     const Unit&     unit()  const { return fUnit;  }
130 
131 private:
132     SkScalar fValue;
133     Unit     fUnit;
134 };
135 
136 // https://www.w3.org/TR/SVG11/linking.html#IRIReference
137 class SkSVGIRI {
138 public:
139     enum class Type {
140         kLocal,
141         kNonlocal,
142         kDataURI,
143     };
144 
SkSVGIRI()145     SkSVGIRI() : fType(Type::kLocal) {}
SkSVGIRI(Type t,const SkSVGStringType & iri)146     SkSVGIRI(Type t, const SkSVGStringType& iri) : fType(t), fIRI(iri) {}
147 
type()148     Type type() const { return fType; }
iri()149     const SkSVGStringType& iri() const { return fIRI; }
150 
151     bool operator==(const SkSVGIRI& other) const {
152         return fType == other.fType && fIRI == other.fIRI;
153     }
154     bool operator!=(const SkSVGIRI& other) const { return !(*this == other); }
155 
156 private:
157     Type fType;
158     SkSVGStringType fIRI;
159 };
160 
161 // https://www.w3.org/TR/SVG11/types.html#InterfaceSVGColor
162 class SkSVGColor {
163 public:
164     enum class Type {
165         kCurrentColor,
166         kColor,
167         kICCColor,
168     };
169 
SkSVGColor()170     SkSVGColor() : fType(Type::kColor), fColor(SK_ColorBLACK) {}
SkSVGColor(Type t)171     explicit SkSVGColor(Type t) : fType(t), fColor(SK_ColorBLACK) {}
SkSVGColor(const SkSVGColorType & c)172     explicit SkSVGColor(const SkSVGColorType& c) : fType(Type::kColor), fColor(c) {}
173     bool operator==(const SkSVGColor& other) const {
174         return fType == other.fType && fColor == other.fColor;
175     }
176     bool operator!=(const SkSVGColor& other) const { return !(*this == other); }
177 
type()178     Type type() const { return fType; }
color()179     const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
180 
181 private:
182     Type fType;
183     SkSVGColorType fColor;
184 };
185 
186 class SkSVGPaint {
187 public:
188     enum class Type {
189         kNone,
190         kColor,
191         kIRI,
192     };
193 
SkSVGPaint()194     SkSVGPaint() : fType(Type::kNone), fColor(SK_ColorBLACK) {}
SkSVGPaint(Type t)195     explicit SkSVGPaint(Type t) : fType(t), fColor(SK_ColorBLACK) {}
SkSVGPaint(const SkSVGColor & c)196     explicit SkSVGPaint(const SkSVGColor& c) : fType(Type::kColor), fColor(c) {}
SkSVGPaint(const SkSVGIRI & iri,const SkSVGColor & fallback_color)197     SkSVGPaint(const SkSVGIRI& iri, const SkSVGColor& fallback_color)
198         : fType(Type::kIRI), fColor(fallback_color), fIRI(iri) {}
199 
200     SkSVGPaint(const SkSVGPaint&)            = default;
201     SkSVGPaint& operator=(const SkSVGPaint&) = default;
202 
203     bool operator==(const SkSVGPaint& other) const {
204         return fType == other.fType && fColor == other.fColor && fIRI == other.fIRI;
205     }
206     bool operator!=(const SkSVGPaint& other) const { return !(*this == other); }
207 
type()208     Type type() const { return fType; }
color()209     const SkSVGColor& color() const {
210         SkASSERT(fType == Type::kColor || fType == Type::kIRI);
211         return fColor;
212     }
iri()213     const SkSVGIRI& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
214 
215 private:
216     Type fType;
217 
218     // Logical union.
219     SkSVGColor fColor;
220     SkSVGIRI   fIRI;
221 };
222 
223 // <funciri> | none (used for clip/mask/filter properties)
224 class SkSVGFuncIRI {
225 public:
226     enum class Type {
227         kNone,
228         kIRI,
229     };
230 
SkSVGFuncIRI()231     SkSVGFuncIRI() : fType(Type::kNone) {}
SkSVGFuncIRI(Type t)232     explicit SkSVGFuncIRI(Type t) : fType(t) {}
SkSVGFuncIRI(SkSVGIRI && iri)233     explicit SkSVGFuncIRI(SkSVGIRI&& iri) : fType(Type::kIRI), fIRI(std::move(iri)) {}
234 
235     bool operator==(const SkSVGFuncIRI& other) const {
236         return fType == other.fType && fIRI == other.fIRI;
237     }
238     bool operator!=(const SkSVGFuncIRI& other) const { return !(*this == other); }
239 
type()240     Type type() const { return fType; }
iri()241     const SkSVGIRI& iri() const { SkASSERT(fType == Type::kIRI); return fIRI; }
242 
243 private:
244     Type           fType;
245     SkSVGIRI       fIRI;
246 };
247 
248 enum class SkSVGLineCap {
249     kButt,
250     kRound,
251     kSquare,
252 };
253 
254 class SkSVGLineJoin {
255 public:
256     enum class Type {
257         kMiter,
258         kRound,
259         kBevel,
260         kInherit,
261     };
262 
SkSVGLineJoin()263     constexpr SkSVGLineJoin() : fType(Type::kInherit) {}
SkSVGLineJoin(Type t)264     constexpr explicit SkSVGLineJoin(Type t) : fType(t) {}
265 
266     SkSVGLineJoin(const SkSVGLineJoin&)            = default;
267     SkSVGLineJoin& operator=(const SkSVGLineJoin&) = default;
268 
269     bool operator==(const SkSVGLineJoin& other) const { return fType == other.fType; }
270     bool operator!=(const SkSVGLineJoin& other) const { return !(*this == other); }
271 
type()272     Type type() const { return fType; }
273 
274 private:
275     Type fType;
276 };
277 
278 class SkSVGSpreadMethod {
279 public:
280     // These values must match Skia's SkShader::TileMode enum.
281     enum class Type {
282         kPad,       // kClamp_TileMode
283         kRepeat,    // kRepeat_TileMode
284         kReflect,   // kMirror_TileMode
285     };
286 
SkSVGSpreadMethod()287     constexpr SkSVGSpreadMethod() : fType(Type::kPad) {}
SkSVGSpreadMethod(Type t)288     constexpr explicit SkSVGSpreadMethod(Type t) : fType(t) {}
289 
290     SkSVGSpreadMethod(const SkSVGSpreadMethod&)            = default;
291     SkSVGSpreadMethod& operator=(const SkSVGSpreadMethod&) = default;
292 
293     bool operator==(const SkSVGSpreadMethod& other) const { return fType == other.fType; }
294     bool operator!=(const SkSVGSpreadMethod& other) const { return !(*this == other); }
295 
type()296     Type type() const { return fType; }
297 
298 private:
299     Type fType;
300 };
301 
302 class SkSVGFillRule {
303 public:
304     enum class Type {
305         kNonZero,
306         kEvenOdd,
307         kInherit,
308     };
309 
SkSVGFillRule()310     constexpr SkSVGFillRule() : fType(Type::kInherit) {}
SkSVGFillRule(Type t)311     constexpr explicit SkSVGFillRule(Type t) : fType(t) {}
312 
313     SkSVGFillRule(const SkSVGFillRule&)            = default;
314     SkSVGFillRule& operator=(const SkSVGFillRule&) = default;
315 
316     bool operator==(const SkSVGFillRule& other) const { return fType == other.fType; }
317     bool operator!=(const SkSVGFillRule& other) const { return !(*this == other); }
318 
type()319     Type type() const { return fType; }
320 
asFillType()321     SkPathFillType asFillType() const {
322         SkASSERT(fType != Type::kInherit); // should never be called for unresolved values.
323         return fType == Type::kEvenOdd ? SkPathFillType::kEvenOdd : SkPathFillType::kWinding;
324     }
325 
326 private:
327     Type fType;
328 };
329 
330 class SkSVGVisibility {
331 public:
332     enum class Type {
333         kVisible,
334         kHidden,
335         kCollapse,
336         kInherit,
337     };
338 
SkSVGVisibility()339     constexpr SkSVGVisibility() : fType(Type::kVisible) {}
SkSVGVisibility(Type t)340     constexpr explicit SkSVGVisibility(Type t) : fType(t) {}
341 
342     SkSVGVisibility(const SkSVGVisibility&)            = default;
343     SkSVGVisibility& operator=(const SkSVGVisibility&) = default;
344 
345     bool operator==(const SkSVGVisibility& other) const { return fType == other.fType; }
346     bool operator!=(const SkSVGVisibility& other) const { return !(*this == other); }
347 
type()348     Type type() const { return fType; }
349 
350 private:
351     Type fType;
352 };
353 
354 class SkSVGDashArray {
355 public:
356     enum class Type {
357         kNone,
358         kDashArray,
359         kInherit,
360     };
361 
SkSVGDashArray()362     SkSVGDashArray()                : fType(Type::kNone) {}
SkSVGDashArray(Type t)363     explicit SkSVGDashArray(Type t) : fType(t) {}
SkSVGDashArray(SkTDArray<SkSVGLength> && dashArray)364     explicit SkSVGDashArray(SkTDArray<SkSVGLength>&& dashArray)
365         : fType(Type::kDashArray)
366         , fDashArray(std::move(dashArray)) {}
367 
368     SkSVGDashArray(const SkSVGDashArray&)            = default;
369     SkSVGDashArray& operator=(const SkSVGDashArray&) = default;
370 
371     bool operator==(const SkSVGDashArray& other) const {
372         return fType == other.fType && fDashArray == other.fDashArray;
373     }
374     bool operator!=(const SkSVGDashArray& other) const { return !(*this == other); }
375 
type()376     Type type() const { return fType; }
377 
dashArray()378     const SkTDArray<SkSVGLength>& dashArray() const { return fDashArray; }
379 
380 private:
381     Type fType;
382     SkTDArray<SkSVGLength> fDashArray;
383 };
384 
385 class SkSVGStopColor {
386 public:
387     enum class Type {
388         kColor,
389         kCurrentColor,
390         kICCColor,
391         kInherit,
392     };
393 
SkSVGStopColor()394     SkSVGStopColor() : fType(Type::kColor), fColor(SK_ColorBLACK) {}
SkSVGStopColor(Type t)395     explicit SkSVGStopColor(Type t) : fType(t), fColor(SK_ColorBLACK) {}
SkSVGStopColor(const SkSVGColorType & c)396     explicit SkSVGStopColor(const SkSVGColorType& c) : fType(Type::kColor), fColor(c) {}
397 
398     SkSVGStopColor(const SkSVGStopColor&)            = default;
399     SkSVGStopColor& operator=(const SkSVGStopColor&) = default;
400 
401     bool operator==(const SkSVGStopColor& other) const {
402         return fType == other.fType && fColor == other.fColor;
403     }
404     bool operator!=(const SkSVGStopColor& other) const { return !(*this == other); }
405 
type()406     Type type() const { return fType; }
color()407     const SkSVGColorType& color() const { SkASSERT(fType == Type::kColor); return fColor; }
408 
409 private:
410     Type fType;
411     SkSVGColorType fColor;
412 };
413 
414 class SkSVGObjectBoundingBoxUnits {
415 public:
416     enum class Type {
417         kUserSpaceOnUse,
418         kObjectBoundingBox,
419     };
420 
SkSVGObjectBoundingBoxUnits()421     SkSVGObjectBoundingBoxUnits() : fType(Type::kUserSpaceOnUse) {}
SkSVGObjectBoundingBoxUnits(Type t)422     explicit SkSVGObjectBoundingBoxUnits(Type t) : fType(t) {}
423 
424     bool operator==(const SkSVGObjectBoundingBoxUnits& other) const {
425         return fType == other.fType;
426     }
427     bool operator!=(const SkSVGObjectBoundingBoxUnits& other) const {
428         return !(*this == other);
429     }
430 
type()431     Type type() const { return fType; }
432 
433 private:
434     Type fType;
435 };
436 
437 class SkSVGFontFamily {
438 public:
439     enum class Type {
440         kFamily,
441         kInherit,
442     };
443 
SkSVGFontFamily()444     SkSVGFontFamily() : fType(Type::kInherit) {}
SkSVGFontFamily(const char family[])445     explicit SkSVGFontFamily(const char family[])
446         : fType(Type::kFamily)
447         , fFamily(family) {}
448 
449     bool operator==(const SkSVGFontFamily& other) const {
450         return fType == other.fType && fFamily == other.fFamily;
451     }
452     bool operator!=(const SkSVGFontFamily& other) const { return !(*this == other); }
453 
type()454     Type type() const { return fType; }
455 
family()456     const SkString& family() const { return fFamily; }
457 
458 private:
459     Type     fType;
460     SkString fFamily;
461 };
462 
463 class SkSVGFontStyle {
464 public:
465     enum class Type {
466         kNormal,
467         kItalic,
468         kOblique,
469         kInherit,
470     };
471 
SkSVGFontStyle()472     SkSVGFontStyle() : fType(Type::kInherit) {}
SkSVGFontStyle(Type t)473     explicit SkSVGFontStyle(Type t) : fType(t) {}
474 
475     bool operator==(const SkSVGFontStyle& other) const {
476         return fType == other.fType;
477     }
478     bool operator!=(const SkSVGFontStyle& other) const { return !(*this == other); }
479 
type()480     Type type() const { return fType; }
481 
482 private:
483     Type fType;
484 };
485 
486 class SkSVGFontSize {
487 public:
488     enum class Type {
489         kLength,
490         kInherit,
491     };
492 
SkSVGFontSize()493     SkSVGFontSize() : fType(Type::kInherit), fSize(0) {}
SkSVGFontSize(const SkSVGLength & s)494     explicit SkSVGFontSize(const SkSVGLength& s)
495         : fType(Type::kLength)
496         , fSize(s) {}
497 
498     bool operator==(const SkSVGFontSize& other) const {
499         return fType == other.fType && fSize == other.fSize;
500     }
501     bool operator!=(const SkSVGFontSize& other) const { return !(*this == other); }
502 
type()503     Type type() const { return fType; }
504 
size()505     const SkSVGLength& size() const { return fSize; }
506 
507 private:
508     Type        fType;
509     SkSVGLength fSize;
510 };
511 
512 class SkSVGFontWeight {
513 public:
514     enum class Type {
515         k100,
516         k200,
517         k300,
518         k400,
519         k500,
520         k600,
521         k700,
522         k800,
523         k900,
524         kNormal,
525         kBold,
526         kBolder,
527         kLighter,
528         kInherit,
529     };
530 
SkSVGFontWeight()531     SkSVGFontWeight() : fType(Type::kInherit) {}
SkSVGFontWeight(Type t)532     explicit SkSVGFontWeight(Type t) : fType(t) {}
533 
534     bool operator==(const SkSVGFontWeight& other) const {
535         return fType == other.fType;
536     }
537     bool operator!=(const SkSVGFontWeight& other) const { return !(*this == other); }
538 
type()539     Type type() const { return fType; }
540 
541 private:
542     Type fType;
543 };
544 
545 struct SkSVGPreserveAspectRatio {
546     enum Align : uint8_t {
547         // These values are chosen such that bits [0,1] encode X alignment, and
548         // bits [2,3] encode Y alignment.
549         kXMinYMin = 0x00,
550         kXMidYMin = 0x01,
551         kXMaxYMin = 0x02,
552         kXMinYMid = 0x04,
553         kXMidYMid = 0x05,
554         kXMaxYMid = 0x06,
555         kXMinYMax = 0x08,
556         kXMidYMax = 0x09,
557         kXMaxYMax = 0x0a,
558 
559         kNone     = 0x10,
560     };
561 
562     enum Scale {
563         kMeet,
564         kSlice,
565     };
566 
567     Align fAlign = kXMidYMid;
568     Scale fScale = kMeet;
569 };
570 
571 class SkSVGTextAnchor {
572 public:
573     enum class Type {
574         kStart,
575         kMiddle,
576         kEnd,
577         kInherit,
578     };
579 
SkSVGTextAnchor()580     SkSVGTextAnchor() : fType(Type::kInherit) {}
SkSVGTextAnchor(Type t)581     explicit SkSVGTextAnchor(Type t) : fType(t) {}
582 
583     bool operator==(const SkSVGTextAnchor& other) const {
584         return fType == other.fType;
585     }
586     bool operator!=(const SkSVGTextAnchor& other) const { return !(*this == other); }
587 
type()588     Type type() const { return fType; }
589 
590 private:
591     Type fType;
592 };
593 
594 // https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveInAttribute
595 class SkSVGFeInputType {
596 public:
597     enum class Type {
598         kSourceGraphic,
599         kSourceAlpha,
600         kBackgroundImage,
601         kBackgroundAlpha,
602         kFillPaint,
603         kStrokePaint,
604         kFilterPrimitiveReference,
605         kUnspecified,
606     };
607 
SkSVGFeInputType()608     SkSVGFeInputType() : fType(Type::kUnspecified) {}
SkSVGFeInputType(Type t)609     explicit SkSVGFeInputType(Type t) : fType(t) {}
SkSVGFeInputType(const SkSVGStringType & id)610     explicit SkSVGFeInputType(const SkSVGStringType& id)
611             : fType(Type::kFilterPrimitiveReference), fId(id) {}
612 
613     bool operator==(const SkSVGFeInputType& other) const {
614         return fType == other.fType && fId == other.fId;
615     }
616     bool operator!=(const SkSVGFeInputType& other) const { return !(*this == other); }
617 
id()618     const SkString& id() const {
619         SkASSERT(fType == Type::kFilterPrimitiveReference);
620         return fId;
621     }
622 
type()623     Type type() const { return fType; }
624 
625 private:
626     Type fType;
627     SkString fId;
628 };
629 
630 enum class SkSVGFeColorMatrixType {
631     kMatrix,
632     kSaturate,
633     kHueRotate,
634     kLuminanceToAlpha,
635 };
636 
637 using SkSVGFeColorMatrixValues = SkTDArray<SkSVGNumberType>;
638 
639 enum class SkSVGFeCompositeOperator {
640     kOver,
641     kIn,
642     kOut,
643     kAtop,
644     kXor,
645     kArithmetic,
646 };
647 
648 class SkSVGFeTurbulenceBaseFrequency {
649 public:
SkSVGFeTurbulenceBaseFrequency()650     SkSVGFeTurbulenceBaseFrequency() : fFreqX(0), fFreqY(0) {}
SkSVGFeTurbulenceBaseFrequency(SkSVGNumberType freqX,SkSVGNumberType freqY)651     SkSVGFeTurbulenceBaseFrequency(SkSVGNumberType freqX, SkSVGNumberType freqY)
652             : fFreqX(freqX), fFreqY(freqY) {}
653 
freqX()654     SkSVGNumberType freqX() const { return fFreqX; }
freqY()655     SkSVGNumberType freqY() const { return fFreqY; }
656 
657 private:
658     SkSVGNumberType fFreqX;
659     SkSVGNumberType fFreqY;
660 };
661 
662 struct SkSVGFeTurbulenceType {
663     enum Type {
664         kFractalNoise,
665         kTurbulence,
666     };
667 
668     Type fType;
669 
SkSVGFeTurbulenceTypeSkSVGFeTurbulenceType670     SkSVGFeTurbulenceType() : fType(kTurbulence) {}
SkSVGFeTurbulenceTypeSkSVGFeTurbulenceType671     explicit SkSVGFeTurbulenceType(Type type) : fType(type) {}
672 };
673 
674 enum class SkSVGXmlSpace {
675     kDefault,
676     kPreserve,
677 };
678 
679 enum class SkSVGColorspace {
680     kAuto,
681     kSRGB,
682     kLinearRGB,
683 };
684 
685 // https://www.w3.org/TR/SVG11/painting.html#DisplayProperty
686 enum class SkSVGDisplay {
687     kInline,
688     kNone,
689 };
690 
691 #endif // SkSVGTypes_DEFINED
692