OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2016 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 "SkJSONRenderer.h" | |
9 #include "SkJSONCanvas.h" | |
10 #include "SkJSONCPP.h" | |
11 #include "SkPath.h" | |
12 | |
13 namespace SkJSONRenderer { | |
14 | |
15 class Renderer { | |
16 public: | |
17 void getPaint(Json::Value& command, SkPaint* paint); | |
18 | |
19 void getRect(Json::Value& command, const char* name, SkRect* rect); | |
20 | |
21 void getRRect(Json::Value& command, const char* name, SkRRect* rrect); | |
22 | |
23 void processCommand(Json::Value& command, SkCanvas* target); | |
24 | |
25 void processMatrix(Json::Value& command, SkCanvas* target); | |
26 | |
27 void processSave(Json::Value& command, SkCanvas* target); | |
28 | |
29 void processRestore(Json::Value& command, SkCanvas* target); | |
30 | |
31 void processPaint(Json::Value& command, SkCanvas* target); | |
32 | |
33 void processRect(Json::Value& command, SkCanvas* target); | |
34 | |
35 void processRRect(Json::Value& command, SkCanvas* target); | |
36 | |
37 void processOval(Json::Value& command, SkCanvas* target); | |
38 | |
39 void processPath(Json::Value& command, SkCanvas* target); | |
40 | |
41 void processText(Json::Value& command, SkCanvas* target); | |
42 | |
43 void processPoints(Json::Value& command, SkCanvas* target); | |
44 | |
45 void processClipRect(Json::Value& command, SkCanvas* target); | |
46 }; | |
47 | |
48 void Renderer::processCommand(Json::Value& command, SkCanvas* target) { | |
49 const char* name = command[SKJSONCANVAS_COMMAND].asCString(); | |
50 // TODO speed this up with a hash | |
51 if (!strcmp(name, SKJSONCANVAS_COMMAND_MATRIX)) { | |
52 this->processMatrix(command, target); | |
53 } | |
54 else if (!strcmp(name, SKJSONCANVAS_COMMAND_SAVE)) { | |
55 this->processSave(command, target); | |
56 } | |
57 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RESTORE)) { | |
58 this->processRestore(command, target); | |
59 } | |
60 else if (!strcmp(name, SKJSONCANVAS_COMMAND_PAINT)) { | |
61 this->processPaint(command, target); | |
62 } | |
63 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RECT)) { | |
64 this->processRect(command, target); | |
65 } | |
66 else if (!strcmp(name, SKJSONCANVAS_COMMAND_RRECT)) { | |
67 this->processRRect(command, target); | |
68 } | |
69 else if (!strcmp(name, SKJSONCANVAS_COMMAND_OVAL)) { | |
70 this->processOval(command, target); | |
71 } | |
72 else if (!strcmp(name, SKJSONCANVAS_COMMAND_PATH)) { | |
73 this->processPath(command, target); | |
74 } | |
75 else if (!strcmp(name, SKJSONCANVAS_COMMAND_TEXT)) { | |
76 this->processText(command, target); | |
77 } | |
78 else if (!strcmp(name, SKJSONCANVAS_COMMAND_POINTS)) { | |
79 this->processPoints(command, target); | |
80 } | |
81 else if (!strcmp(name, SKJSONCANVAS_COMMAND_CLIPRECT)) { | |
82 this->processClipRect(command, target); | |
83 } | |
84 else { | |
85 SkDebugf("unsupported JSON command: %s\n", name); | |
86 } | |
87 } | |
88 | |
89 void Renderer::getPaint(Json::Value& command, SkPaint* result) { | |
90 Json::Value jsonPaint = command[SKJSONCANVAS_ATTRIBUTE_PAINT]; | |
91 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_COLOR)) { | |
92 Json::Value color = jsonPaint[SKJSONCANVAS_ATTRIBUTE_COLOR]; | |
93 result->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), colo
r[2].asInt(), | |
94 color[3].asInt())); | |
95 } | |
96 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STYLE)) { | |
97 const char* style = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STYLE].asCString(); | |
98 if (!strcmp(style, SKJSONCANVAS_STYLE_FILL)) { | |
99 result->setStyle(SkPaint::kFill_Style); | |
100 } | |
101 else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKE)) { | |
102 result->setStyle(SkPaint::kStroke_Style); | |
103 } | |
104 else if (!strcmp(style, SKJSONCANVAS_STYLE_STROKEANDFILL)) { | |
105 result->setStyle(SkPaint::kStrokeAndFill_Style); | |
106 } | |
107 } | |
108 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH)) { | |
109 float strokeWidth = jsonPaint[SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH].asFloa
t(); | |
110 result->setStrokeWidth(strokeWidth); | |
111 } | |
112 if (jsonPaint.isMember(SKJSONCANVAS_ATTRIBUTE_ANTIALIAS)) { | |
113 result->setAntiAlias(jsonPaint[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS].asBool(
)); | |
114 } | |
115 } | |
116 | |
117 void Renderer::getRect(Json::Value& command, const char* name, SkRect* result) { | |
118 Json::Value rect = command[name]; | |
119 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3]
.asFloat()); | |
120 } | |
121 | |
122 void Renderer::getRRect(Json::Value& command, const char* name, SkRRect* result)
{ | |
123 Json::Value rrect = command[name]; | |
124 SkVector radii[4] = { | |
125 { rrect[1][0].asFloat(), rrect[1][1].asFloat() }, | |
126 { rrect[2][0].asFloat(), rrect[2][1].asFloat() }, | |
127 { rrect[3][0].asFloat(), rrect[3][1].asFloat() }, | |
128 { rrect[4][0].asFloat(), rrect[4][1].asFloat() } | |
129 }; | |
130 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asF
loat(), | |
131 rrect[0][2].asFloat(), rrect[0][3].asF
loat()), | |
132 radii); | |
133 } | |
134 | |
135 void Renderer::processMatrix(Json::Value& command, SkCanvas* target) { | |
136 Json::Value jsonMatrix = command[SKJSONCANVAS_ATTRIBUTE_MATRIX]; | |
137 SkMatrix matrix; | |
138 SkScalar values[] = { | |
139 jsonMatrix[0][0].asFloat(), jsonMatrix[0][1].asFloat(), jsonMatrix[0][2]
.asFloat(), | |
140 jsonMatrix[1][0].asFloat(), jsonMatrix[1][1].asFloat(), jsonMatrix[1][2]
.asFloat(), | |
141 jsonMatrix[2][0].asFloat(), jsonMatrix[2][1].asFloat(), jsonMatrix[2][2]
.asFloat() | |
142 }; | |
143 matrix.set9(values); | |
144 target->setMatrix(matrix); | |
145 } | |
146 | |
147 void Renderer::processSave(Json::Value& command, SkCanvas* target) { | |
148 target->save(); | |
149 } | |
150 | |
151 void Renderer::processRestore(Json::Value& command, SkCanvas* target) { | |
152 target->restore(); | |
153 } | |
154 | |
155 void Renderer::processPaint(Json::Value& command, SkCanvas* target) { | |
156 SkPaint paint; | |
157 this->getPaint(command, &paint); | |
158 target->drawPaint(paint); | |
159 } | |
160 | |
161 void Renderer::processRect(Json::Value& command, SkCanvas* target) { | |
162 SkRect rect; | |
163 this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); | |
164 SkPaint paint; | |
165 this->getPaint(command, &paint); | |
166 target->drawRect(rect, paint); | |
167 } | |
168 | |
169 void Renderer::processRRect(Json::Value& command, SkCanvas* target) { | |
170 SkRRect rrect; | |
171 this->getRRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rrect); | |
172 SkPaint paint; | |
173 this->getPaint(command, &paint); | |
174 target->drawRRect(rrect, paint); | |
175 } | |
176 | |
177 void Renderer::processOval(Json::Value& command, SkCanvas* target) { | |
178 SkRect rect; | |
179 this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); | |
180 SkPaint paint; | |
181 this->getPaint(command, &paint); | |
182 target->drawOval(rect, paint); | |
183 } | |
184 | |
185 void Renderer::processPath(Json::Value& command, SkCanvas* target) { | |
186 Json::Value jsonPath = command[SKJSONCANVAS_ATTRIBUTE_PATH]; | |
187 SkPath path; | |
188 for (Json::ArrayIndex i = 0; i < jsonPath.size(); i++) { | |
189 Json::Value verb = jsonPath[i]; | |
190 if (verb.isString()) { | |
191 SkASSERT(!strcmp(verb.asCString(), SKJSONCANVAS_VERB_CLOSE)); | |
192 path.close(); | |
193 } | |
194 else { | |
195 if (verb.isMember(SKJSONCANVAS_VERB_MOVE)) { | |
196 Json::Value move = verb[SKJSONCANVAS_VERB_MOVE]; | |
197 path.moveTo(move[0].asFloat(), move[1].asFloat()); | |
198 } | |
199 else if (verb.isMember(SKJSONCANVAS_VERB_LINE)) { | |
200 Json::Value line = verb[SKJSONCANVAS_VERB_LINE]; | |
201 path.lineTo(line[0].asFloat(), line[1].asFloat()); | |
202 } | |
203 else if (verb.isMember(SKJSONCANVAS_VERB_QUAD)) { | |
204 Json::Value quad = verb[SKJSONCANVAS_VERB_QUAD]; | |
205 path.quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(), | |
206 quad[1][0].asFloat(), quad[1][1].asFloat()); | |
207 } | |
208 else if (verb.isMember(SKJSONCANVAS_VERB_CUBIC)) { | |
209 Json::Value cubic = verb[SKJSONCANVAS_VERB_CUBIC]; | |
210 path.cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(), | |
211 cubic[1][0].asFloat(), cubic[1][1].asFloat(), | |
212 cubic[2][0].asFloat(), cubic[2][1].asFloat()); | |
213 } | |
214 else if (verb.isMember(SKJSONCANVAS_VERB_CONIC)) { | |
215 Json::Value conic = verb[SKJSONCANVAS_VERB_CONIC]; | |
216 path.conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(), | |
217 conic[1][0].asFloat(), conic[1][1].asFloat(), | |
218 conic[2].asFloat()); | |
219 } | |
220 else { | |
221 SkASSERT(false); | |
222 } | |
223 } | |
224 } | |
225 SkPaint paint; | |
226 this->getPaint(command, &paint); | |
227 target->drawPath(path, paint); | |
228 } | |
229 | |
230 void Renderer::processText(Json::Value& command, SkCanvas* target) { | |
231 const char* text = command[SKJSONCANVAS_ATTRIBUTE_TEXT].asCString(); | |
232 SkPaint paint; | |
233 this->getPaint(command, &paint); | |
234 Json::Value coords = command[SKJSONCANVAS_ATTRIBUTE_COORDS]; | |
235 target->drawText(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(
), paint); | |
236 } | |
237 | |
238 void Renderer::processPoints(Json::Value& command, SkCanvas* target) { | |
239 SkCanvas::PointMode mode; | |
240 const char* jsonMode = command[SKJSONCANVAS_ATTRIBUTE_MODE].asCString(); | |
241 if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_POINTS)) { | |
242 mode = SkCanvas::kPoints_PointMode; | |
243 } | |
244 else if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_LINES)) { | |
245 mode = SkCanvas::kLines_PointMode; | |
246 } | |
247 else if (!strcmp(jsonMode, SKJSONCANVAS_POINTMODE_POLYGON)) { | |
248 mode = SkCanvas::kPolygon_PointMode; | |
249 } | |
250 else { | |
251 SkASSERT(false); | |
252 return; | |
253 } | |
254 Json::Value jsonPoints = command[SKJSONCANVAS_ATTRIBUTE_POINTS]; | |
255 int count = (int) jsonPoints.size(); | |
256 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint)); | |
257 for (int i = 0; i < count; i++) { | |
258 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].a
sFloat()); | |
259 } | |
260 SkPaint paint; | |
261 this->getPaint(command, &paint); | |
262 target->drawPoints(mode, count, points, paint); | |
263 free(points); | |
264 } | |
265 | |
266 void Renderer::processClipRect(Json::Value& command, SkCanvas* target) { | |
267 SkRect rect; | |
268 this->getRect(command, SKJSONCANVAS_ATTRIBUTE_COORDS, &rect); | |
269 target->clipRect(rect); | |
270 } | |
271 | |
272 void render(const char* json, SkCanvas* target) { | |
273 Renderer renderer; | |
274 Json::Reader reader; | |
275 Json::Value root; | |
276 if (reader.parse(std::string(json), root)) { | |
277 SkASSERT(root[SKJSONCANVAS_VERSION].asInt() == 1); | |
278 Json::Value commands = root[SKJSONCANVAS_COMMANDS]; | |
279 for (Json::ArrayIndex i = 0; i < commands.size(); i++) { | |
280 renderer.processCommand(commands[i], target); | |
281 } | |
282 } | |
283 else { | |
284 SkDebugf(json); | |
285 SkFAIL("json parse failure"); | |
286 } | |
287 } | |
288 | |
289 } // namespace | |
OLD | NEW |