| /* |
| * Copyright 2018 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "modules/skottie/src/SkottieJson.h" |
| |
| #include "include/core/SkData.h" |
| #include "include/core/SkPath.h" |
| #include "include/core/SkPoint.h" |
| #include "include/core/SkScalar.h" |
| #include "include/core/SkStream.h" |
| #include "include/core/SkString.h" |
| #include "modules/skottie/src/SkottieValue.h" |
| #include <vector> |
| |
| namespace skottie { |
| |
| using namespace skjson; |
| |
| template <> |
| bool Parse<SkScalar>(const Value& v, SkScalar* s) { |
| // Some versions wrap values as single-element arrays. |
| if (const skjson::ArrayValue* array = v) { |
| if (array->size() > 0) { |
| return Parse((*array)[0], s); |
| } |
| } |
| |
| if (const skjson::NumberValue* num = v) { |
| *s = static_cast<SkScalar>(**num); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| template <> |
| bool Parse<bool>(const Value& v, bool* b) { |
| switch(v.getType()) { |
| case Value::Type::kNumber: |
| *b = SkToBool(*v.as<NumberValue>()); |
| return true; |
| case Value::Type::kBool: |
| *b = *v.as<BoolValue>(); |
| return true; |
| default: |
| break; |
| } |
| |
| return false; |
| } |
| |
| template <typename T> |
| bool ParseIntegral(const Value& v, T* result) { |
| if (const skjson::NumberValue* num = v) { |
| const auto dbl = **num; |
| *result = static_cast<T>(dbl); |
| return static_cast<double>(*result) == dbl; |
| } |
| |
| return false; |
| } |
| |
| template <> |
| bool Parse<int>(const Value& v, int* i) { |
| return ParseIntegral(v, i); |
| } |
| |
| template <> |
| bool Parse<size_t>(const Value& v, size_t* sz) { |
| return ParseIntegral(v, sz); |
| } |
| |
| template <> |
| bool Parse<SkString>(const Value& v, SkString* s) { |
| if (const skjson::StringValue* sv = v) { |
| s->set(sv->begin(), sv->size()); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| template <> |
| bool Parse<SkV2>(const Value& v, SkV2* v2) { |
| if (!v.is<ArrayValue>()) |
| return false; |
| const auto& av = v.as<ArrayValue>(); |
| |
| // We need at least two scalars (BM sometimes exports a third value == 0). |
| return av.size() >= 2 |
| && Parse<SkScalar>(av[0], &v2->x) |
| && Parse<SkScalar>(av[1], &v2->y); |
| } |
| |
| template <> |
| bool Parse<SkPoint>(const Value& v, SkPoint* pt) { |
| if (!v.is<ObjectValue>()) |
| return false; |
| const auto& ov = v.as<ObjectValue>(); |
| |
| return Parse<SkScalar>(ov["x"], &pt->fX) |
| && Parse<SkScalar>(ov["y"], &pt->fY); |
| } |
| |
| template <> |
| bool Parse<VectorValue>(const Value& v, VectorValue* vec) { |
| if (!v.is<ArrayValue>()) |
| return false; |
| const auto& av = v.as<ArrayValue>(); |
| |
| vec->resize(av.size()); |
| for (size_t i = 0; i < av.size(); ++i) { |
| if (!Parse(av[i], vec->data() + i)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| } // namespace skottie |