blob: 7f1c3b60c29ccfbcbfd8a4f6f8860a2487f1db45 [file] [log] [blame]
Florin Malitafa7e9a82018-05-04 15:10:54 -04001/*
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 "SkottieJson.h"
9
10#include "SkData.h"
11#include "SkScalar.h"
12#include "SkPath.h"
13#include "SkPoint.h"
14#include "SkStream.h"
15#include "SkString.h"
16#include "SkottieValue.h"
Florin Malitafa7e9a82018-05-04 15:10:54 -040017#include <vector>
18
19namespace skottie {
20
Florin Malita7d42c442018-06-14 16:16:01 -040021using namespace skjson;
Florin Malitafa7e9a82018-05-04 15:10:54 -040022
23template <>
Florin Malita7d42c442018-06-14 16:16:01 -040024bool Parse<SkScalar>(const Value& v, SkScalar* s) {
Florin Malitafa7e9a82018-05-04 15:10:54 -040025 // Some versions wrap values as single-element arrays.
Florin Malita7d42c442018-06-14 16:16:01 -040026 if (const skjson::ArrayValue* array = v) {
Florin Malitaf5ac9062018-06-19 12:55:53 -040027 if (array->size() > 0) {
Florin Malita7d42c442018-06-14 16:16:01 -040028 return Parse((*array)[0], s);
29 }
Florin Malitafa7e9a82018-05-04 15:10:54 -040030 }
31
Florin Malita7d42c442018-06-14 16:16:01 -040032 if (const skjson::NumberValue* num = v) {
33 *s = static_cast<SkScalar>(**num);
34 return true;
35 }
Florin Malitafa7e9a82018-05-04 15:10:54 -040036
Florin Malita7d42c442018-06-14 16:16:01 -040037 return false;
Florin Malitafa7e9a82018-05-04 15:10:54 -040038}
39
40template <>
Florin Malita7d42c442018-06-14 16:16:01 -040041bool Parse<bool>(const Value& v, bool* b) {
42 switch(v.getType()) {
43 case Value::Type::kNumber:
44 *b = SkToBool(*v.as<NumberValue>());
Florin Malitafa7e9a82018-05-04 15:10:54 -040045 return true;
Florin Malita7d42c442018-06-14 16:16:01 -040046 case Value::Type::kBool:
47 *b = *v.as<BoolValue>();
Florin Malitafa7e9a82018-05-04 15:10:54 -040048 return true;
49 default:
50 break;
51 }
52
53 return false;
54}
55
Florin Malita73154ba2018-08-09 17:29:14 -040056template <typename T>
57bool ParseIntegral(const Value& v, T* result) {
Florin Malita7d42c442018-06-14 16:16:01 -040058 if (const skjson::NumberValue* num = v) {
59 const auto dbl = **num;
Florin Malita73154ba2018-08-09 17:29:14 -040060 *result = static_cast<T>(dbl);
61 return static_cast<double>(*result) == dbl;
Florin Malita7d42c442018-06-14 16:16:01 -040062 }
Florin Malitafa7e9a82018-05-04 15:10:54 -040063
Florin Malita7d42c442018-06-14 16:16:01 -040064 return false;
Florin Malitafa7e9a82018-05-04 15:10:54 -040065}
66
67template <>
Florin Malita73154ba2018-08-09 17:29:14 -040068bool Parse<int>(const Value& v, int* i) {
69 return ParseIntegral(v, i);
70}
71
72template <>
73bool Parse<size_t>(const Value& v, size_t* sz) {
74 return ParseIntegral(v, sz);
75}
76
77template <>
Florin Malita7d42c442018-06-14 16:16:01 -040078bool 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 }
Florin Malitafa7e9a82018-05-04 15:10:54 -040083
Florin Malita7d42c442018-06-14 16:16:01 -040084 return false;
Florin Malitafa7e9a82018-05-04 15:10:54 -040085}
86
87template <>
Florin Malita7d42c442018-06-14 16:16:01 -040088bool Parse<SkPoint>(const Value& v, SkPoint* pt) {
89 if (!v.is<ObjectValue>())
Florin Malitafa7e9a82018-05-04 15:10:54 -040090 return false;
Florin Malita7d42c442018-06-14 16:16:01 -040091 const auto& ov = v.as<ObjectValue>();
Florin Malitafa7e9a82018-05-04 15:10:54 -040092
Florin Malitaf5ac9062018-06-19 12:55:53 -040093 return Parse<SkScalar>(ov["x"], &pt->fX)
94 && Parse<SkScalar>(ov["y"], &pt->fY);
Florin Malitafa7e9a82018-05-04 15:10:54 -040095}
96
97template <>
Florin Malita7d42c442018-06-14 16:16:01 -040098bool Parse<std::vector<float>>(const Value& v, std::vector<float>* vec) {
99 if (!v.is<ArrayValue>())
Florin Malitafa7e9a82018-05-04 15:10:54 -0400100 return false;
Florin Malita7d42c442018-06-14 16:16:01 -0400101 const auto& av = v.as<ArrayValue>();
Florin Malitafa7e9a82018-05-04 15:10:54 -0400102
Florin Malita7d42c442018-06-14 16:16:01 -0400103 vec->resize(av.size());
104 for (size_t i = 0; i < av.size(); ++i) {
105 if (!Parse(av[i], vec->data() + i)) {
Florin Malitafa7e9a82018-05-04 15:10:54 -0400106 return false;
107 }
108 }
109
110 return true;
111}
112
Florin Malitafa7e9a82018-05-04 15:10:54 -0400113} // namespace skottie