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 "SkColorFilter.h"
10 #include "SkImageFilter.h"
11 #include "SkMaskFilter.h"
12 #include "SkPaintDefaults.h"
13 #include "SkPath.h"
14 #include "SkPathEffect.h"
15 #include "SkRRect.h"
16 #include "SkTextBlob.h"
17 #include "SkTextBlobRunIterator.h"
18 #include "SkTypeface.h"
19 #include "SkWriteBuffer.h"
20
SkJSONCanvas(int width,int height,SkWStream & out,bool sendBinaries)21 SkJSONCanvas::SkJSONCanvas(int width, int height, SkWStream& out, bool sendBinaries)
22 : INHERITED(width, height)
23 , fOut(out)
24 , fRoot(Json::objectValue)
25 , fCommands(Json::arrayValue)
26 , fSendBinaries(sendBinaries) {
27 fRoot[SKJSONCANVAS_VERSION] = Json::Value(1);
28 }
29
finish()30 void SkJSONCanvas::finish() {
31 fRoot[SKJSONCANVAS_COMMANDS] = fCommands;
32 fOut.writeText(Json::FastWriter().write(fRoot).c_str());
33 }
34
makePoint(const SkPoint & point)35 Json::Value SkJSONCanvas::makePoint(const SkPoint& point) {
36 Json::Value result(Json::arrayValue);
37 result.append(Json::Value(point.x()));
38 result.append(Json::Value(point.y()));
39 return result;
40 }
41
makePoint(SkScalar x,SkScalar y)42 Json::Value SkJSONCanvas::makePoint(SkScalar x, SkScalar y) {
43 Json::Value result(Json::arrayValue);
44 result.append(Json::Value(x));
45 result.append(Json::Value(y));
46 return result;
47 }
48
makeRect(const SkRect & rect)49 Json::Value SkJSONCanvas::makeRect(const SkRect& rect) {
50 Json::Value result(Json::arrayValue);
51 result.append(Json::Value(rect.left()));
52 result.append(Json::Value(rect.top()));
53 result.append(Json::Value(rect.right()));
54 result.append(Json::Value(rect.bottom()));
55 return result;
56 }
57
makeRRect(const SkRRect & rrect)58 Json::Value SkJSONCanvas::makeRRect(const SkRRect& rrect) {
59 Json::Value result(Json::arrayValue);
60 result.append(this->makeRect(rrect.rect()));
61 result.append(this->makePoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
62 result.append(this->makePoint(rrect.radii(SkRRect::kUpperRight_Corner)));
63 result.append(this->makePoint(rrect.radii(SkRRect::kLowerRight_Corner)));
64 result.append(this->makePoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
65 return result;
66 }
67
makePath(const SkPath & path)68 Json::Value SkJSONCanvas::makePath(const SkPath& path) {
69 Json::Value result(Json::objectValue);
70 switch (path.getFillType()) {
71 case SkPath::kWinding_FillType:
72 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_WINDING;
73 break;
74 case SkPath::kEvenOdd_FillType:
75 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_EVENODD;
76 break;
77 case SkPath::kInverseWinding_FillType:
78 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEWINDING;
79 break;
80 case SkPath::kInverseEvenOdd_FillType:
81 result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEEVENODD;
82 break;
83 }
84 Json::Value verbs(Json::arrayValue);
85 SkPath::Iter iter(path, false);
86 SkPoint pts[4];
87 SkPath::Verb verb;
88 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
89 switch (verb) {
90 case SkPath::kLine_Verb: {
91 Json::Value line(Json::objectValue);
92 line[SKJSONCANVAS_VERB_LINE] = this->makePoint(pts[1]);
93 verbs.append(line);
94 break;
95 }
96 case SkPath::kQuad_Verb: {
97 Json::Value quad(Json::objectValue);
98 Json::Value coords(Json::arrayValue);
99 coords.append(this->makePoint(pts[1]));
100 coords.append(this->makePoint(pts[2]));
101 quad[SKJSONCANVAS_VERB_QUAD] = coords;
102 verbs.append(quad);
103 break;
104 }
105 case SkPath::kCubic_Verb: {
106 Json::Value cubic(Json::objectValue);
107 Json::Value coords(Json::arrayValue);
108 coords.append(this->makePoint(pts[1]));
109 coords.append(this->makePoint(pts[2]));
110 coords.append(this->makePoint(pts[3]));
111 cubic[SKJSONCANVAS_VERB_CUBIC] = coords;
112 verbs.append(cubic);
113 break;
114 }
115 case SkPath::kConic_Verb: {
116 Json::Value conic(Json::objectValue);
117 Json::Value coords(Json::arrayValue);
118 coords.append(this->makePoint(pts[1]));
119 coords.append(this->makePoint(pts[2]));
120 coords.append(Json::Value(iter.conicWeight()));
121 conic[SKJSONCANVAS_VERB_CONIC] = coords;
122 verbs.append(conic);
123 break;
124 }
125 case SkPath::kMove_Verb: {
126 Json::Value move(Json::objectValue);
127 move[SKJSONCANVAS_VERB_MOVE] = this->makePoint(pts[0]);
128 verbs.append(move);
129 break;
130 }
131 case SkPath::kClose_Verb:
132 verbs.append(Json::Value(SKJSONCANVAS_VERB_CLOSE));
133 break;
134 case SkPath::kDone_Verb:
135 break;
136 }
137 }
138 result[SKJSONCANVAS_ATTRIBUTE_VERBS] = verbs;
139 return result;
140 }
141
makeRegion(const SkRegion & region)142 Json::Value SkJSONCanvas::makeRegion(const SkRegion& region) {
143 return Json::Value("<unimplemented>");
144 }
145
store_scalar(Json::Value * target,const char * key,SkScalar value,SkScalar defaultValue)146 static void store_scalar(Json::Value* target, const char* key, SkScalar value,
147 SkScalar defaultValue) {
148 if (value != defaultValue) {
149 (*target)[key] = Json::Value(value);
150 }
151 }
152
store_bool(Json::Value * target,const char * key,bool value,bool defaultValue)153 static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
154 if (value != defaultValue) {
155 (*target)[key] = Json::Value(value);
156 }
157 }
158
encode_data(const void * data,size_t count,Json::Value * target)159 static void encode_data(const void* data, size_t count, Json::Value* target) {
160 // just use a brain-dead JSON array for now, switch to base64 or something else smarter down the
161 // road
162 for (size_t i = 0; i < count; i++) {
163 target->append(((const uint8_t*)data)[i]);
164 }
165 }
166
flatten(const SkFlattenable * flattenable,Json::Value * target,bool sendBinaries)167 static void flatten(const SkFlattenable* flattenable, Json::Value* target, bool sendBinaries) {
168 if (sendBinaries) {
169 SkWriteBuffer buffer;
170 flattenable->flatten(buffer);
171 void* data = sk_malloc_throw(buffer.bytesWritten());
172 buffer.writeToMemory(data);
173 Json::Value bytes;
174 encode_data(data, buffer.bytesWritten(), &bytes);
175 Json::Value jsonFlattenable;
176 jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
177 jsonFlattenable[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes;
178 (*target) = jsonFlattenable;
179 free(data);
180 }
181 else {
182 (*target)[SKJSONCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(flattenable->getTypeName());
183 }
184 }
185
flatten(const SkImage & image,Json::Value * target,bool sendBinaries)186 static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target,
187 bool sendBinaries) {
188 if (sendBinaries) {
189 SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100);
190 if (encoded == nullptr) {
191 // PNG encode doesn't necessarily support all color formats, convert to a different
192 // format
193 size_t rowBytes = 4 * image.width();
194 void* buffer = sk_malloc_throw(rowBytes * image.height());
195 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
196 kN32_SkColorType, kPremul_SkAlphaType);
197 if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) {
198 SkDebugf("readPixels failed\n");
199 return false;
200 }
201 SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes);
202 encoded = converted->encode(SkImageEncoder::kPNG_Type, 100);
203 if (encoded == nullptr) {
204 SkDebugf("image encode failed\n");
205 return false;
206 }
207 free(converted);
208 free(buffer);
209 }
210 Json::Value bytes;
211 encode_data(encoded->data(), encoded->size(), &bytes);
212 (*target)[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes;
213 encoded->unref();
214 }
215 else {
216 SkString description = SkStringPrintf("%dx%d pixel image", image.width(), image.height());
217 (*target)[SKJSONCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(description.c_str());
218 }
219 return true;
220 }
221
color_type_name(SkColorType colorType)222 static const char* color_type_name(SkColorType colorType) {
223 switch (colorType) {
224 case kARGB_4444_SkColorType:
225 return SKJSONCANVAS_COLORTYPE_ARGB4444;
226 case kRGBA_8888_SkColorType:
227 return SKJSONCANVAS_COLORTYPE_RGBA8888;
228 case kBGRA_8888_SkColorType:
229 return SKJSONCANVAS_COLORTYPE_BGRA8888;
230 case kRGB_565_SkColorType:
231 return SKJSONCANVAS_COLORTYPE_565;
232 case kGray_8_SkColorType:
233 return SKJSONCANVAS_COLORTYPE_GRAY8;
234 case kIndex_8_SkColorType:
235 return SKJSONCANVAS_COLORTYPE_INDEX8;
236 case kAlpha_8_SkColorType:
237 return SKJSONCANVAS_COLORTYPE_ALPHA8;
238 default:
239 SkASSERT(false);
240 return SKJSONCANVAS_COLORTYPE_RGBA8888;
241 }
242 }
243
alpha_type_name(SkAlphaType alphaType)244 static const char* alpha_type_name(SkAlphaType alphaType) {
245 switch (alphaType) {
246 case kOpaque_SkAlphaType:
247 return SKJSONCANVAS_ALPHATYPE_OPAQUE;
248 case kPremul_SkAlphaType:
249 return SKJSONCANVAS_ALPHATYPE_PREMUL;
250 case kUnpremul_SkAlphaType:
251 return SKJSONCANVAS_ALPHATYPE_UNPREMUL;
252 default:
253 SkASSERT(false);
254 return SKJSONCANVAS_ALPHATYPE_OPAQUE;
255 }
256 }
257
flatten(const SkBitmap & bitmap,Json::Value * target,bool sendBinaries)258 static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target,
259 bool sendBinaries) {
260 bitmap.lockPixels();
261 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
262 bitmap.unlockPixels();
263 (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
264 (*target)[SKJSONCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
265 bool success = flatten(*image, target, sendBinaries);
266 return success;
267 }
268
apply_paint_color(const SkPaint & paint,Json::Value * target)269 static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
270 SkColor color = paint.getColor();
271 if (color != SK_ColorBLACK) {
272 Json::Value colorValue(Json::arrayValue);
273 colorValue.append(Json::Value(SkColorGetA(color)));
274 colorValue.append(Json::Value(SkColorGetR(color)));
275 colorValue.append(Json::Value(SkColorGetG(color)));
276 colorValue.append(Json::Value(SkColorGetB(color)));
277 (*target)[SKJSONCANVAS_ATTRIBUTE_COLOR] = colorValue;;
278 }
279 }
280
apply_paint_style(const SkPaint & paint,Json::Value * target)281 static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
282 SkPaint::Style style = paint.getStyle();
283 if (style != SkPaint::kFill_Style) {
284 switch (style) {
285 case SkPaint::kStroke_Style: {
286 Json::Value stroke(SKJSONCANVAS_STYLE_STROKE);
287 (*target)[SKJSONCANVAS_ATTRIBUTE_STYLE] = stroke;
288 break;
289 }
290 case SkPaint::kStrokeAndFill_Style: {
291 Json::Value strokeAndFill(SKJSONCANVAS_STYLE_STROKEANDFILL);
292 (*target)[SKJSONCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
293 break;
294 }
295 default: SkASSERT(false);
296 }
297 }
298 }
299
apply_paint_cap(const SkPaint & paint,Json::Value * target)300 static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
301 SkPaint::Cap cap = paint.getStrokeCap();
302 if (cap != SkPaint::kDefault_Cap) {
303 switch (cap) {
304 case SkPaint::kButt_Cap: {
305 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_BUTT);
306 break;
307 }
308 case SkPaint::kRound_Cap: {
309 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_ROUND);
310 break;
311 }
312 case SkPaint::kSquare_Cap: {
313 (*target)[SKJSONCANVAS_ATTRIBUTE_CAP] = Json::Value(SKJSONCANVAS_CAP_SQUARE);
314 break;
315 }
316 default: SkASSERT(false);
317 }
318 }
319 }
apply_paint_maskfilter(const SkPaint & paint,Json::Value * target,bool sendBinaries)320 static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
321 SkMaskFilter* maskFilter = paint.getMaskFilter();
322 if (maskFilter != nullptr) {
323 SkMaskFilter::BlurRec blurRec;
324 if (maskFilter->asABlur(&blurRec)) {
325 Json::Value blur(Json::objectValue);
326 blur[SKJSONCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
327 switch (blurRec.fStyle) {
328 case SkBlurStyle::kNormal_SkBlurStyle:
329 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_NORMAL);
330 break;
331 case SkBlurStyle::kSolid_SkBlurStyle:
332 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_SOLID);
333 break;
334 case SkBlurStyle::kOuter_SkBlurStyle:
335 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_OUTER);
336 break;
337 case SkBlurStyle::kInner_SkBlurStyle:
338 blur[SKJSONCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKJSONCANVAS_BLURSTYLE_INNER);
339 break;
340 default:
341 SkASSERT(false);
342 }
343 switch (blurRec.fQuality) {
344 case SkBlurQuality::kLow_SkBlurQuality:
345 blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_LOW);
346 break;
347 case SkBlurQuality::kHigh_SkBlurQuality:
348 blur[SKJSONCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKJSONCANVAS_BLURQUALITY_HIGH);
349 break;
350 default:
351 SkASSERT(false);
352 }
353 (*target)[SKJSONCANVAS_ATTRIBUTE_BLUR] = blur;
354 }
355 else {
356 Json::Value jsonMaskFilter;
357 flatten(maskFilter, &jsonMaskFilter, sendBinaries);
358 (*target)[SKJSONCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
359 }
360 }
361 }
362
apply_paint_patheffect(const SkPaint & paint,Json::Value * target,bool sendBinaries)363 static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
364 SkPathEffect* pathEffect = paint.getPathEffect();
365 if (pathEffect != nullptr) {
366 SkPathEffect::DashInfo dashInfo;
367 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
368 if (dashType == SkPathEffect::kDash_DashType) {
369 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
370 pathEffect->asADash(&dashInfo);
371 Json::Value dashing(Json::objectValue);
372 Json::Value intervals(Json::arrayValue);
373 for (int32_t i = 0; i < dashInfo.fCount; i++) {
374 intervals.append(Json::Value(dashInfo.fIntervals[i]));
375 }
376 free(dashInfo.fIntervals);
377 dashing[SKJSONCANVAS_ATTRIBUTE_INTERVALS] = intervals;
378 dashing[SKJSONCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
379 (*target)[SKJSONCANVAS_ATTRIBUTE_DASHING] = dashing;
380 }
381 else {
382 Json::Value jsonPathEffect;
383 flatten(pathEffect, &jsonPathEffect, sendBinaries);
384 (*target)[SKJSONCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
385 }
386 }
387 }
388
apply_paint_textalign(const SkPaint & paint,Json::Value * target)389 static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
390 SkPaint::Align textAlign = paint.getTextAlign();
391 if (textAlign != SkPaint::kLeft_Align) {
392 switch (textAlign) {
393 case SkPaint::kCenter_Align: {
394 (*target)[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_CENTER;
395 break;
396 }
397 case SkPaint::kRight_Align: {
398 (*target)[SKJSONCANVAS_ATTRIBUTE_TEXTALIGN] = SKJSONCANVAS_ALIGN_RIGHT;
399 break;
400 }
401 default: SkASSERT(false);
402 }
403 }
404 }
405
apply_paint_typeface(const SkPaint & paint,Json::Value * target,bool sendBinaries)406 static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
407 bool sendBinaries) {
408 SkTypeface* typeface = paint.getTypeface();
409 if (typeface != nullptr) {
410 if (sendBinaries) {
411 Json::Value jsonTypeface;
412 SkDynamicMemoryWStream buffer;
413 typeface->serialize(&buffer);
414 void* data = sk_malloc_throw(buffer.bytesWritten());
415 buffer.copyTo(data);
416 Json::Value bytes;
417 encode_data(data, buffer.bytesWritten(), &bytes);
418 jsonTypeface[SKJSONCANVAS_ATTRIBUTE_BYTES] = bytes;
419 free(data);
420 (*target)[SKJSONCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
421 }
422 }
423 }
424
apply_paint_shader(const SkPaint & paint,Json::Value * target,bool sendBinaries)425 static void apply_paint_shader(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
426 SkFlattenable* shader = paint.getShader();
427 if (shader != nullptr) {
428 Json::Value jsonShader;
429 flatten(shader, &jsonShader, sendBinaries);
430 (*target)[SKJSONCANVAS_ATTRIBUTE_SHADER] = jsonShader;
431 }
432 }
433
apply_paint_xfermode(const SkPaint & paint,Json::Value * target,bool sendBinaries)434 static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
435 SkFlattenable* xfermode = paint.getXfermode();
436 if (xfermode != nullptr) {
437 Json::Value jsonXfermode;
438 flatten(xfermode, &jsonXfermode, sendBinaries);
439 (*target)[SKJSONCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
440 }
441 }
442
apply_paint_imagefilter(const SkPaint & paint,Json::Value * target,bool sendBinaries)443 static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
444 SkFlattenable* imageFilter = paint.getImageFilter();
445 if (imageFilter != nullptr) {
446 Json::Value jsonImageFilter;
447 flatten(imageFilter, &jsonImageFilter, sendBinaries);
448 (*target)[SKJSONCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
449 }
450 }
451
apply_paint_colorfilter(const SkPaint & paint,Json::Value * target,bool sendBinaries)452 static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
453 SkFlattenable* colorFilter = paint.getColorFilter();
454 if (colorFilter != nullptr) {
455 Json::Value jsonColorFilter;
456 flatten(colorFilter, &jsonColorFilter, sendBinaries);
457 (*target)[SKJSONCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
458 }
459 }
460
makePaint(const SkPaint & paint)461 Json::Value SkJSONCanvas::makePaint(const SkPaint& paint) {
462 Json::Value result(Json::objectValue);
463 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
464 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
465 SkPaintDefaults_MiterLimit);
466 store_bool(&result, SKJSONCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
467 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
468 SkPaintDefaults_TextSize);
469 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
470 store_scalar(&result, SKJSONCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
471 apply_paint_color(paint, &result);
472 apply_paint_style(paint, &result);
473 apply_paint_cap(paint, &result);
474 apply_paint_textalign(paint, &result);
475 apply_paint_patheffect(paint, &result, fSendBinaries);
476 apply_paint_maskfilter(paint, &result, fSendBinaries);
477 apply_paint_shader(paint, &result, fSendBinaries);
478 apply_paint_xfermode(paint, &result, fSendBinaries);
479 apply_paint_imagefilter(paint, &result, fSendBinaries);
480 apply_paint_colorfilter(paint, &result, fSendBinaries);
481 apply_paint_typeface(paint, &result, fSendBinaries);
482 return result;
483 }
484
MakeIRect(const SkIRect & rect)485 Json::Value SkJSONCanvas::MakeIRect(const SkIRect& rect) {
486 Json::Value result(Json::arrayValue);
487 result.append(Json::Value(rect.left()));
488 result.append(Json::Value(rect.top()));
489 result.append(Json::Value(rect.right()));
490 result.append(Json::Value(rect.bottom()));
491 return result;
492 }
493
MakeMatrix(const SkMatrix & matrix)494 Json::Value SkJSONCanvas::MakeMatrix(const SkMatrix& matrix) {
495 Json::Value result(Json::arrayValue);
496 Json::Value row1(Json::arrayValue);
497 row1.append(Json::Value(matrix[0]));
498 row1.append(Json::Value(matrix[1]));
499 row1.append(Json::Value(matrix[2]));
500 result.append(row1);
501 Json::Value row2(Json::arrayValue);
502 row2.append(Json::Value(matrix[3]));
503 row2.append(Json::Value(matrix[4]));
504 row2.append(Json::Value(matrix[5]));
505 result.append(row2);
506 Json::Value row3(Json::arrayValue);
507 row3.append(Json::Value(matrix[6]));
508 row3.append(Json::Value(matrix[7]));
509 row3.append(Json::Value(matrix[8]));
510 result.append(row3);
511 return result;
512 }
513
makeRegionOp(SkRegion::Op op)514 Json::Value SkJSONCanvas::makeRegionOp(SkRegion::Op op) {
515 switch (op) {
516 case SkRegion::kDifference_Op:
517 return Json::Value(SKJSONCANVAS_REGIONOP_DIFFERENCE);
518 case SkRegion::kIntersect_Op:
519 return Json::Value(SKJSONCANVAS_REGIONOP_INTERSECT);
520 case SkRegion::kUnion_Op:
521 return Json::Value(SKJSONCANVAS_REGIONOP_UNION);
522 case SkRegion::kXOR_Op:
523 return Json::Value(SKJSONCANVAS_REGIONOP_XOR);
524 case SkRegion::kReverseDifference_Op:
525 return Json::Value(SKJSONCANVAS_REGIONOP_REVERSE_DIFFERENCE);
526 case SkRegion::kReplace_Op:
527 return Json::Value(SKJSONCANVAS_REGIONOP_REPLACE);
528 default:
529 SkASSERT(false);
530 return Json::Value("<invalid region op>");
531 };
532 }
533
makePointMode(SkCanvas::PointMode mode)534 Json::Value SkJSONCanvas::makePointMode(SkCanvas::PointMode mode) {
535 switch (mode) {
536 case SkCanvas::kPoints_PointMode:
537 return Json::Value(SKJSONCANVAS_POINTMODE_POINTS);
538 case SkCanvas::kLines_PointMode:
539 return Json::Value(SKJSONCANVAS_POINTMODE_LINES);
540 case SkCanvas::kPolygon_PointMode:
541 return Json::Value(SKJSONCANVAS_POINTMODE_POLYGON);
542 default:
543 SkASSERT(false);
544 return Json::Value("<invalid point mode>");
545 };
546 }
547
didConcat(const SkMatrix & matrix)548 void SkJSONCanvas::didConcat(const SkMatrix& matrix) {
549 Json::Value command(Json::objectValue);
550 switch (matrix.getType()) {
551 case SkMatrix::kTranslate_Mask:
552 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TRANSLATE);
553 command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(matrix.get(SkMatrix::kMTransX));
554 command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(matrix.get(SkMatrix::kMTransY));
555 break;
556 case SkMatrix::kScale_Mask:
557 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SCALE);
558 command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(matrix.get(SkMatrix::kMScaleX));
559 command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(matrix.get(SkMatrix::kMScaleY));
560 break;
561 default:
562 this->didSetMatrix(this->getTotalMatrix());
563 return;
564 }
565 fCommands.append(command);
566 }
567
didSetMatrix(const SkMatrix & matrix)568 void SkJSONCanvas::didSetMatrix(const SkMatrix& matrix) {
569 Json::Value command(Json::objectValue);
570 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_MATRIX);
571 command[SKJSONCANVAS_ATTRIBUTE_MATRIX] = this->MakeMatrix(matrix);
572 fCommands.append(command);
573 }
574
onDrawPaint(const SkPaint & paint)575 void SkJSONCanvas::onDrawPaint(const SkPaint& paint) {
576 Json::Value command(Json::objectValue);
577 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PAINT);
578 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
579 fCommands.append(command);
580 }
581
onDrawRect(const SkRect & rect,const SkPaint & paint)582 void SkJSONCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
583 Json::Value command(Json::objectValue);
584 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RECT);
585 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect);
586 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
587 fCommands.append(command);
588 }
589
onDrawOval(const SkRect & rect,const SkPaint & paint)590 void SkJSONCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
591 Json::Value command(Json::objectValue);
592 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_OVAL);
593 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect);
594 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
595 fCommands.append(command);
596 }
597
onDrawRRect(const SkRRect & rrect,const SkPaint & paint)598 void SkJSONCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
599 Json::Value command(Json::objectValue);
600 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RRECT);
601 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect);
602 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
603 fCommands.append(command);
604 }
605
onDrawDRRect(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)606 void SkJSONCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
607 Json::Value command(Json::objectValue);
608 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RRECT);
609 command[SKJSONCANVAS_ATTRIBUTE_INNER] = this->makeRRect(inner);
610 command[SKJSONCANVAS_ATTRIBUTE_OUTER] = this->makeRRect(outer);
611 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
612 fCommands.append(command);
613 }
614
onDrawPoints(SkCanvas::PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)615 void SkJSONCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
616 const SkPaint& paint) {
617 Json::Value command(Json::objectValue);
618 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POINTS);
619 command[SKJSONCANVAS_ATTRIBUTE_MODE] = this->makePointMode(mode);
620 Json::Value points(Json::arrayValue);
621 for (size_t i = 0; i < count; i++) {
622 points.append(this->makePoint(pts[i]));
623 }
624 command[SKJSONCANVAS_ATTRIBUTE_POINTS] = points;
625 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
626 fCommands.append(command);
627 }
628
onDrawVertices(SkCanvas::VertexMode,int vertexCount,const SkPoint vertices[],const SkPoint texs[],const SkColor colors[],SkXfermode *,const uint16_t indices[],int indexCount,const SkPaint &)629 void SkJSONCanvas::onDrawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint vertices[],
630 const SkPoint texs[], const SkColor colors[], SkXfermode*,
631 const uint16_t indices[], int indexCount, const SkPaint&) {
632 SkDebugf("unsupported: drawVertices\n");
633 Json::Value command(Json::objectValue);
634 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_VERTICES);
635 fCommands.append(command);
636 }
637
onDrawAtlas(const SkImage *,const SkRSXform[],const SkRect[],const SkColor[],int count,SkXfermode::Mode,const SkRect * cull,const SkPaint *)638 void SkJSONCanvas::onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
639 int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) {
640 SkDebugf("unsupported: drawAtlas\n");
641 Json::Value command(Json::objectValue);
642 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_ATLAS);
643 fCommands.append(command);
644 }
645
onDrawPath(const SkPath & path,const SkPaint & paint)646 void SkJSONCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
647 Json::Value command(Json::objectValue);
648 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PATH);
649 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path);
650 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
651 fCommands.append(command);
652 }
653
onDrawImage(const SkImage * image,SkScalar dx,SkScalar dy,const SkPaint * paint)654 void SkJSONCanvas::onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy,
655 const SkPaint* paint) {
656 Json::Value encoded;
657 if (flatten(*image, &encoded, fSendBinaries)) {
658 Json::Value command(Json::objectValue);
659 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGE);
660 command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded;
661 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(dx, dy);
662 if (paint != nullptr) {
663 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
664 }
665 fCommands.append(command);
666 }
667 }
668
onDrawImageRect(const SkImage * image,const SkRect * src,const SkRect & dst,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)669 void SkJSONCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
670 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
671 Json::Value encoded;
672 if (flatten(*image, &encoded, fSendBinaries)) {
673 Json::Value command(Json::objectValue);
674 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGERECT);
675 command[SKJSONCANVAS_ATTRIBUTE_IMAGE] = encoded;
676 if (src != nullptr) {
677 command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src);
678 }
679 command[SKJSONCANVAS_ATTRIBUTE_DST] = this->makeRect(dst);
680 if (paint != nullptr) {
681 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
682 }
683 if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
684 command[SKJSONCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
685 }
686 fCommands.append(command);
687 }
688 }
689
onDrawImageNine(const SkImage *,const SkIRect & center,const SkRect & dst,const SkPaint *)690 void SkJSONCanvas::onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
691 const SkPaint*) {
692 SkDebugf("unsupported: drawImageNine\n");
693 Json::Value command(Json::objectValue);
694 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_IMAGENINE);
695 fCommands.append(command);
696 }
697
onDrawBitmap(const SkBitmap & bitmap,SkScalar dx,SkScalar dy,const SkPaint * paint)698 void SkJSONCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
699 const SkPaint* paint) {
700 Json::Value encoded;
701 if (flatten(bitmap, &encoded, fSendBinaries)) {
702 Json::Value command(Json::objectValue);
703 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAP);
704 command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded;
705 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(dx, dy);
706 if (paint != nullptr) {
707 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
708 }
709 fCommands.append(command);
710 }
711 }
712
onDrawBitmapRect(const SkBitmap & bitmap,const SkRect * src,const SkRect & dst,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)713 void SkJSONCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
714 const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) {
715 Json::Value encoded;
716 if (flatten(bitmap, &encoded, fSendBinaries)) {
717 Json::Value command(Json::objectValue);
718 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAPRECT);
719 command[SKJSONCANVAS_ATTRIBUTE_BITMAP] = encoded;
720 if (src != nullptr) {
721 command[SKJSONCANVAS_ATTRIBUTE_SRC] = this->makeRect(*src);
722 }
723 command[SKJSONCANVAS_ATTRIBUTE_DST] = this->makeRect(dst);
724 if (paint != nullptr) {
725 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*paint);
726 }
727 if (constraint == SkCanvas::kStrict_SrcRectConstraint) {
728 command[SKJSONCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
729 }
730 fCommands.append(command);
731 }
732 }
733
onDrawBitmapNine(const SkBitmap &,const SkIRect & center,const SkRect & dst,const SkPaint *)734 void SkJSONCanvas::onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
735 const SkPaint*) {
736 SkDebugf("unsupported: drawBitmapNine\n");
737 Json::Value command(Json::objectValue);
738 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_BITMAPNINE);
739 fCommands.append(command);
740 }
741
onDrawText(const void * text,size_t byteLength,SkScalar x,SkScalar y,const SkPaint & paint)742 void SkJSONCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x,
743 SkScalar y, const SkPaint& paint) {
744 Json::Value command(Json::objectValue);
745 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXT);
746 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text,
747 ((const char*) text) + byteLength);
748 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(x, y);
749 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
750 fCommands.append(command);
751 }
752
onDrawPosText(const void * text,size_t byteLength,const SkPoint pos[],const SkPaint & paint)753 void SkJSONCanvas::onDrawPosText(const void* text, size_t byteLength,
754 const SkPoint pos[], const SkPaint& paint) {
755 Json::Value command(Json::objectValue);
756 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POSTEXT);
757 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text,
758 ((const char*) text) + byteLength);
759 Json::Value coords(Json::arrayValue);
760 for (size_t i = 0; i < byteLength; i++) {
761 coords.append(this->makePoint(pos[i]));
762 }
763 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = coords;
764 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
765 fCommands.append(command);
766 }
767
onDrawPosTextH(const void * text,size_t byteLength,const SkScalar xpos[],SkScalar constY,const SkPaint & paint)768 void SkJSONCanvas::onDrawPosTextH(const void* text, size_t byteLength,
769 const SkScalar xpos[], SkScalar constY,
770 const SkPaint& paint) {
771 SkDebugf("unsupported: drawPosTextH\n");
772 Json::Value command(Json::objectValue);
773 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_POSTEXTH);
774 fCommands.append(command);
775 }
776
onDrawTextOnPath(const void * text,size_t byteLength,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)777 void SkJSONCanvas::onDrawTextOnPath(const void* text, size_t byteLength,
778 const SkPath& path, const SkMatrix* matrix,
779 const SkPaint& paint) {
780 Json::Value command(Json::objectValue);
781 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXTONPATH);
782 command[SKJSONCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) text,
783 ((const char*) text) + byteLength);
784 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path);
785 if (matrix != nullptr) {
786 command[SKJSONCANVAS_ATTRIBUTE_MATRIX] = this->MakeMatrix(*matrix);
787 }
788 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
789 fCommands.append(command);
790 }
791
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)792 void SkJSONCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
793 const SkPaint& paint) {
794 Json::Value command(Json::objectValue);
795 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_TEXTBLOB);
796 Json::Value runs(Json::arrayValue);
797 SkTextBlobRunIterator iter(blob);
798 while (!iter.done()) {
799 Json::Value run(Json::objectValue);
800 Json::Value jsonPositions(Json::arrayValue);
801 Json::Value jsonGlyphs(Json::arrayValue);
802 const SkScalar* iterPositions = iter.pos();
803 const uint16_t* iterGlyphs = iter.glyphs();
804 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
805 switch (iter.positioning()) {
806 case SkTextBlob::kFull_Positioning:
807 jsonPositions.append(this->makePoint(iterPositions[i * 2],
808 iterPositions[i * 2 + 1]));
809 break;
810 case SkTextBlob::kHorizontal_Positioning:
811 jsonPositions.append(Json::Value(iterPositions[i]));
812 break;
813 case SkTextBlob::kDefault_Positioning:
814 break;
815 }
816 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
817 }
818 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
819 run[SKJSONCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
820 }
821 run[SKJSONCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
822 SkPaint fontPaint;
823 iter.applyFontToPaint(&fontPaint);
824 run[SKJSONCANVAS_ATTRIBUTE_FONT] = this->makePaint(fontPaint);
825 run[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makePoint(iter.offset());
826 runs.append(run);
827 iter.next();
828 }
829 command[SKJSONCANVAS_ATTRIBUTE_RUNS] = runs;
830 command[SKJSONCANVAS_ATTRIBUTE_X] = Json::Value(x);
831 command[SKJSONCANVAS_ATTRIBUTE_Y] = Json::Value(y);
832 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(paint);
833 fCommands.append(command);
834 }
835
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkXfermode * xmode,const SkPaint & paint)836 void SkJSONCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
837 const SkPoint texCoords[4], SkXfermode* xmode,
838 const SkPaint& paint) {
839 SkDebugf("unsupported: drawPatch\n");
840 Json::Value command(Json::objectValue);
841 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_PATCH);
842 fCommands.append(command);
843 }
844
onDrawDrawable(SkDrawable *,const SkMatrix *)845 void SkJSONCanvas::onDrawDrawable(SkDrawable*, const SkMatrix*) {
846 SkDebugf("unsupported: drawDrawable\n");
847 Json::Value command(Json::objectValue);
848 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_DRAWABLE);
849 fCommands.append(command);
850 }
851
onClipRect(const SkRect & rect,SkRegion::Op op,ClipEdgeStyle edgeStyle)852 void SkJSONCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
853 Json::Value command(Json::objectValue);
854 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRECT);
855 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRect(rect);
856 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
857 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle);
858 fCommands.append(command);
859 }
860
onClipRRect(const SkRRect & rrect,SkRegion::Op op,ClipEdgeStyle edgeStyle)861 void SkJSONCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
862 Json::Value command(Json::objectValue);
863 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPRRECT);
864 command[SKJSONCANVAS_ATTRIBUTE_COORDS] = this->makeRRect(rrect);
865 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
866 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle);
867 fCommands.append(command);
868 }
869
onClipPath(const SkPath & path,SkRegion::Op op,ClipEdgeStyle edgeStyle)870 void SkJSONCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
871 Json::Value command(Json::objectValue);
872 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPPATH);
873 command[SKJSONCANVAS_ATTRIBUTE_PATH] = this->makePath(path);
874 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
875 command[SKJSONCANVAS_ATTRIBUTE_ANTIALIAS] = (edgeStyle == SkCanvas::kSoft_ClipEdgeStyle);
876 fCommands.append(command);
877 }
878
onClipRegion(const SkRegion & deviceRgn,SkRegion::Op op)879 void SkJSONCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
880 Json::Value command(Json::objectValue);
881 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_CLIPREGION);
882 command[SKJSONCANVAS_ATTRIBUTE_REGION] = this->makeRegion(deviceRgn);
883 command[SKJSONCANVAS_ATTRIBUTE_REGIONOP] = this->makeRegionOp(op);
884 fCommands.append(command);
885 }
886
willSave()887 void SkJSONCanvas::willSave() {
888 Json::Value command(Json::objectValue);
889 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVE);
890 fCommands.append(command);
891 }
892
willRestore()893 void SkJSONCanvas::willRestore() {
894 Json::Value command(Json::objectValue);
895 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_RESTORE);
896 fCommands.append(command);
897 }
898
getSaveLayerStrategy(const SaveLayerRec & rec)899 SkCanvas::SaveLayerStrategy SkJSONCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
900 Json::Value command(Json::objectValue);
901 command[SKJSONCANVAS_COMMAND] = Json::Value(SKJSONCANVAS_COMMAND_SAVELAYER);
902 if (rec.fBounds != nullptr) {
903 command[SKJSONCANVAS_ATTRIBUTE_BOUNDS] = this->makeRect(*rec.fBounds);
904 }
905 if (rec.fPaint != nullptr) {
906 command[SKJSONCANVAS_ATTRIBUTE_PAINT] = this->makePaint(*rec.fPaint);
907 }
908 if (rec.fBackdrop != nullptr) {
909 Json::Value backdrop;
910 flatten(rec.fBackdrop, &backdrop, fSendBinaries);
911 command[SKJSONCANVAS_ATTRIBUTE_BACKDROP] = backdrop;
912 }
913 if (rec.fSaveLayerFlags != 0) {
914 SkDebugf("unsupported: saveLayer flags\n");
915 }
916 fCommands.append(command);
917 return this->INHERITED::getSaveLayerStrategy(rec);
918 }
919