• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 #include "modules/skottie/src/SkottieJson.h"
9 
10 #include "include/core/SkData.h"
11 #include "include/core/SkPath.h"
12 #include "include/core/SkPoint.h"
13 #include "include/core/SkScalar.h"
14 #include "include/core/SkStream.h"
15 #include "include/core/SkString.h"
16 #include "modules/skottie/src/SkottieValue.h"
17 #include <vector>
18 
19 namespace skottie {
20 
21 using namespace skjson;
22 
23 template <>
Parse(const Value & v,SkScalar * s)24 bool Parse<SkScalar>(const Value& v, SkScalar* s) {
25     // Some versions wrap values as single-element arrays.
26     if (const skjson::ArrayValue* array = v) {
27         if (array->size() > 0) {
28             return Parse((*array)[0], s);
29         }
30     }
31 
32     if (const skjson::NumberValue* num = v) {
33         *s = static_cast<SkScalar>(**num);
34         return true;
35     }
36 
37     return false;
38 }
39 
40 template <>
Parse(const Value & v,bool * b)41 bool Parse<bool>(const Value& v, bool* b) {
42     switch(v.getType()) {
43     case Value::Type::kNumber:
44         *b = SkToBool(*v.as<NumberValue>());
45         return true;
46     case Value::Type::kBool:
47         *b = *v.as<BoolValue>();
48         return true;
49     default:
50         break;
51     }
52 
53     return false;
54 }
55 
56 template <typename T>
ParseIntegral(const Value & v,T * result)57 bool ParseIntegral(const Value& v, T* result) {
58     if (const skjson::NumberValue* num = v) {
59         const auto dbl = **num;
60         *result = static_cast<T>(dbl);
61         return static_cast<double>(*result) == dbl;
62     }
63 
64     return false;
65 }
66 
67 template <>
Parse(const Value & v,int * i)68 bool Parse<int>(const Value& v, int* i) {
69     return ParseIntegral(v, i);
70 }
71 
72 template <>
Parse(const Value & v,size_t * sz)73 bool Parse<size_t>(const Value& v, size_t* sz) {
74     return ParseIntegral(v, sz);
75 }
76 
77 template <>
Parse(const Value & v,SkString * s)78 bool Parse<SkString>(const Value& v, SkString* s) {
79     if (const skjson::StringValue* sv = v) {
80         s->set(sv->begin(), sv->size());
81         return true;
82     }
83 
84     return false;
85 }
86 
87 template <>
Parse(const Value & v,SkV2 * v2)88 bool Parse<SkV2>(const Value& v, SkV2* v2) {
89     if (!v.is<ArrayValue>())
90         return false;
91     const auto& av = v.as<ArrayValue>();
92 
93     // We need at least two scalars (BM sometimes exports a third value == 0).
94     return av.size() >= 2
95         && Parse<SkScalar>(av[0], &v2->x)
96         && Parse<SkScalar>(av[1], &v2->y);
97 }
98 
99 template <>
Parse(const Value & v,SkPoint * pt)100 bool Parse<SkPoint>(const Value& v, SkPoint* pt) {
101     if (!v.is<ObjectValue>())
102         return false;
103     const auto& ov = v.as<ObjectValue>();
104 
105     return Parse<SkScalar>(ov["x"], &pt->fX)
106         && Parse<SkScalar>(ov["y"], &pt->fY);
107 }
108 
109 template <>
Parse(const Value & v,VectorValue * vec)110 bool Parse<VectorValue>(const Value& v, VectorValue* vec) {
111     if (!v.is<ArrayValue>())
112         return false;
113     const auto& av = v.as<ArrayValue>();
114 
115     vec->resize(av.size());
116     for (size_t i = 0; i < av.size(); ++i) {
117         if (!Parse(av[i], vec->data() + i)) {
118             return false;
119         }
120     }
121 
122     return true;
123 }
124 
125 } // namespace skottie
126