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 SkSVGValue_DEFINED
9#define SkSVGValue_DEFINED
10
11#include "SkColor.h"
12#include "SkMatrix.h"
13#include "SkPath.h"
14#include "SkSVGTypes.h"
15#include "SkTypes.h"
16
17class SkSVGValue : public SkNoncopyable {
18public:
19    enum class Type {
20        kClip,
21        kColor,
22        kDashArray,
23        kFillRule,
24        kLength,
25        kLineCap,
26        kLineJoin,
27        kNumber,
28        kPaint,
29        kPath,
30        kPoints,
31        kSpreadMethod,
32        kString,
33        kTransform,
34        kViewBox,
35        kVisibility,
36    };
37
38    Type type() const { return fType; }
39
40    template <typename T>
41    const T* as() const {
42        return fType == T::TYPE ? static_cast<const T*>(this) : nullptr;
43    }
44
45protected:
46    SkSVGValue(Type t) : fType(t) { }
47
48private:
49    Type fType;
50
51    typedef SkNoncopyable INHERITED;
52};
53
54template <typename T, SkSVGValue::Type ValueType>
55class SkSVGWrapperValue final : public SkSVGValue {
56public:
57    static constexpr Type TYPE = ValueType;
58
59    explicit SkSVGWrapperValue(const T& v)
60        : INHERITED(ValueType)
61        , fWrappedValue(v) { }
62
63    operator const T&() const { return fWrappedValue; }
64    const T* operator->() const { return &fWrappedValue; }
65
66private:
67    // Stack-only
68    void* operator new(size_t) = delete;
69    void* operator new(size_t, void*) = delete;
70
71    const T& fWrappedValue;
72
73    typedef SkSVGValue INHERITED;
74};
75
76using SkSVGClipValue         = SkSVGWrapperValue<SkSVGClip         , SkSVGValue::Type::kClip      >;
77using SkSVGColorValue        = SkSVGWrapperValue<SkSVGColorType    , SkSVGValue::Type::kColor     >;
78using SkSVGFillRuleValue     = SkSVGWrapperValue<SkSVGFillRule     , SkSVGValue::Type::kFillRule  >;
79using SkSVGLengthValue       = SkSVGWrapperValue<SkSVGLength       , SkSVGValue::Type::kLength    >;
80using SkSVGPathValue         = SkSVGWrapperValue<SkPath            , SkSVGValue::Type::kPath      >;
81using SkSVGTransformValue    = SkSVGWrapperValue<SkSVGTransformType, SkSVGValue::Type::kTransform >;
82using SkSVGViewBoxValue      = SkSVGWrapperValue<SkSVGViewBoxType  , SkSVGValue::Type::kViewBox   >;
83using SkSVGPaintValue        = SkSVGWrapperValue<SkSVGPaint        , SkSVGValue::Type::kPaint     >;
84using SkSVGLineCapValue      = SkSVGWrapperValue<SkSVGLineCap      , SkSVGValue::Type::kLineCap   >;
85using SkSVGLineJoinValue     = SkSVGWrapperValue<SkSVGLineJoin     , SkSVGValue::Type::kLineJoin  >;
86using SkSVGNumberValue       = SkSVGWrapperValue<SkSVGNumberType   , SkSVGValue::Type::kNumber    >;
87using SkSVGPointsValue       = SkSVGWrapperValue<SkSVGPointsType   , SkSVGValue::Type::kPoints    >;
88using SkSVGStringValue       = SkSVGWrapperValue<SkSVGStringType   , SkSVGValue::Type::kString    >;
89using SkSVGSpreadMethodValue = SkSVGWrapperValue<SkSVGSpreadMethod ,
90                                                 SkSVGValue::Type::kSpreadMethod>;
91using SkSVGVisibilityValue   = SkSVGWrapperValue<SkSVGVisibility   , SkSVGValue::Type::kVisibility>;
92using SkSVGDashArrayValue    = SkSVGWrapperValue<SkSVGDashArray    , SkSVGValue::Type::kDashArray >;
93
94#endif // SkSVGValue_DEFINED
95