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