Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / modules / particles / include / SkParticleSerialization.h
1 /*
2 * Copyright 2019 Google LLC
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 SkParticleSerialization_DEFINED
9 #define SkParticleSerialization_DEFINED
10
11 #include "modules/particles/include/SkReflected.h"
12
13 #include "include/core/SkString.h"
14 #include "include/private/SkTArray.h"
15 #include "src/utils/SkJSON.h"
16 #include "src/utils/SkJSONWriter.h"
17
18 class SkToJsonVisitor : public SkFieldVisitor {
19 public:
20     SkToJsonVisitor(SkJSONWriter& writer) : fWriter(writer) {}
21
22     // Primitives
23     void visit(const char* name, float& f) override {
24         fWriter.appendFloat(name, f);
25     }
26     void visit(const char* name, int& i) override {
27         fWriter.appendS32(name, i);
28     }
29     void visit(const char* name, bool& b) override {
30         fWriter.appendBool(name, b);
31     }
32     void visit(const char* name, SkString& s) override {
33         if (s.contains('\n')) {
34             SkTArray<SkString> lines;
35             SkStrSplit(s.c_str(), "\n", kStrict_SkStrSplitMode, &lines);
36             fWriter.beginArray(name);
37             for (const auto& line : lines) {
38                 fWriter.appendString(line.c_str());
39             }
40             fWriter.endArray();
41         } else {
42             fWriter.appendString(name, s.c_str());
43         }
44     }
45
46     // Compound types
47     void visit(sk_sp<SkReflected>& e, const SkReflected::Type* baseType) override {
48         fWriter.appendString("Type", e ? e->getType()->fName : "Null");
49     }
50
51     void enterObject(const char* name) override { fWriter.beginObject(name); }
52     void exitObject()                  override { fWriter.endObject(); }
53
54     int enterArray(const char* name, int oldCount) override {
55         fWriter.beginArray(name);
56         return oldCount;
57     }
58     ArrayEdit exitArray() override {
59         fWriter.endArray();
60         return ArrayEdit();
61     }
62
63 private:
64     SkJSONWriter& fWriter;
65 };
66
67 class SkFromJsonVisitor : public SkFieldVisitor {
68 public:
69     SkFromJsonVisitor(const skjson::Value& v) : fRoot(v) {
70         fStack.push_back(&fRoot);
71     }
72
73     void visit(const char* name, float& f) override {
74         TryParse(get(name), f);
75     }
76     void visit(const char* name, int& i) override {
77         TryParse(get(name), i);
78     }
79     void visit(const char* name, bool& b) override {
80         TryParse(get(name), b);
81     }
82     void visit(const char* name, SkString& s) override {
83         if (const skjson::ArrayValue* lines = get(name)) {
84             s.reset();
85             bool first = true;
86             for (const skjson::StringValue* line : *lines) {
87                 if (line) {
88                     if (!first) {
89                         s.append("\n");
90                     }
91                     s.append(line->begin(), line->size());
92                     first = false;
93                 }
94             }
95         } else {
96             TryParse(get(name), s);
97         }
98     }
99
100     void visit(sk_sp<SkReflected>& e, const SkReflected::Type* baseType) override {
101         const skjson::StringValue* typeString = get("Type");
102         const char* type = typeString ? typeString->begin() : "Null";
103         e = SkReflected::CreateInstance(type);
104     }
105
106     void enterObject(const char* name) override {
107         fStack.push_back((const skjson::ObjectValue*)get(name));
108     }
109     void exitObject() override {
110         fStack.pop_back();
111     }
112
113     int enterArray(const char* name, int oldCount) override {
114         const skjson::ArrayValue* arrVal = get(name);
115         fStack.push_back(arrVal);
116         fArrayIndexStack.push_back(0);
117         return arrVal ? arrVal->size() : 0;
118     }
119     ArrayEdit exitArray() override {
120         fStack.pop_back();
121         fArrayIndexStack.pop_back();
122         return ArrayEdit();
123     }
124
125 private:
126     const skjson::Value& get(const char* name) {
127         if (const skjson::Value* cur = fStack.back()) {
128             if (cur->is<skjson::ArrayValue>()) {
129                 SkASSERT(!name);
130                 return cur->as<skjson::ArrayValue>()[fArrayIndexStack.back()++];
131             } else if (!name) {
132                 return *cur;
133             } else if (cur->is<skjson::ObjectValue>()) {
134                 return cur->as<skjson::ObjectValue>()[name];
135             }
136         }
137         static skjson::NullValue gNull;
138         return gNull;
139     }
140
141     static bool TryParse(const skjson::Value& v, float& f) {
142         if (const skjson::NumberValue* num = v) {
143             f = static_cast<float>(**num);
144             return true;
145         }
146         return false;
147     }
148
149     static bool TryParse(const skjson::Value& v, int& i) {
150         if (const skjson::NumberValue* num = v) {
151             double dbl = **num;
152             i = static_cast<int>(dbl);
153             return static_cast<double>(i) == dbl;
154         }
155         return false;
156     }
157
158     static bool TryParse(const skjson::Value& v, SkString& s) {
159         if (const skjson::StringValue* str = v) {
160             s.set(str->begin(), str->size());
161             return true;
162         }
163         return false;
164     }
165
166     static bool TryParse(const skjson::Value& v, bool& b) {
167         switch (v.getType()) {
168         case skjson::Value::Type::kNumber:
169             b = SkToBool(*v.as<skjson::NumberValue>());
170             return true;
171         case skjson::Value::Type::kBool:
172             b = *v.as<skjson::BoolValue>();
173             return true;
174         default:
175             break;
176         }
177
178         return false;
179     }
180
181     const skjson::Value& fRoot;
182     SkSTArray<16, const skjson::Value*, true> fStack;
183     SkSTArray<16, size_t, true>               fArrayIndexStack;
184 };
185
186 #endif // SkParticleSerialization_DEFINED