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 "SkJSONCanvas.h" | |
9 #include "SkPath.h" | |
10 #include "SkRRect.h" | |
11 #include "stdio.h" | |
12 #include "stdlib.h" | |
13 | |
14 SkJSONCanvas::SkJSONCanvas(int width, int height, SkWStream& out) | |
15 : INHERITED(width, height) | |
16 , fOut(out) | |
17 , fFirstCommand(true) { | |
18 fOut.writeText("{\"" SKJSONCANVAS_VERSION "\":1, \"" SKJSONCANVAS_COMMAN
DS | |
19 "\":["); | |
20 } | |
21 | |
22 void SkJSONCanvas::finish() { | |
23 fOut.writeText("]}"); | |
24 } | |
25 | |
26 void SkJSONCanvas::writef(const char* format, ...) { | |
27 va_list args; | |
28 va_start(args, format); | |
29 SkString s; | |
30 s.appendVAList(format, args); | |
31 fOut.writeText(s.c_str()); | |
32 } | |
33 | |
34 void SkJSONCanvas::open(const char* name) { | |
35 if (fFirstCommand) { | |
36 fFirstCommand = false; | |
37 } | |
38 else { | |
39 fOut.writeText(","); | |
40 } | |
41 this->writef("{\"" SKJSONCANVAS_COMMAND "\":\"%s\"", name); | |
42 } | |
43 | |
44 void SkJSONCanvas::close() { | |
45 fOut.writeText("}"); | |
46 } | |
47 | |
48 void SkJSONCanvas::writeString(const char* name, const char* text) { | |
49 this->writeString(name, text, strlen(text)); | |
50 } | |
51 | |
52 void SkJSONCanvas::writeString(const char* name, const void* text, size_t length
) { | |
53 // TODO: escaping | |
54 this->writef(",\"%s\":\"", name); | |
55 fOut.write(text, length); | |
56 fOut.writeText("\""); | |
57 } | |
58 | |
59 void SkJSONCanvas::writePoint(const char* name, const SkPoint& point) { | |
60 this->writef(",\"%s\":[%f, %f]", name, point.x(), point.y()); | |
61 } | |
62 | |
63 void SkJSONCanvas::writeRect(const char* name, const SkRect& rect) { | |
64 this->writef(",\"%s\":[%f, %f, %f, %f]", name, rect.left(), rect.top(),
rect.right(), | |
65 rect.bottom()); | |
66 } | |
67 | |
68 void SkJSONCanvas::writeRRect(const char* name, const SkRRect& rrect) { | |
69 SkRect rect = rrect.rect(); | |
70 SkVector corner1 = rrect.radii(SkRRect::kUpperLeft_Corner); | |
71 SkVector corner2 = rrect.radii(SkRRect::kUpperRight_Corner); | |
72 SkVector corner3 = rrect.radii(SkRRect::kLowerLeft_Corner); | |
73 SkVector corner4 = rrect.radii(SkRRect::kLowerRight_Corner); | |
74 this->writef(",\"%s\":[[%f, %f, %f, %f],[%f, %f],[%f, %f],[%f, %f],[%f,
%f]]", name, | |
75 rect.left(), rect.top(), rect.right(), rect.bot
tom(), corner1.x(), corner1.y(), | |
76 corner2.x(), corner2.y(), corner3.x(), corner3.
y(), corner4.x(), corner4.y()); | |
77 } | |
78 | |
79 void SkJSONCanvas::writePath(const char* name, const SkPath& path) { | |
80 SkString text("["); | |
81 SkPath::Iter iter(path, false); | |
82 SkPoint pts[4]; | |
83 bool first = true; | |
84 SkPath::Verb verb; | |
85 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | |
86 if (first) { | |
87 first = false; | |
88 } | |
89 else { | |
90 text.append(","); | |
91 } | |
92 switch (verb) { | |
93 case SkPath::kLine_Verb: | |
94 text.appendf("{\"" SKJSONCANVAS_VERB_LINE "\":[%f,%f]}", pts[1].
x(), pts[1].y()); | |
95 break; | |
96 case SkPath::kQuad_Verb: | |
97 text.appendf("{\"" SKJSONCANVAS_VERB_QUAD "\":[[%f,%f],[%f,%f]]}
", pts[1].x(), | |
98 pts[1].y(), pts[2].x(), pts[2].y()); | |
99 break; | |
100 case SkPath::kCubic_Verb: | |
101 text.appendf("{\"" SKJSONCANVAS_VERB_CUBIC "\":[[%f,%f],[%f,%f],
[%f,%f]]}", | |
102 pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(), pts
[3].x(), | |
103 pts[3].y()); | |
104 break; | |
105 case SkPath::kConic_Verb: | |
106 text.appendf("{\"" SKJSONCANVAS_VERB_CONIC "\":[[%f,%f],[%f,%f],
%f]}", pts[1].x(), | |
107 pts[1].y(), pts[2].x(), pts[2].y(), iter.conicWeigh
t()); | |
108 break; | |
109 case SkPath::kMove_Verb: | |
110 text.appendf("{\"" SKJSONCANVAS_VERB_MOVE "\":[%f,%f]}", pts[0].
x(), pts[0].y()); | |
111 break; | |
112 case SkPath::kClose_Verb: | |
113 text.appendf("\"" SKJSONCANVAS_VERB_CLOSE "\""); | |
114 break; | |
115 case SkPath::kDone_Verb: | |
116 break; | |
117 } | |
118 } | |
119 text.appendf("]"); | |
120 this->writef(",\"" SKJSONCANVAS_ATTRIBUTE_PATH "\":%s", text.c_str()); | |
121 } | |
122 | |
123 void SkJSONCanvas::writeRegion(const char* name, const SkRegion& region) { | |
124 this->writef(",\"%s\":\"<unimplemented>\"", name); | |
125 } | |
126 | |
127 void SkJSONCanvas::writePaint(const SkPaint& paint) { | |
128 this->writef(",\"" SKJSONCANVAS_ATTRIBUTE_PAINT "\":{"); | |
129 SkColor color = paint.getColor(); | |
130 bool first = true; | |
131 if (color != SK_ColorBLACK) { | |
132 this->writef("\"" SKJSONCANVAS_ATTRIBUTE_COLOR "\":[%d,%d,%d,%d]
", SkColorGetA(color), | |
133 SkColorGetR(color), SkColorGetG(color), SkColorGetB(color))
; | |
134 first = false; | |
135 } | |
136 SkPaint::Style style = paint.getStyle(); | |
137 if (style != SkPaint::kFill_Style) { | |
138 if (first) { | |
139 first = false; | |
140 } | |
141 else { | |
142 fOut.writeText(","); | |
143 } | |
144 switch (style) { | |
145 case SkPaint::kStroke_Style: | |
146 fOut.writeText("\"" SKJSONCANVAS_ATTRIBUTE_STYLE "\":\"" | |
147 SKJSONCANVAS_STYLE_STROKE "\""); | |
148 break; | |
149 case SkPaint::kStrokeAndFill_Style: | |
150 fOut.writeText("\"" SKJSONCANVAS_ATTRIBUTE_STYLE "\":\"" | |
151 SKJSONCANVAS_STYLE_STROKEANDFILL "\""); | |
152 break; | |
153 default: SkASSERT(false); | |
154 } | |
155 } | |
156 SkScalar strokeWidth = paint.getStrokeWidth(); | |
157 if (strokeWidth != 0.0f) { | |
158 if (first) { | |
159 first = false; | |
160 } | |
161 else { | |
162 fOut.writeText(","); | |
163 } | |
164 this->writef("\"" SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH "\":%f", strokeWidt
h); | |
165 } | |
166 if (paint.isAntiAlias()) { | |
167 if (first) { | |
168 first = false; | |
169 } | |
170 else { | |
171 fOut.writeText(","); | |
172 } | |
173 fOut.writeText("\"" SKJSONCANVAS_ATTRIBUTE_ANTIALIAS "\":true"); | |
174 } | |
175 fOut.writeText("}"); | |
176 } | |
177 | |
178 void SkJSONCanvas::writeMatrix(const char* name, const SkMatrix& matrix) { | |
179 this->writef(",\"%s\":[[%f,%f,%f],[%f,%f,%f],[%f,%f,%f]]", name, | |
180 matrix[0], matrix[1], matrix[2], | |
181 matrix[3], matrix[4], matrix[5], | |
182 matrix[6], matrix[7], matrix[8]); | |
183 } | |
184 | |
185 void SkJSONCanvas::writeRegionOp(const char* name, SkRegion::Op op) { | |
186 this->writef(",\"%s\":\"", name); | |
187 switch (op) { | |
188 case SkRegion::kDifference_Op: | |
189 fOut.writeText(SKJSONCANVAS_REGIONOP_DIFFERENCE); | |
190 break; | |
191 case SkRegion::kIntersect_Op: | |
192 fOut.writeText(SKJSONCANVAS_REGIONOP_INTERSECT); | |
193 break; | |
194 case SkRegion::kUnion_Op: | |
195 fOut.writeText(SKJSONCANVAS_REGIONOP_UNION); | |
196 break; | |
197 case SkRegion::kXOR_Op: | |
198 fOut.writeText(SKJSONCANVAS_REGIONOP_XOR); | |
199 break; | |
200 case SkRegion::kReverseDifference_Op: | |
201 fOut.writeText(SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE); | |
202 break; | |
203 case SkRegion::kReplace_Op: | |
204 fOut.writeText(SKJSONCANVAS_REGIONOP_REPLACE); | |
205 break; | |
206 default: | |
207 SkASSERT(false); | |
208 }; | |
209 fOut.writeText("\""); | |
210 } | |
211 | |
212 void SkJSONCanvas::writeEdgeStyle(const char* name, SkCanvas::ClipEdgeStyle edge
Style) { | |
213 this->writef(",\"%s\":\"", name); | |
214 switch (edgeStyle) { | |
215 case SkCanvas::kHard_ClipEdgeStyle: fOut.writeText(SKJSONCANVAS_EDGESTYL
E_HARD); break; | |
216 case SkCanvas::kSoft_ClipEdgeStyle: fOut.writeText(SKJSONCANVAS_EDGESTYL
E_SOFT); break; | |
217 default: SkASSERT(false); | |
218 }; | |
219 fOut.writeText("\""); | |
220 } | |
221 | |
222 void SkJSONCanvas::writePointMode(const char* name, SkCanvas::PointMode mode) { | |
223 this->writef(",\"%s\":\"", name); | |
224 switch (mode) { | |
225 case SkCanvas::kPoints_PointMode: fOut.writeText(SKJSONCANVAS_POINTMODE
_POINTS); break; | |
226 case SkCanvas::kLines_PointMode: fOut.writeText(SKJSONCANVAS_POINTMODE
_LINES); break; | |
227 case SkCanvas::kPolygon_PointMode: fOut.writeText(SKJSONCANVAS_POINTMODE
_POLYGON); break; | |
228 default: SkASSERT(false); | |
229 }; | |
230 fOut.writeText("\""); | |
231 } | |
232 | |
233 void SkJSONCanvas::updateMatrix() { | |
234 const SkMatrix& matrix = this->getTotalMatrix(); | |
235 if (matrix != fLastMatrix) { | |
236 this->open(SKJSONCANVAS_COMMAND_MATRIX); | |
237 this->writeMatrix(SKJSONCANVAS_ATTRIBUTE_MATRIX, matrix); | |
238 fLastMatrix = matrix; | |
239 this->close(); | |
240 } | |
241 } | |
242 | |
243 void SkJSONCanvas::onDrawPaint(const SkPaint& paint) { | |
244 this->open(SKJSONCANVAS_COMMAND_PAINT); | |
245 this->writePaint(paint); | |
246 this->close(); | |
247 } | |
248 | |
249 void SkJSONCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { | |
250 this->updateMatrix(); | |
251 this->open(SKJSONCANVAS_COMMAND_RECT); | |
252 this->writeRect(SKJSONCANVAS_ATTRIBUTE_COORDS, rect); | |
253 this->writePaint(paint); | |
254 this->close(); | |
255 } | |
256 | |
257 void SkJSONCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { | |
258 this->updateMatrix(); | |
259 this->open(SKJSONCANVAS_COMMAND_OVAL); | |
260 this->writeRect(SKJSONCANVAS_ATTRIBUTE_COORDS, rect); | |
261 this->writePaint(paint); | |
262 this->close(); | |
263 } | |
264 | |
265 void SkJSONCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | |
266 this->updateMatrix(); | |
267 this->open(SKJSONCANVAS_COMMAND_RRECT); | |
268 this->writeRRect(SKJSONCANVAS_ATTRIBUTE_COORDS, rrect); | |
269 this->writePaint(paint); | |
270 this->close();} | |
271 | |
272 void SkJSONCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, cons
t SkPaint& paint) { | |
273 this->updateMatrix(); | |
274 this->open(SKJSONCANVAS_COMMAND_DRRECT); | |
275 this->writeRRect(SKJSONCANVAS_ATTRIBUTE_OUTER, outer); | |
276 this->writeRRect(SKJSONCANVAS_ATTRIBUTE_INNER, inner); | |
277 this->writePaint(paint); | |
278 this->close(); | |
279 } | |
280 | |
281 void SkJSONCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const Sk
Point pts[], | |
282 const SkPaint& p
aint) { | |
283 this->updateMatrix(); | |
284 this->open(SKJSONCANVAS_COMMAND_POINTS); | |
285 this->writePointMode(SKJSONCANVAS_ATTRIBUTE_MODE, mode); | |
286 fOut.writeText(",\"" SKJSONCANVAS_ATTRIBUTE_POINTS "\":["); | |
287 for (size_t i = 0; i < count; i++) { | |
288 if (i != 0) { | |
289 fOut.writeText(","); | |
290 } | |
291 this->writef("[%f,%f]", pts[i].x(), pts[i].y()); | |
292 } | |
293 fOut.writeText("]"); | |
294 this->writePaint(paint); | |
295 this->close(); | |
296 } | |
297 | |
298 void SkJSONCanvas::onDrawVertices(SkCanvas::VertexMode, int vertexCount, const S
kPoint vertices[], | |
299 const SkPoint texs[], const SkColor colors[],
SkXfermode*, | |
300 const uint16_t indices[], int indexCount, cons
t SkPaint&) { | |
301 SkDebugf("unsupported: drawVertices\n"); | |
302 } | |
303 | |
304 void SkJSONCanvas::onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[]
, const SkColor[], | |
305 int count, SkXfermode::Mode, const SkRect* cull,
const SkPaint*) { | |
306 SkDebugf("unsupported: drawAtlas\n"); | |
307 } | |
308 | |
309 void SkJSONCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { | |
310 this->updateMatrix(); | |
311 this->open(SKJSONCANVAS_COMMAND_PATH); | |
312 this->writePath(SKJSONCANVAS_ATTRIBUTE_PATH, path); | |
313 this->writePaint(paint); | |
314 this->close();} | |
315 | |
316 void SkJSONCanvas::onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const S
kPaint*) { | |
317 SkDebugf("unsupported: drawImage\n"); | |
318 } | |
319 | |
320 void SkJSONCanvas::onDrawImageRect(const SkImage*, const SkRect*, const SkRect&,
const SkPaint*, | |
321 SkCanvas::SrcRectConstraint) { | |
322 SkDebugf("unsupported: drawImageRect\n"); | |
323 } | |
324 | |
325 void SkJSONCanvas::onDrawImageNine(const SkImage*, const SkIRect& center, const
SkRect& dst, | |
326 const SkPaint*) { | |
327 SkDebugf("unsupported: drawImageNine\n"); | |
328 } | |
329 | |
330 void SkJSONCanvas::onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const
SkPaint*) { | |
331 SkDebugf("unsupported: drawBitmap\n"); | |
332 } | |
333 | |
334 void SkJSONCanvas::onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect
&, const SkPaint*, | |
335 SkCanvas::SrcRectConstraint) { | |
336 SkDebugf("unsupported: drawBitmapRect\n"); | |
337 } | |
338 | |
339 void SkJSONCanvas::onDrawBitmapNine(const SkBitmap&, const SkIRect& center, cons
t SkRect& dst, | |
340 const SkPaint*) { | |
341 SkDebugf("unsupported: drawBitmapNine\n"); | |
342 } | |
343 | |
344 void SkJSONCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, | |
345 SkScalar y, const SkPaint& paint) { | |
346 this->updateMatrix(); | |
347 this->open(SKJSONCANVAS_COMMAND_TEXT); | |
348 this->writeString(SKJSONCANVAS_ATTRIBUTE_TEXT, text, byteLength); | |
349 this->writePoint(SKJSONCANVAS_ATTRIBUTE_COORDS, { x, y }); | |
350 this->writePaint(paint); | |
351 this->close(); | |
352 } | |
353 | |
354 void SkJSONCanvas::onDrawPosText(const void* text, size_t byteLength, | |
355 const SkPoint pos[], const SkPaint& paint) { | |
356 SkDebugf("unsupported: drawPosText\n"); | |
357 } | |
358 | |
359 void SkJSONCanvas::onDrawPosTextH(const void* text, size_t byteLength, | |
360 const SkScalar xpos[], SkScalar constY, | |
361 const SkPaint& paint) { | |
362 SkDebugf("unsupported: drawPosTextH\n"); | |
363 } | |
364 | |
365 void SkJSONCanvas::onDrawTextOnPath(const void* text, size_t byteLength, | |
366 const SkPath& path, const SkMatrix* matrix, | |
367 const SkPaint& paint) { | |
368 SkDebugf("unsupported: drawTextOnPath\n"); | |
369 } | |
370 | |
371 void SkJSONCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y
, | |
372 const SkPaint& paint) { | |
373 SkDebugf("unsupported: drawTextBlob\n"); | |
374 } | |
375 | |
376 void SkJSONCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4]
, | |
377 const SkPoint texCoords[4], SkXfermode* xmode, | |
378 const SkPaint& paint) { | |
379 SkDebugf("unsupported: drawPatch\n"); | |
380 } | |
381 | |
382 void SkJSONCanvas::onDrawDrawable(SkDrawable*, const SkMatrix*) { | |
383 SkDebugf("unsupported: drawDrawable\n"); | |
384 } | |
385 | |
386 void SkJSONCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle
edgeStyle) { | |
387 this->updateMatrix(); | |
388 this->open(SKJSONCANVAS_COMMAND_CLIPRECT); | |
389 this->writeRect(SKJSONCANVAS_ATTRIBUTE_COORDS, rect); | |
390 this->writeRegionOp(SKJSONCANVAS_ATTRIBUTE_REGIONOP, op); | |
391 this->writeEdgeStyle(SKJSONCANVAS_ATTRIBUTE_EDGESTYLE, edgeStyle); | |
392 this->close(); | |
393 } | |
394 | |
395 void SkJSONCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeSt
yle edgeStyle) { | |
396 this->updateMatrix(); | |
397 this->open(SKJSONCANVAS_COMMAND_CLIPRRECT); | |
398 this->writeRRect(SKJSONCANVAS_ATTRIBUTE_COORDS, rrect); | |
399 this->writeRegionOp(SKJSONCANVAS_ATTRIBUTE_REGIONOP, op); | |
400 this->writeEdgeStyle(SKJSONCANVAS_ATTRIBUTE_EDGESTYLE, edgeStyle); | |
401 this->close(); | |
402 } | |
403 | |
404 void SkJSONCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle
edgeStyle) { | |
405 updateMatrix(); | |
406 this->open(SKJSONCANVAS_COMMAND_CLIPPATH); | |
407 this->writePath(SKJSONCANVAS_ATTRIBUTE_PATH, path); | |
408 this->writeRegionOp(SKJSONCANVAS_ATTRIBUTE_REGIONOP, op); | |
409 this->writeEdgeStyle(SKJSONCANVAS_ATTRIBUTE_EDGESTYLE, edgeStyle); | |
410 this->close(); | |
411 } | |
412 | |
413 void SkJSONCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { | |
414 this->open(SKJSONCANVAS_COMMAND_CLIPREGION); | |
415 this->writeRegion(SKJSONCANVAS_ATTRIBUTE_DEVICEREGION, deviceRgn); | |
416 this->writeRegionOp(SKJSONCANVAS_ATTRIBUTE_REGIONOP, op); | |
417 this->close(); | |
418 } | |
419 | |
420 void SkJSONCanvas::willSave() { | |
421 this->open(SKJSONCANVAS_COMMAND_SAVE); | |
422 this->close(); | |
423 } | |
424 | |
425 void SkJSONCanvas::willRestore() { | |
426 this->open(SKJSONCANVAS_COMMAND_RESTORE); | |
427 this->close(); | |
428 } | |
OLD | NEW |