blob: 9361191c0a1b1fc900d7c94ec99d4fb622c35761 [file] [log] [blame]
ethannicholas978d08a2016-01-26 07:47:57 -08001/*
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"
ethannicholas30c5dde2016-02-02 08:36:58 -08009#include "SkImageFilter.h"
ethannicholas78fc22a2016-01-29 07:15:08 -080010#include "SkMaskFilter.h"
11#include "SkPaintDefaults.h"
ethannicholas978d08a2016-01-26 07:47:57 -080012#include "SkPath.h"
ethannicholas78fc22a2016-01-29 07:15:08 -080013#include "SkPathEffect.h"
ethannicholas978d08a2016-01-26 07:47:57 -080014#include "SkRRect.h"
ethannicholas30c5dde2016-02-02 08:36:58 -080015#include "SkWriteBuffer.h"
ethannicholas978d08a2016-01-26 07:47:57 -080016
ethannicholas30c5dde2016-02-02 08:36:58 -080017SkJSONCanvas::SkJSONCanvas(int width, int height, SkWStream& out, bool sendBinaries)
ethannicholas2bbc3432016-01-27 09:06:35 -080018 : INHERITED(width, height)
19 , fOut(out)
20 , fRoot(Json::objectValue)
ethannicholas30c5dde2016-02-02 08:36:58 -080021 , fCommands(Json::arrayValue)
22 , fSendBinaries(sendBinaries) {
ethannicholas2bbc3432016-01-27 09:06:35 -080023 fRoot[SKJSONCANVAS_VERSION] = Json::Value(1);
ethannicholas978d08a2016-01-26 07:47:57 -080024}
25
26void SkJSONCanvas::finish() {
ethannicholas2bbc3432016-01-27 09:06:35 -080027 fRoot[SKJSONCANVAS_COMMANDS] = fCommands;
28 fOut.writeText(Json::FastWriter().write(fRoot).c_str());
ethannicholas978d08a2016-01-26 07:47:57 -080029}
30
ethannicholas2bbc3432016-01-27 09:06:35 -080031Json::Value SkJSONCanvas::makePoint(const SkPoint& point) {
32 Json::Value result(Json::arrayValue);
33 result.append(Json::Value(point.x()));
34 result.append(Json::Value(point.y()));
35 return result;
ethannicholas978d08a2016-01-26 07:47:57 -080036}
37
ethannicholas2bbc3432016-01-27 09:06:35 -080038Json::Value SkJSONCanvas::makePoint(SkScalar x, SkScalar y) {
39 Json::Value result(Json::arrayValue);
40 result.append(Json::Value(x));
41 result.append(Json::Value(y));
42 return result;
ethannicholas978d08a2016-01-26 07:47:57 -080043}
44
ethannicholas2bbc3432016-01-27 09:06:35 -080045Json::Value SkJSONCanvas::makeRect(const SkRect& rect) {
46 Json::Value result(Json::arrayValue);
47 result.append(Json::Value(rect.left()));
48 result.append(Json::Value(rect.top()));
49 result.append(Json::Value(rect.right()));
50 result.append(Json::Value(rect.bottom()));
51 return result;
ethannicholas978d08a2016-01-26 07:47:57 -080052}
53
ethannicholas2bbc3432016-01-27 09:06:35 -080054Json::Value SkJSONCanvas::makeRRect(const SkRRect& rrect) {
55 Json::Value result(Json::arrayValue);
56 result.append(this->makeRect(rrect.rect()));
57 result.append(this->makePoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
58 result.append(this->makePoint(rrect.radii(SkRRect::kUpperRight_Corner)));
ethannicholas2bbc3432016-01-27 09:06:35 -080059 result.append(this->makePoint(rrect.radii(SkRRect::kLowerRight_Corner)));
ethannicholas78fc22a2016-01-29 07:15:08 -080060 result.append(this->makePoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas2bbc3432016-01-27 09:06:35 -080061 return result;
ethannicholas978d08a2016-01-26 07:47:57 -080062}
63
ethannicholas2bbc3432016-01-27 09:06:35 -080064Json::Value SkJSONCanvas::makePath(const SkPath& path) {
ethannicholas78fc22a2016-01-29 07:15:08 -080065 Json::Value result(Json::objectValue);
66 switch (path.getFillType()) {
67 case SkPath::kWinding_FillType:
68 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_WINDING;
69 break;
70 case SkPath::kEvenOdd_FillType:
71 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_EVENODD;
72 break;
73 case SkPath::kInverseWinding_FillType:
74 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEWINDING;
75 break;
76 case SkPath::kInverseEvenOdd_FillType:
77 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEEVENODD;
78 break;
79 }
80 Json::Value verbs(Json::arrayValue);
ethannicholas978d08a2016-01-26 07:47:57 -080081 SkPath::Iter iter(path, false);
82 SkPoint pts[4];
ethannicholas978d08a2016-01-26 07:47:57 -080083 SkPath::Verb verb;
84 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
ethannicholas978d08a2016-01-26 07:47:57 -080085 switch (verb) {
ethannicholas2bbc3432016-01-27 09:06:35 -080086 case SkPath::kLine_Verb: {
87 Json::Value line(Json::objectValue);
88 line[SKJSONCANVAS_VERB_LINE] = this->makePoint(pts[1]);
ethannicholas78fc22a2016-01-29 07:15:08 -080089 verbs.append(line);
ethannicholas978d08a2016-01-26 07:47:57 -080090 break;
ethannicholas2bbc3432016-01-27 09:06:35 -080091 }
92 case SkPath::kQuad_Verb: {
93 Json::Value quad(Json::objectValue);
94 Json::Value coords(Json::arrayValue);
95 coords.append(this->makePoint(pts[1]));
96 coords.append(this->makePoint(pts[2]));
97 quad[SKJSONCANVAS_VERB_QUAD] = coords;
ethannicholas78fc22a2016-01-29 07:15:08 -080098 verbs.append(quad);
ethannicholas978d08a2016-01-26 07:47:57 -080099 break;
ethannicholas2bbc3432016-01-27 09:06:35 -0800100 }
101 case SkPath::kCubic_Verb: {
102 Json::Value cubic(Json::objectValue);
103 Json::Value coords(Json::arrayValue);
104 coords.append(this->makePoint(pts[1]));
105 coords.append(this->makePoint(pts[2]));
106 coords.append(this->makePoint(pts[3]));
107 cubic[SKJSONCANVAS_VERB_CUBIC] = coords;
ethannicholas78fc22a2016-01-29 07:15:08 -0800108 verbs.append(cubic);
ethannicholas978d08a2016-01-26 07:47:57 -0800109 break;
ethannicholas2bbc3432016-01-27 09:06:35 -0800110 }
111 case SkPath::kConic_Verb: {
112 Json::Value conic(Json::objectValue);
113 Json::Value coords(Json::arrayValue);
114 coords.append(this->makePoint(pts[1]));
115 coords.append(this->makePoint(pts[2]));
116 coords.append(Json::Value(iter.conicWeight()));
117 conic[SKJSONCANVAS_VERB_CONIC] = coords;
ethannicholas78fc22a2016-01-29 07:15:08 -0800118 verbs.append(conic);
ethannicholas978d08a2016-01-26 07:47:57 -0800119 break;
ethannicholas2bbc3432016-01-27 09:06:35 -0800120 }
121 case SkPath::kMove_Verb: {
122 Json::Value move(Json::objectValue);
123 move[SKJSONCANVAS_VERB_MOVE] = this->makePoint(pts[0]);
ethannicholas78fc22a2016-01-29 07:15:08 -0800124 verbs.append(move);
ethannicholas978d08a2016-01-26 07:47:57 -0800125 break;
ethannicholas2bbc3432016-01-27 09:06:35 -0800126 }
ethannicholas978d08a2016-01-26 07:47:57 -0800127 case SkPath::kClose_Verb:
ethannicholas78fc22a2016-01-29 07:15:08 -0800128 verbs.append(Json::Value(SKJSONCANVAS_VERB_CLOSE));
ethannicholas978d08a2016-01-26 07:47:57 -0800129 break;
130 case SkPath::kDone_Verb:
131 break;
132 }
133 }
ethannicholas78fc22a2016-01-29 07:15:08 -0800134 result[SKJSONCANVAS_ATTRIBUTE_VERBS] = verbs;
ethannicholas2bbc3432016-01-27 09:06:35 -0800135 return result;
ethannicholas978d08a2016-01-26 07:47:57 -0800136}
137
ethannicholas2bbc3432016-01-27 09:06:35 -0800138Json::Value SkJSONCanvas::makeRegion(const SkRegion& region) {
139 return Json::Value("<unimplemented>");
ethannicholas978d08a2016-01-26 07:47:57 -0800140}
141
ethannicholas78fc22a2016-01-29 07:15:08 -0800142void store_scalar(Json::Value* target, const char* key, SkScalar value, SkScalar defaultValue) {
143 if (value != defaultValue) {
144 (*target)[key] = Json::Value(value);
145 }
146}
147
148void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
149 if (value != defaultValue) {
150 (*target)[key] = Json::Value(value);
151 }
152}
153
ethannicholas30c5dde2016-02-02 08:36:58 -0800154static void encode_data(const void* data, size_t count, Json::Value* target) {
155 // just use a brain-dead JSON array for now, switch to base64 or something else smarter down the
156 // road
157 for (size_t i = 0; i < count; i++) {
158 target->append(((const uint8_t*)data)[i]);
159 }
160}
161
162static void flatten(const SkFlattenable* flattenable, Json::Value* target, bool sendBinaries) {
163 if (sendBinaries) {
164 SkWriteBuffer buffer;
165 flattenable->flatten(buffer);
166 void* data = sk_malloc_throw(buffer.bytesWritten());
167 buffer.writeToMemory(data);
168 Json::Value bytes;
169 encode_data(data, buffer.bytesWritten(), &bytes);
170 Json::Value jsonFlattenable;
171 jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
172 jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes;
173 (*target) = jsonFlattenable;
174 free(data);
175 }
176 else {
177 (*target)[SKJSONCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(flattenable->getTypeName());
178 }
179}
180
181static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target,
182 bool sendBinaries) {
183 if (sendBinaries) {
ethannicholas0bd10342016-02-04 06:45:25 -0800184 SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100);
185 if (encoded == nullptr) {
186 // PNG encode doesn't necessarily support all color formats, convert to a different
187 // format
188 size_t rowBytes = 4 * image.width();
189 void* buffer = sk_malloc_throw(rowBytes * image.height());
190 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
191 kN32_SkColorType, kPremul_SkAlphaType);
192 if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) {
193 SkDebugf("readPixels failed\n");
194 return false;
195 }
196 SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes);
197 encoded = converted->encode(SkImageEncoder::kPNG_Type, 100);
198 if (encoded == nullptr) {
199 SkDebugf("image encode failed\n");
200 return false;
201 }
202 free(converted);
203 free(buffer);
ethannicholas30c5dde2016-02-02 08:36:58 -0800204 }
205 Json::Value bytes;
ethannicholas0bd10342016-02-04 06:45:25 -0800206 encode_data(encoded->data(), encoded->size(), &bytes);
ethannicholas30c5dde2016-02-02 08:36:58 -0800207 (*target)[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes;
ethannicholas0bd10342016-02-04 06:45:25 -0800208 encoded->unref();
ethannicholas30c5dde2016-02-02 08:36:58 -0800209 }
210 else {
211 SkString description = SkStringPrintf("%dx%d pixel image", image.width(), image.height());
212 (*target)[SKJSONCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(description.c_str());
213 }
214 return true;
215}
216
ethannicholas0bd10342016-02-04 06:45:25 -0800217static const char* color_type_name(SkColorType colorType) {
218 switch (colorType) {
219 case kARGB_4444_SkColorType:
220 return SKJSONCANVAS_COLORTYPE_ARGB4444;
221 case kRGBA_8888_SkColorType:
222 return SKJSONCANVAS_COLORTYPE_RGBA8888;
223 case kBGRA_8888_SkColorType:
224 return SKJSONCANVAS_COLORTYPE_BGRA8888;
225 case kRGB_565_SkColorType:
226 return SKJSONCANVAS_COLORTYPE_565;
227 case kGray_8_SkColorType:
228 return SKJSONCANVAS_COLORTYPE_GRAY8;
229 case kIndex_8_SkColorType:
230 return SKJSONCANVAS_COLORTYPE_INDEX8;
231 case kAlpha_8_SkColorType:
232 return SKJSONCANVAS_COLORTYPE_ALPHA8;
233 default:
234 SkASSERT(false);
235 return SKJSONCANVAS_COLORTYPE_RGBA8888;
236 }
237}
238
239static const char* alpha_type_name(SkAlphaType alphaType) {
240 switch (alphaType) {
241 case kOpaque_SkAlphaType:
242 return SKJSONCANVAS_ALPHATYPE_OPAQUE;
243 case kPremul_SkAlphaType:
244 return SKJSONCANVAS_ALPHATYPE_PREMUL;
245 case kUnpremul_SkAlphaType:
246 return SKJSONCANVAS_ALPHATYPE_UNPREMUL;
247 default:
248 SkASSERT(false);
249 return SKJSONCANVAS_ALPHATYPE_OPAQUE;
250 }
251}
252
ethannicholas30c5dde2016-02-02 08:36:58 -0800253static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target,
254 bool sendBinaries) {
ethannicholas0bd10342016-02-04 06:45:25 -0800255 bitmap.lockPixels();
256 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
257 bitmap.unlockPixels();
258 (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
259 (*target)[SKJSONCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholas30c5dde2016-02-02 08:36:58 -0800260 bool success = flatten(*image, target, sendBinaries);
ethannicholas30c5dde2016-02-02 08:36:58 -0800261 return success;
262}
263
264static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800265 SkColor color = paint.getColor();
266 if (color != SK_ColorBLACK) {
267 Json::Value colorValue(Json::arrayValue);
268 colorValue.append(Json::Value(SkColorGetA(color)));
269 colorValue.append(Json::Value(SkColorGetR(color)));
270 colorValue.append(Json::Value(SkColorGetG(color)));
271 colorValue.append(Json::Value(SkColorGetB(color)));
ethannicholas30c5dde2016-02-02 08:36:58 -0800272 (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = colorValue;;
ethannicholas2bbc3432016-01-27 09:06:35 -0800273 }
ethannicholas30c5dde2016-02-02 08:36:58 -0800274}
275
276static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
ethannicholas978d08a2016-01-26 07:47:57 -0800277 SkPaint::Style style = paint.getStyle();
278 if (style != SkPaint::kFill_Style) {
ethannicholas978d08a2016-01-26 07:47:57 -0800279 switch (style) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800280 case SkPaint::kStroke_Style: {
281 Json::Value stroke(SKJSONCANVAS_STYLE_STROKE);
ethannicholas30c5dde2016-02-02 08:36:58 -0800282 (*target)[SKJSONCANVAS_ATTRIBUTE_STYLE] = stroke;
ethannicholas978d08a2016-01-26 07:47:57 -0800283 break;
ethannicholas2bbc3432016-01-27 09:06:35 -0800284 }
285 case SkPaint::kStrokeAndFill_Style: {
286 Json::Value strokeAndFill(SKJSONCANVAS_STYLE_STROKEANDFILL);
ethannicholas30c5dde2016-02-02 08:36:58 -0800287 (*target)[SKJSONCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
ethannicholas978d08a2016-01-26 07:47:57 -0800288 break;
ethannicholas2bbc3432016-01-27 09:06:35 -0800289 }
ethannicholas978d08a2016-01-26 07:47:57 -0800290 default: SkASSERT(false);
291 }
292 }
ethannicholas30c5dde2016-02-02 08:36:58 -0800293}
294
295static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
296 SkPaint::Cap cap = paint.getStrokeCap();
297 if (cap != SkPaint::kDefault_Cap) {
298 switch (cap) {
299 case SkPaint::kButt_Cap: {
300 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_BUTT);
301 break;
302 }
303 case SkPaint::kRound_Cap: {
304 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_ROUND);
305 break;
306 }
307 case SkPaint::kSquare_Cap: {
308 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_SQUARE);
309 break;
310 }
311 default: SkASSERT(false);
312 }
313 }
314}
315static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
ethannicholas78fc22a2016-01-29 07:15:08 -0800316 SkMaskFilter* maskFilter = paint.getMaskFilter();
317 if (maskFilter != nullptr) {
318 SkMaskFilter::BlurRec blurRec;
319 if (maskFilter->asABlur(&blurRec)) {
320 Json::Value blur(Json::objectValue);
321 blur[SKJSONCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
322 switch (blurRec.fStyle) {
323 case SkBlurStyle::kNormal_SkBlurStyle:
324 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_NORMAL);
325 break;
326 case SkBlurStyle::kSolid_SkBlurStyle:
327 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_SOLID);
328 break;
329 case SkBlurStyle::kOuter_SkBlurStyle:
330 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_OUTER);
331 break;
332 case SkBlurStyle::kInner_SkBlurStyle:
333 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_INNER);
334 break;
335 default:
336 SkASSERT(false);
337 }
338 switch (blurRec.fQuality) {
339 case SkBlurQuality::kLow_SkBlurQuality:
340 blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_LOW);
341 break;
342 case SkBlurQuality::kHigh_SkBlurQuality:
343 blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_HIGH);
344 break;
345 default:
346 SkASSERT(false);
347 }
ethannicholas30c5dde2016-02-02 08:36:58 -0800348 (*target)[SKJSONCANVAS_ATTRIBUTE_BLUR] = blur;
ethannicholas78fc22a2016-01-29 07:15:08 -0800349 }
350 else {
ethannicholas30c5dde2016-02-02 08:36:58 -0800351 Json::Value jsonMaskFilter;
352 flatten(maskFilter, &jsonMaskFilter, sendBinaries);
353 (*target)[SKJSONCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
ethannicholas78fc22a2016-01-29 07:15:08 -0800354 }
ethannicholas978d08a2016-01-26 07:47:57 -0800355 }
ethannicholas30c5dde2016-02-02 08:36:58 -0800356}
357
358static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
ethannicholas78fc22a2016-01-29 07:15:08 -0800359 SkPathEffect* pathEffect = paint.getPathEffect();
360 if (pathEffect != nullptr) {
361 SkPathEffect::DashInfo dashInfo;
362 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
363 if (dashType == SkPathEffect::kDash_DashType) {
364 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
365 pathEffect->asADash(&dashInfo);
366 Json::Value dashing(Json::objectValue);
367 Json::Value intervals(Json::arrayValue);
368 for (int32_t i = 0; i < dashInfo.fCount; i++) {
369 intervals.append(Json::Value(dashInfo.fIntervals[i]));
370 }
371 free(dashInfo.fIntervals);
372 dashing[SKJSONCANVAS_ATTRIBUTE_INTERVALS] = intervals;
373 dashing[SKJSONCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
ethannicholas30c5dde2016-02-02 08:36:58 -0800374 (*target)[SKJSONCANVAS_ATTRIBUTE_DASHING] = dashing;
ethannicholas78fc22a2016-01-29 07:15:08 -0800375 }
376 else {
ethannicholas30c5dde2016-02-02 08:36:58 -0800377 Json::Value jsonPathEffect;
378 flatten(pathEffect, &jsonPathEffect, sendBinaries);
379 (*target)[SKJSONCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
ethannicholas78fc22a2016-01-29 07:15:08 -0800380 }
381 }
ethannicholas30c5dde2016-02-02 08:36:58 -0800382}
383
384static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
ethannicholas78fc22a2016-01-29 07:15:08 -0800385 SkPaint::Align textAlign = paint.getTextAlign();
386 if (textAlign != SkPaint::kLeft_Align) {
387 switch (textAlign) {
388 case SkPaint::kCenter_Align: {
ethannicholas30c5dde2016-02-02 08:36:58 -0800389 (*target)[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_CENTER;
ethannicholas78fc22a2016-01-29 07:15:08 -0800390 break;
391 }
392 case SkPaint::kRight_Align: {
ethannicholas30c5dde2016-02-02 08:36:58 -0800393 (*target)[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_RIGHT;
ethannicholas78fc22a2016-01-29 07:15:08 -0800394 break;
395 }
396 default: SkASSERT(false);
397 }
ethannicholas978d08a2016-01-26 07:47:57 -0800398 }
ethannicholas30c5dde2016-02-02 08:36:58 -0800399}
400
401static void apply_paint_shader(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
402 SkFlattenable* shader = paint.getShader();
403 if (shader != nullptr) {
404 Json::Value jsonShader;
405 flatten(shader, &jsonShader, sendBinaries);
406 (*target)[SKJSONCANVAS_ATTRIBUTE_SHADER] = jsonShader;
407 }
408}
409
410static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
411 SkFlattenable* xfermode = paint.getXfermode();
412 if (xfermode != nullptr) {
413 Json::Value jsonXfermode;
414 flatten(xfermode, &jsonXfermode, sendBinaries);
415 (*target)[SKJSONCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
416 }
417}
418
ethannicholas0bd10342016-02-04 06:45:25 -0800419static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
420 SkFlattenable* imageFilter = paint.getImageFilter();
421 if (imageFilter != nullptr) {
422 Json::Value jsonImageFilter;
423 flatten(imageFilter, &jsonImageFilter, sendBinaries);
424 (*target)[SKJSONCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
425 }
426}
427
ethannicholas30c5dde2016-02-02 08:36:58 -0800428Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) {
429 Json::Value result(Json::objectValue);
430 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
431 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
432 SkPaintDefaults_MiterLimit);
433 store_bool(&result, SKJSONCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
434 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
435 SkPaintDefaults_TextSize);
436 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
437 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
438 apply_paint_color(paint, &result);
439 apply_paint_style(paint, &result);
440 apply_paint_cap(paint, &result);
441 apply_paint_textalign(paint, &result);
442 apply_paint_patheffect(paint, &result, fSendBinaries);
443 apply_paint_maskfilter(paint, &result, fSendBinaries);
444 apply_paint_shader(paint, &result, fSendBinaries);
445 apply_paint_xfermode(paint, &result, fSendBinaries);
ethannicholas0bd10342016-02-04 06:45:25 -0800446 apply_paint_imagefilter(paint, &result, fSendBinaries);
ethannicholas2bbc3432016-01-27 09:06:35 -0800447 return result;
ethannicholas978d08a2016-01-26 07:47:57 -0800448}
449
joshualitt29e5a892016-02-04 06:08:33 -0800450Json::Value SkJSONCanvas::MakeIRect(const SkIRect& rect) {
451 Json::Value result(Json::arrayValue);
452 result.append(Json::Value(rect.left()));
453 result.append(Json::Value(rect.top()));
454 result.append(Json::Value(rect.right()));
455 result.append(Json::Value(rect.bottom()));
456 return result;
457}
458
459Json::Value SkJSONCanvas::MakeMatrix(const SkMatrix& matrix) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800460 Json::Value result(Json::arrayValue);
461 Json::Value row1(Json::arrayValue);
462 row1.append(Json::Value(matrix[0]));
463 row1.append(Json::Value(matrix[1]));
464 row1.append(Json::Value(matrix[2]));
465 result.append(row1);
466 Json::Value row2(Json::arrayValue);
467 row2.append(Json::Value(matrix[3]));
468 row2.append(Json::Value(matrix[4]));
469 row2.append(Json::Value(matrix[5]));
470 result.append(row2);
471 Json::Value row3(Json::arrayValue);
472 row3.append(Json::Value(matrix[6]));
473 row3.append(Json::Value(matrix[7]));
474 row3.append(Json::Value(matrix[8]));
475 result.append(row3);
476 return result;
ethannicholas978d08a2016-01-26 07:47:57 -0800477}
478
ethannicholas2bbc3432016-01-27 09:06:35 -0800479Json::Value SkJSONCanvas::makeRegionOp(SkRegion::Op op) {
480 switch (op) {
ethannicholas978d08a2016-01-26 07:47:57 -0800481 case SkRegion::kDifference_Op:
ethannicholas2bbc3432016-01-27 09:06:35 -0800482 return Json::Value(SKJSONCANVAS_REGIONOP_DIFFERENCE);
ethannicholas978d08a2016-01-26 07:47:57 -0800483 case SkRegion::kIntersect_Op:
ethannicholas2bbc3432016-01-27 09:06:35 -0800484 return Json::Value(SKJSONCANVAS_REGIONOP_INTERSECT);
ethannicholas978d08a2016-01-26 07:47:57 -0800485 case SkRegion::kUnion_Op:
ethannicholas2bbc3432016-01-27 09:06:35 -0800486 return Json::Value(SKJSONCANVAS_REGIONOP_UNION);
ethannicholas978d08a2016-01-26 07:47:57 -0800487 case SkRegion::kXOR_Op:
ethannicholas2bbc3432016-01-27 09:06:35 -0800488 return Json::Value(SKJSONCANVAS_REGIONOP_XOR);
ethannicholas978d08a2016-01-26 07:47:57 -0800489 case SkRegion::kReverseDifference_Op:
ethannicholas2bbc3432016-01-27 09:06:35 -0800490 return Json::Value(SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE);
ethannicholas978d08a2016-01-26 07:47:57 -0800491 case SkRegion::kReplace_Op:
ethannicholas2bbc3432016-01-27 09:06:35 -0800492 return Json::Value(SKJSONCANVAS_REGIONOP_REPLACE);
ethannicholas978d08a2016-01-26 07:47:57 -0800493 default:
494 SkASSERT(false);
ethannicholas2bbc3432016-01-27 09:06:35 -0800495 return Json::Value("<invalid region op>");
ethannicholas978d08a2016-01-26 07:47:57 -0800496 };
ethannicholas978d08a2016-01-26 07:47:57 -0800497}
498
ethannicholas2bbc3432016-01-27 09:06:35 -0800499Json::Value SkJSONCanvas::makePointMode(SkCanvas::PointMode mode) {
ethannicholas978d08a2016-01-26 07:47:57 -0800500 switch (mode) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800501 case SkCanvas::kPoints_PointMode:
502 return Json::Value(SKJSONCANVAS_POINTMODE_POINTS);
503 case SkCanvas::kLines_PointMode:
504 return Json::Value(SKJSONCANVAS_POINTMODE_LINES);
505 case SkCanvas::kPolygon_PointMode:
506 return Json::Value(SKJSONCANVAS_POINTMODE_POLYGON);
507 default:
508 SkASSERT(false);
509 return Json::Value("<invalid point mode>");
ethannicholas978d08a2016-01-26 07:47:57 -0800510 };
ethannicholas978d08a2016-01-26 07:47:57 -0800511}
512
513void SkJSONCanvas::updateMatrix() {
ethannicholas2bbc3432016-01-27 09:06:35 -0800514 const SkMatrix& matrix = this->getTotalMatrix();
515 if (matrix != fLastMatrix) {
516 Json::Value command(Json::objectValue);
517 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_MATRIX);
joshualitt29e5a892016-02-04 06:08:33 -0800518 command[SKJSONCANVAS_ATTRIBUTE_MATRIX] = MakeMatrix(matrix);
ethannicholas2bbc3432016-01-27 09:06:35 -0800519 fCommands.append(command);
520 fLastMatrix = matrix;
521 }
ethannicholas978d08a2016-01-26 07:47:57 -0800522}
523
524void SkJSONCanvas::onDrawPaint(const SkPaint& paint) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800525 Json::Value command(Json::objectValue);
526 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PAINT);
527 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
528 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800529}
530
531void SkJSONCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800532 this->updateMatrix();
533 Json::Value command(Json::objectValue);
534 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RECT);
535 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect);
536 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
537 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800538}
539
540void SkJSONCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800541 this->updateMatrix();
542 Json::Value command(Json::objectValue);
543 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_OVAL);
544 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect);
545 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
546 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800547}
548
549void SkJSONCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800550 this->updateMatrix();
551 Json::Value command(Json::objectValue);
552 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RRECT);
553 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect);
554 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
555 fCommands.append(command);
556}
ethannicholas978d08a2016-01-26 07:47:57 -0800557
558void SkJSONCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
559 this->updateMatrix();
ethannicholas2bbc3432016-01-27 09:06:35 -0800560 Json::Value command(Json::objectValue);
561 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RRECT);
562 command[SKJSONCANVAS_ATTRIBUTE_INNER] = this->makeRRect(inner);
563 command[SKJSONCANVAS_ATTRIBUTE_OUTER] = this->makeRRect(outer);
564 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
565 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800566}
567
568void SkJSONCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
ethannicholas2bbc3432016-01-27 09:06:35 -0800569 const SkPaint& paint) {
ethannicholas978d08a2016-01-26 07:47:57 -0800570 this->updateMatrix();
ethannicholas2bbc3432016-01-27 09:06:35 -0800571 Json::Value command(Json::objectValue);
572 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POINTS);
573 command[SKJSONCANVAS_ATTRIBUTE_MODE] = this->makePointMode(mode);
574 Json::Value points(Json::arrayValue);
ethannicholas978d08a2016-01-26 07:47:57 -0800575 for (size_t i = 0; i < count; i++) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800576 points.append(this->makePoint(pts[i]));
ethannicholas978d08a2016-01-26 07:47:57 -0800577 }
ethannicholas2bbc3432016-01-27 09:06:35 -0800578 command[SKJSONCANVAS_ATTRIBUTE_POINTS] = points;
579 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
580 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800581}
582
583void SkJSONCanvas::onDrawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint vertices[],
584 const SkPoint texs[], const SkColor colors[], SkXfermode*,
585 const uint16_t indices[], int indexCount, const SkPaint&) {
586 SkDebugf("unsupported: drawVertices\n");
587}
588
589void SkJSONCanvas::onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
590 int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) {
591 SkDebugf("unsupported: drawAtlas\n");
592}
593
594void SkJSONCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800595 this->updateMatrix();
596 Json::Value command(Json::objectValue);
597 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PATH);
598 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path);
599 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
600 fCommands.append(command);
601}
ethannicholas978d08a2016-01-26 07:47:57 -0800602
ethannicholas30c5dde2016-02-02 08:36:58 -0800603void SkJSONCanvas::onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy,
604 const SkPaint* paint) {
605 Json::Value encoded;
606 if (flatten(*image, &encoded, fSendBinaries)) {
607 this->updateMatrix();
608 Json::Value command(Json::objectValue);
609 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGE);
610 command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded;
611 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(dx, dy);
612 if (paint != nullptr) {
613 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
614 }
615 fCommands.append(command);
616 }
ethannicholas978d08a2016-01-26 07:47:57 -0800617}
618
ethannicholas30c5dde2016-02-02 08:36:58 -0800619void SkJSONCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
620 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
621 Json::Value encoded;
622 if (flatten(*image, &encoded, fSendBinaries)) {
623 this->updateMatrix();
624 Json::Value command(Json::objectValue);
625 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGERECT);
626 command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded;
627 if (src != nullptr) {
628 command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src);
629 }
630 command[SKJSONCANVAS_ATTRIBUTE_DST] = this->makeRect(dst);
631 if (paint != nullptr) {
632 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
633 }
634 if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
635 command[SKJSONCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
636 }
637 fCommands.append(command);
638 }
ethannicholas978d08a2016-01-26 07:47:57 -0800639}
640
641void SkJSONCanvas::onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
642 const SkPaint*) {
643 SkDebugf("unsupported: drawImageNine\n");
644}
645
ethannicholas30c5dde2016-02-02 08:36:58 -0800646void SkJSONCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
647 const SkPaint* paint) {
648 Json::Value encoded;
649 if (flatten(bitmap, &encoded, fSendBinaries)) {
650 this->updateMatrix();
651 Json::Value command(Json::objectValue);
652 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAP);
653 command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded;
654 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(dx, dy);
655 if (paint != nullptr) {
656 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
657 }
658 fCommands.append(command);
659 }
ethannicholas978d08a2016-01-26 07:47:57 -0800660}
661
ethannicholas30c5dde2016-02-02 08:36:58 -0800662void SkJSONCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
663 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
664 Json::Value encoded;
665 if (flatten(bitmap, &encoded, fSendBinaries)) {
666 this->updateMatrix();
667 Json::Value command(Json::objectValue);
668 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAPRECT);
ethannicholas0bd10342016-02-04 06:45:25 -0800669 command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded;
ethannicholas30c5dde2016-02-02 08:36:58 -0800670 if (src != nullptr) {
671 command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src);
672 }
673 command[SKJSONCANVAS_ATTRIBUTE_DST] = this->makeRect(dst);
674 if (paint != nullptr) {
675 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
676 }
677 if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
678 command[SKJSONCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
679 }
680 fCommands.append(command);
681 }
ethannicholas978d08a2016-01-26 07:47:57 -0800682}
683
684void SkJSONCanvas::onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
685 const SkPaint*) {
686 SkDebugf("unsupported: drawBitmapNine\n");
687}
688
689void SkJSONCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x,
690 SkScalar y, const SkPaint& paint) {
691 this->updateMatrix();
ethannicholas2bbc3432016-01-27 09:06:35 -0800692 Json::Value command(Json::objectValue);
693 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXT);
694 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text,
695 ((const char*) text) + byteLength);
696 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(x, y);
697 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
698 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800699}
700
701void SkJSONCanvas::onDrawPosText(const void* text, size_t byteLength,
702 const SkPoint pos[], const SkPaint& paint) {
ethannicholas78fc22a2016-01-29 07:15:08 -0800703 this->updateMatrix();
704 Json::Value command(Json::objectValue);
705 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POSTEXT);
706 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text,
707 ((const char*) text) + byteLength);
708 Json::Value coords(Json::arrayValue);
709 for (size_t i = 0; i < byteLength; i++) {
710 coords.append(this->makePoint(pos[i]));
711 }
712 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = coords;
713 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
714 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800715}
716
717void SkJSONCanvas::onDrawPosTextH(const void* text, size_t byteLength,
718 const SkScalar xpos[], SkScalar constY,
719 const SkPaint& paint) {
720 SkDebugf("unsupported: drawPosTextH\n");
721}
722
723void SkJSONCanvas::onDrawTextOnPath(const void* text, size_t byteLength,
724 const SkPath& path, const SkMatrix* matrix,
725 const SkPaint& paint) {
726 SkDebugf("unsupported: drawTextOnPath\n");
727}
728
729void SkJSONCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
730 const SkPaint& paint) {
731 SkDebugf("unsupported: drawTextBlob\n");
732}
733
734void SkJSONCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
735 const SkPoint texCoords[4], SkXfermode* xmode,
736 const SkPaint& paint) {
737 SkDebugf("unsupported: drawPatch\n");
738}
739
740void SkJSONCanvas::onDrawDrawable(SkDrawable*, const SkMatrix*) {
741 SkDebugf("unsupported: drawDrawable\n");
742}
743
744void SkJSONCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800745 this->updateMatrix();
746 Json::Value command(Json::objectValue);
747 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRECT);
748 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect);
749 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
ethannicholas78fc22a2016-01-29 07:15:08 -0800750 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle);
ethannicholas2bbc3432016-01-27 09:06:35 -0800751 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800752}
753
754void SkJSONCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800755 this->updateMatrix();
756 Json::Value command(Json::objectValue);
757 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRRECT);
758 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect);
759 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
ethannicholas78fc22a2016-01-29 07:15:08 -0800760 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle);
ethannicholas2bbc3432016-01-27 09:06:35 -0800761 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800762}
763
764void SkJSONCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800765 this->updateMatrix();
766 Json::Value command(Json::objectValue);
767 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPPATH);
768 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path);
769 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
ethannicholas78fc22a2016-01-29 07:15:08 -0800770 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle);
ethannicholas2bbc3432016-01-27 09:06:35 -0800771 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800772}
773
774void SkJSONCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
ethannicholas2bbc3432016-01-27 09:06:35 -0800775 this->updateMatrix();
776 Json::Value command(Json::objectValue);
777 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPREGION);
778 command[SKJSONCANVAS_ATTRIBUTE_REGION] = this->makeRegion(deviceRgn);
779 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
780 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800781}
782
783void SkJSONCanvas::willSave() {
ethannicholas78fc22a2016-01-29 07:15:08 -0800784 this->updateMatrix();
ethannicholas2bbc3432016-01-27 09:06:35 -0800785 Json::Value command(Json::objectValue);
786 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVE);
787 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800788}
789
790void SkJSONCanvas::willRestore() {
ethannicholas2bbc3432016-01-27 09:06:35 -0800791 Json::Value command(Json::objectValue);
792 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RESTORE);
793 fCommands.append(command);
ethannicholas978d08a2016-01-26 07:47:57 -0800794}
ethannicholas30c5dde2016-02-02 08:36:58 -0800795
796SkCanvas::SaveLayerStrategy SkJSONCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
ethannicholas0bd10342016-02-04 06:45:25 -0800797 this->updateMatrix();
ethannicholas30c5dde2016-02-02 08:36:58 -0800798 Json::Value command(Json::objectValue);
799 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVELAYER);
800 if (rec.fBounds != nullptr) {
801 command[SKJSONCANVAS_ATTRIBUTE_BOUNDS] = this->makeRect(*rec.fBounds);
802 }
803 if (rec.fPaint != nullptr) {
804 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*rec.fPaint);
805 }
806 if (rec.fBackdrop != nullptr) {
807 Json::Value backdrop;
808 flatten(rec.fBackdrop, &backdrop, fSendBinaries);
809 command[SKJSONCANVAS_ATTRIBUTE_BACKDROP] = backdrop;
810 }
811 if (rec.fSaveLayerFlags != 0) {
812 SkDebugf("unsupported: saveLayer flags\n");
813 }
814 fCommands.append(command);
815 return this->INHERITED::getSaveLayerStrategy(rec);
816}