1 /*
2 * Copyright 2012 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 "SkDrawCommand.h"
9
10 #include "png.h"
11
12 #include "SkAutoMalloc.h"
13 #include "SkBlurMaskFilter.h"
14 #include "SkColorFilter.h"
15 #include "SkDashPathEffect.h"
16 #include "SkImageFilter.h"
17 #include "SkJsonWriteBuffer.h"
18 #include "SkMaskFilter.h"
19 #include "SkObjectParser.h"
20 #include "SkPaintDefaults.h"
21 #include "SkPathEffect.h"
22 #include "SkPicture.h"
23 #include "SkTextBlob.h"
24 #include "SkTextBlobRunIterator.h"
25 #include "SkTHash.h"
26 #include "SkTypeface.h"
27 #include "SkValidatingReadBuffer.h"
28 #include "SkWriteBuffer.h"
29 #include "picture_utils.h"
30 #include "SkClipOpPriv.h"
31 #include <SkLatticeIter.h>
32
33 #define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
34 #define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
35 #define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
36 #define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
37 #define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
38 #define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
39 #define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
40 #define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
41 #define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
42 #define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
43 #define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
44 #define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
45 #define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
46 #define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
47 #define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
48 #define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
49 #define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
50 #define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
51 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
52 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
53 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
54 #define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
55 #define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
56 #define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
57 #define SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
58 #define SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
59 #define SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
60 #define SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
61 #define SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
62 #define SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
63 #define SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
64 #define SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT "verticalText"
65 #define SKDEBUGCANVAS_ATTRIBUTE_REGION "region"
66 #define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
67 #define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
68 #define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
69 #define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur"
70 #define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
71 #define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
72 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign"
73 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
74 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
75 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
76 #define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
77 #define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
78 #define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
79 #define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
80 #define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
81 #define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
82 #define SKDEBUGCANVAS_ATTRIBUTE_DATA "data"
83 #define SKDEBUGCANVAS_ATTRIBUTE_VALUES "values"
84 #define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
85 #define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
86 #define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
87 #define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
88 #define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
89 #define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
90 #define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
91 #define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
92 #define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
93 #define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
94 #define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
95 #define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
96 #define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
97 #define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
98 #define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
99 #define SKDEBUGCANVAS_ATTRIBUTE_X "x"
100 #define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
101 #define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
102 #define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
103 #define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
104 #define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
105 #define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
106 #define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
107 #define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors"
108 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
109 #define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
110 #define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
111 #define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
112 #define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
113 #define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
114 #define SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
115 #define SKDEBUGCANVAS_ATTRIBUTE_WIDTH "width"
116 #define SKDEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
117 #define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
118 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
119 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
120 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
121 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
122 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
123 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
124
125 #define SKDEBUGCANVAS_VERB_MOVE "move"
126 #define SKDEBUGCANVAS_VERB_LINE "line"
127 #define SKDEBUGCANVAS_VERB_QUAD "quad"
128 #define SKDEBUGCANVAS_VERB_CUBIC "cubic"
129 #define SKDEBUGCANVAS_VERB_CONIC "conic"
130 #define SKDEBUGCANVAS_VERB_CLOSE "close"
131
132 #define SKDEBUGCANVAS_STYLE_FILL "fill"
133 #define SKDEBUGCANVAS_STYLE_STROKE "stroke"
134 #define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
135
136 #define SKDEBUGCANVAS_POINTMODE_POINTS "points"
137 #define SKDEBUGCANVAS_POINTMODE_LINES "lines"
138 #define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
139
140 #define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
141 #define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
142 #define SKDEBUGCANVAS_REGIONOP_UNION "union"
143 #define SKDEBUGCANVAS_REGIONOP_XOR "xor"
144 #define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
145 #define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
146
147 #define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
148 #define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
149 #define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
150 #define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
151
152 #define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
153 #define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
154
155 #define SKDEBUGCANVAS_ALIGN_LEFT "left"
156 #define SKDEBUGCANVAS_ALIGN_CENTER "center"
157 #define SKDEBUGCANVAS_ALIGN_RIGHT "right"
158
159 #define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
160 #define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
161 #define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
162 #define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
163
164 #define SKDEBUGCANVAS_CAP_BUTT "butt"
165 #define SKDEBUGCANVAS_CAP_ROUND "round"
166 #define SKDEBUGCANVAS_CAP_SQUARE "square"
167
168 #define SKDEBUGCANVAS_MITER_JOIN "miter"
169 #define SKDEBUGCANVAS_ROUND_JOIN "round"
170 #define SKDEBUGCANVAS_BEVEL_JOIN "bevel"
171
172 #define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
173 #define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
174 #define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
175 #define SKDEBUGCANVAS_COLORTYPE_565 "565"
176 #define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
177 #define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
178 #define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
179
180 #define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
181 #define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
182 #define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
183 #define SKDEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
184
185 #define SKDEBUGCANVAS_FILTERQUALITY_NONE "none"
186 #define SKDEBUGCANVAS_FILTERQUALITY_LOW "low"
187 #define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
188 #define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high"
189
190 #define SKDEBUGCANVAS_HINTING_NONE "none"
191 #define SKDEBUGCANVAS_HINTING_SLIGHT "slight"
192 #define SKDEBUGCANVAS_HINTING_NORMAL "normal"
193 #define SKDEBUGCANVAS_HINTING_FULL "full"
194
195 typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&);
196
str_append(SkString * str,const SkRect & r)197 static SkString* str_append(SkString* str, const SkRect& r) {
198 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
199 return str;
200 }
201
202 // TODO(chudy): Refactor into non subclass model.
203
SkDrawCommand(OpType type)204 SkDrawCommand::SkDrawCommand(OpType type)
205 : fOpType(type)
206 , fVisible(true) {
207 }
208
~SkDrawCommand()209 SkDrawCommand::~SkDrawCommand() {
210 fInfo.deleteAll();
211 }
212
GetCommandString(OpType type)213 const char* SkDrawCommand::GetCommandString(OpType type) {
214 switch (type) {
215 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
216 case kClipPath_OpType: return "ClipPath";
217 case kClipRegion_OpType: return "ClipRegion";
218 case kClipRect_OpType: return "ClipRect";
219 case kClipRRect_OpType: return "ClipRRect";
220 case kConcat_OpType: return "Concat";
221 case kDrawAnnotation_OpType: return "DrawAnnotation";
222 case kDrawBitmap_OpType: return "DrawBitmap";
223 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
224 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
225 case kDrawClear_OpType: return "DrawClear";
226 case kDrawDRRect_OpType: return "DrawDRRect";
227 case kDrawImage_OpType: return "DrawImage";
228 case kDrawImageLattice_OpType: return "DrawImageLattice";
229 case kDrawImageRect_OpType: return "DrawImageRect";
230 case kDrawOval_OpType: return "DrawOval";
231 case kDrawPaint_OpType: return "DrawPaint";
232 case kDrawPatch_OpType: return "DrawPatch";
233 case kDrawPath_OpType: return "DrawPath";
234 case kDrawPoints_OpType: return "DrawPoints";
235 case kDrawPosText_OpType: return "DrawPosText";
236 case kDrawPosTextH_OpType: return "DrawPosTextH";
237 case kDrawRect_OpType: return "DrawRect";
238 case kDrawRRect_OpType: return "DrawRRect";
239 case kDrawText_OpType: return "DrawText";
240 case kDrawTextBlob_OpType: return "DrawTextBlob";
241 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
242 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
243 case kDrawVertices_OpType: return "DrawVertices";
244 case kEndDrawPicture_OpType: return "EndDrawPicture";
245 case kRestore_OpType: return "Restore";
246 case kSave_OpType: return "Save";
247 case kSaveLayer_OpType: return "SaveLayer";
248 case kSetMatrix_OpType: return "SetMatrix";
249 default:
250 SkDebugf("OpType error 0x%08x\n", type);
251 SkASSERT(0);
252 break;
253 }
254 SkDEBUGFAIL("DrawType UNUSED\n");
255 return nullptr;
256 }
257
toString() const258 SkString SkDrawCommand::toString() const {
259 return SkString(GetCommandString(fOpType));
260 }
261
toJSON(UrlDataManager & urlDataManager) const262 Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
263 Json::Value result;
264 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
265 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
266 return result;
267 }
268
269 #define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
270 (FROM_JSON) Sk ## name ## Command::fromJSON)
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)271 SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
272 static SkTHashMap<SkString, FROM_JSON> factories;
273 static bool initialized = false;
274 if (!initialized) {
275 initialized = true;
276 INSTALL_FACTORY(Restore);
277 INSTALL_FACTORY(ClipPath);
278 INSTALL_FACTORY(ClipRegion);
279 INSTALL_FACTORY(ClipRect);
280 INSTALL_FACTORY(ClipRRect);
281 INSTALL_FACTORY(Concat);
282 INSTALL_FACTORY(DrawAnnotation);
283 INSTALL_FACTORY(DrawBitmap);
284 INSTALL_FACTORY(DrawBitmapRect);
285 INSTALL_FACTORY(DrawBitmapNine);
286 INSTALL_FACTORY(DrawImage);
287 INSTALL_FACTORY(DrawImageRect);
288 INSTALL_FACTORY(DrawOval);
289 INSTALL_FACTORY(DrawPaint);
290 INSTALL_FACTORY(DrawPath);
291 INSTALL_FACTORY(DrawPoints);
292 INSTALL_FACTORY(DrawText);
293 INSTALL_FACTORY(DrawPosText);
294 INSTALL_FACTORY(DrawPosTextH);
295 INSTALL_FACTORY(DrawTextOnPath);
296 INSTALL_FACTORY(DrawTextRSXform);
297 INSTALL_FACTORY(DrawTextBlob);
298
299 INSTALL_FACTORY(DrawRect);
300 INSTALL_FACTORY(DrawRRect);
301 INSTALL_FACTORY(DrawDRRect);
302 INSTALL_FACTORY(DrawPatch);
303 INSTALL_FACTORY(Save);
304 INSTALL_FACTORY(SaveLayer);
305 INSTALL_FACTORY(SetMatrix);
306 }
307 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
308 FROM_JSON* factory = factories.find(name);
309 if (factory == nullptr) {
310 SkDebugf("no JSON factory for '%s'\n", name.c_str());
311 return nullptr;
312 }
313 return (*factory)(command, urlDataManager);
314 }
315
316 namespace {
317
xlate_and_scale_to_bounds(SkCanvas * canvas,const SkRect & bounds)318 void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
319 const SkISize& size = canvas->getBaseLayerSize();
320
321 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
322
323 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
324 if (bounds.width() > bounds.height()) {
325 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
326 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
327 } else {
328 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
329 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
330 }
331 canvas->translate(-bounds.centerX(), -bounds.centerY());
332 }
333
334
render_path(SkCanvas * canvas,const SkPath & path)335 void render_path(SkCanvas* canvas, const SkPath& path) {
336 canvas->clear(0xFFFFFFFF);
337
338 const SkRect& bounds = path.getBounds();
339 if (bounds.isEmpty()) {
340 return;
341 }
342
343 SkAutoCanvasRestore acr(canvas, true);
344 xlate_and_scale_to_bounds(canvas, bounds);
345
346 SkPaint p;
347 p.setColor(SK_ColorBLACK);
348 p.setStyle(SkPaint::kStroke_Style);
349
350 canvas->drawPath(path, p);
351 }
352
render_bitmap(SkCanvas * canvas,const SkBitmap & input,const SkRect * srcRect=nullptr)353 void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
354 const SkISize& size = canvas->getBaseLayerSize();
355
356 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
357 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
358
359 if (input.width() > input.height()) {
360 yScale *= input.height() / (float) input.width();
361 } else {
362 xScale *= input.width() / (float) input.height();
363 }
364
365 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
366 xScale * input.width(),
367 yScale * input.height());
368
369 static const int kNumBlocks = 8;
370
371 canvas->clear(0xFFFFFFFF);
372 SkISize block = {
373 canvas->imageInfo().width()/kNumBlocks,
374 canvas->imageInfo().height()/kNumBlocks
375 };
376 for (int y = 0; y < kNumBlocks; ++y) {
377 for (int x = 0; x < kNumBlocks; ++x) {
378 SkPaint paint;
379 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
380 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
381 SkIntToScalar(y*block.height()),
382 SkIntToScalar(block.width()),
383 SkIntToScalar(block.height()));
384 canvas->drawRect(r, paint);
385 }
386 }
387
388 canvas->drawBitmapRect(input, dst, nullptr);
389
390 if (srcRect) {
391 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
392 srcRect->fTop * yScale + SK_Scalar1,
393 srcRect->fRight * xScale + SK_Scalar1,
394 srcRect->fBottom * yScale + SK_Scalar1);
395 SkPaint p;
396 p.setColor(SK_ColorRED);
397 p.setStyle(SkPaint::kStroke_Style);
398
399 canvas->drawRect(r, p);
400 }
401 }
402
render_rrect(SkCanvas * canvas,const SkRRect & rrect)403 void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
404 canvas->clear(0xFFFFFFFF);
405 canvas->save();
406
407 const SkRect& bounds = rrect.getBounds();
408
409 xlate_and_scale_to_bounds(canvas, bounds);
410
411 SkPaint p;
412 p.setColor(SK_ColorBLACK);
413 p.setStyle(SkPaint::kStroke_Style);
414
415 canvas->drawRRect(rrect, p);
416 canvas->restore();
417 }
418
render_drrect(SkCanvas * canvas,const SkRRect & outer,const SkRRect & inner)419 void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
420 canvas->clear(0xFFFFFFFF);
421 canvas->save();
422
423 const SkRect& bounds = outer.getBounds();
424
425 xlate_and_scale_to_bounds(canvas, bounds);
426
427 SkPaint p;
428 p.setColor(SK_ColorBLACK);
429 p.setStyle(SkPaint::kStroke_Style);
430
431 canvas->drawDRRect(outer, inner, p);
432 canvas->restore();
433 }
434
435 static const char* const gBlendModeMap[] = {
436 "clear",
437 "src",
438 "dst",
439 "srcOver",
440 "dstOver",
441 "srcIn",
442 "dstIn",
443 "srcOut",
444 "dstOut",
445 "srcATop",
446 "dstATop",
447 "xor",
448 "plus",
449 "modulate",
450
451 "screen",
452
453 "overlay",
454 "darken",
455 "lighten",
456 "colorDodge",
457 "colorBurn",
458 "hardLight",
459 "softLight",
460 "difference",
461 "exclusion",
462 "multiply",
463
464 "hue",
465 "saturation",
466 "color",
467 "luminosity",
468 };
469
470 static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
471 "blendMode mismatch");
472 static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
473 "blendMode mismatch");
474
apply_paint_blend_mode(const SkPaint & paint,Json::Value * target)475 void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
476 const auto mode = paint.getBlendMode();
477 if (mode != SkBlendMode::kSrcOver) {
478 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
479 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
480 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
481 }
482 }
483
extract_json_paint_blend_mode(Json::Value & jsonPaint,SkPaint * target)484 void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
485 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
486 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
487
488 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
489 if (!strcmp(mode, gBlendModeMap[i])) {
490 target->setBlendMode(static_cast<SkBlendMode>(i));
491 break;
492 }
493 }
494 }
495 }
496
497 };
498
MakeJsonColor(const SkColor color)499 Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
500 Json::Value result(Json::arrayValue);
501 result.append(Json::Value(SkColorGetA(color)));
502 result.append(Json::Value(SkColorGetR(color)));
503 result.append(Json::Value(SkColorGetG(color)));
504 result.append(Json::Value(SkColorGetB(color)));
505 return result;
506 }
507
MakeJsonColor4f(const SkColor4f & color)508 Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
509 Json::Value result(Json::arrayValue);
510 result.append(Json::Value(color.fA));
511 result.append(Json::Value(color.fR));
512 result.append(Json::Value(color.fG));
513 result.append(Json::Value(color.fB));
514 return result;
515 }
516
MakeJsonPoint(const SkPoint & point)517 Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
518 Json::Value result(Json::arrayValue);
519 result.append(Json::Value(point.x()));
520 result.append(Json::Value(point.y()));
521 return result;
522 }
523
MakeJsonPoint(SkScalar x,SkScalar y)524 Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
525 Json::Value result(Json::arrayValue);
526 result.append(Json::Value(x));
527 result.append(Json::Value(y));
528 return result;
529 }
530
MakeJsonRect(const SkRect & rect)531 Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
532 Json::Value result(Json::arrayValue);
533 result.append(Json::Value(rect.left()));
534 result.append(Json::Value(rect.top()));
535 result.append(Json::Value(rect.right()));
536 result.append(Json::Value(rect.bottom()));
537 return result;
538 }
539
MakeJsonIRect(const SkIRect & rect)540 Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
541 Json::Value result(Json::arrayValue);
542 result.append(Json::Value(rect.left()));
543 result.append(Json::Value(rect.top()));
544 result.append(Json::Value(rect.right()));
545 result.append(Json::Value(rect.bottom()));
546 return result;
547 }
548
make_json_rrect(const SkRRect & rrect)549 static Json::Value make_json_rrect(const SkRRect& rrect) {
550 Json::Value result(Json::arrayValue);
551 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
552 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
553 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
554 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
555 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
556 return result;
557 }
558
MakeJsonMatrix(const SkMatrix & matrix)559 Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
560 Json::Value result(Json::arrayValue);
561 Json::Value row1(Json::arrayValue);
562 row1.append(Json::Value(matrix[0]));
563 row1.append(Json::Value(matrix[1]));
564 row1.append(Json::Value(matrix[2]));
565 result.append(row1);
566 Json::Value row2(Json::arrayValue);
567 row2.append(Json::Value(matrix[3]));
568 row2.append(Json::Value(matrix[4]));
569 row2.append(Json::Value(matrix[5]));
570 result.append(row2);
571 Json::Value row3(Json::arrayValue);
572 row3.append(Json::Value(matrix[6]));
573 row3.append(Json::Value(matrix[7]));
574 row3.append(Json::Value(matrix[8]));
575 result.append(row3);
576 return result;
577 }
578
MakeJsonScalar(SkScalar z)579 Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
580 Json::Value result(z);
581 return result;
582 }
583
MakeJsonPath(const SkPath & path)584 Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
585 Json::Value result(Json::objectValue);
586 switch (path.getFillType()) {
587 case SkPath::kWinding_FillType:
588 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
589 break;
590 case SkPath::kEvenOdd_FillType:
591 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
592 break;
593 case SkPath::kInverseWinding_FillType:
594 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
595 break;
596 case SkPath::kInverseEvenOdd_FillType:
597 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
598 break;
599 }
600 Json::Value verbs(Json::arrayValue);
601 SkPath::Iter iter(path, false);
602 SkPoint pts[4];
603 SkPath::Verb verb;
604 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
605 switch (verb) {
606 case SkPath::kLine_Verb: {
607 Json::Value line(Json::objectValue);
608 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
609 verbs.append(line);
610 break;
611 }
612 case SkPath::kQuad_Verb: {
613 Json::Value quad(Json::objectValue);
614 Json::Value coords(Json::arrayValue);
615 coords.append(MakeJsonPoint(pts[1]));
616 coords.append(MakeJsonPoint(pts[2]));
617 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
618 verbs.append(quad);
619 break;
620 }
621 case SkPath::kCubic_Verb: {
622 Json::Value cubic(Json::objectValue);
623 Json::Value coords(Json::arrayValue);
624 coords.append(MakeJsonPoint(pts[1]));
625 coords.append(MakeJsonPoint(pts[2]));
626 coords.append(MakeJsonPoint(pts[3]));
627 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
628 verbs.append(cubic);
629 break;
630 }
631 case SkPath::kConic_Verb: {
632 Json::Value conic(Json::objectValue);
633 Json::Value coords(Json::arrayValue);
634 coords.append(MakeJsonPoint(pts[1]));
635 coords.append(MakeJsonPoint(pts[2]));
636 coords.append(Json::Value(iter.conicWeight()));
637 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
638 verbs.append(conic);
639 break;
640 }
641 case SkPath::kMove_Verb: {
642 Json::Value move(Json::objectValue);
643 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
644 verbs.append(move);
645 break;
646 }
647 case SkPath::kClose_Verb:
648 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
649 break;
650 case SkPath::kDone_Verb:
651 break;
652 }
653 }
654 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
655 return result;
656 }
657
MakeJsonRegion(const SkRegion & region)658 Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
659 return Json::Value("<unimplemented>");
660 }
661
make_json_regionop(SkClipOp op)662 static Json::Value make_json_regionop(SkClipOp op) {
663 switch (op) {
664 case kDifference_SkClipOp:
665 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
666 case kIntersect_SkClipOp:
667 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
668 case kUnion_SkClipOp:
669 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
670 case kXOR_SkClipOp:
671 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
672 case kReverseDifference_SkClipOp:
673 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
674 case kReplace_SkClipOp:
675 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
676 default:
677 SkASSERT(false);
678 return Json::Value("<invalid region op>");
679 };
680 }
681
make_json_pointmode(SkCanvas::PointMode mode)682 static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
683 switch (mode) {
684 case SkCanvas::kPoints_PointMode:
685 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
686 case SkCanvas::kLines_PointMode:
687 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
688 case SkCanvas::kPolygon_PointMode:
689 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
690 default:
691 SkASSERT(false);
692 return Json::Value("<invalid point mode>");
693 };
694 }
695
store_scalar(Json::Value * target,const char * key,SkScalar value,SkScalar defaultValue)696 static void store_scalar(Json::Value* target, const char* key, SkScalar value,
697 SkScalar defaultValue) {
698 if (value != defaultValue) {
699 (*target)[key] = Json::Value(value);
700 }
701 }
702
store_bool(Json::Value * target,const char * key,bool value,bool defaultValue)703 static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
704 if (value != defaultValue) {
705 (*target)[key] = Json::Value(value);
706 }
707 }
708
encode_data(const void * bytes,size_t count,const char * contentType,UrlDataManager & urlDataManager,Json::Value * target)709 static void encode_data(const void* bytes, size_t count, const char* contentType,
710 UrlDataManager& urlDataManager, Json::Value* target) {
711 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
712 SkString url = urlDataManager.addData(data.get(), contentType);
713 *target = Json::Value(url.c_str());
714 }
715
flatten(const SkFlattenable * flattenable,Json::Value * target,UrlDataManager & urlDataManager)716 void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
717 UrlDataManager& urlDataManager) {
718 SkBinaryWriteBuffer buffer;
719 flattenable->flatten(buffer);
720 void* data = sk_malloc_throw(buffer.bytesWritten());
721 buffer.writeToMemory(data);
722 Json::Value jsonData;
723 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
724 Json::Value jsonFlattenable;
725 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
726 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
727
728 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
729 flattenable->flatten(jsonBuffer);
730 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
731
732 (*target) = jsonFlattenable;
733 sk_free(data);
734 }
735
write_png_callback(png_structp png_ptr,png_bytep data,png_size_t length)736 static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
737 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
738 out->write(data, length);
739 }
740
WritePNG(const uint8_t * rgba,unsigned width,unsigned height,SkWStream & out,bool isOpaque)741 void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
742 SkWStream& out, bool isOpaque) {
743 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
744 SkASSERT(png != nullptr);
745 png_infop info_ptr = png_create_info_struct(png);
746 SkASSERT(info_ptr != nullptr);
747 if (setjmp(png_jmpbuf(png))) {
748 SkFAIL("png encode error");
749 }
750 png_set_write_fn(png, &out, write_png_callback, NULL);
751 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
752 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
753 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
754 png_set_compression_level(png, 1);
755 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
756 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
757 for (png_size_t y = 0; y < height; ++y) {
758 const uint8_t* src = rgba + y * width * 4;
759 rows[y] = pixels + y * width * 4;
760 for (png_size_t x = 0; x < width; ++x) {
761 rows[y][x * 4] = src[x * 4];
762 rows[y][x * 4 + 1] = src[x * 4 + 1];
763 rows[y][x * 4 + 2] = src[x * 4 + 2];
764 rows[y][x * 4 + 3] = src[x * 4 + 3];
765 }
766 }
767 png_write_info(png, info_ptr);
768 if (isOpaque) {
769 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
770 }
771 png_set_filter(png, 0, PNG_NO_FILTERS);
772 png_write_image(png, &rows[0]);
773 png_destroy_write_struct(&png, NULL);
774 sk_free(rows);
775 sk_free(pixels);
776 }
777
flatten(const SkImage & image,Json::Value * target,UrlDataManager & urlDataManager)778 bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
779 UrlDataManager& urlDataManager) {
780 size_t rowBytes = 4 * image.width();
781 SkAutoMalloc buffer(rowBytes * image.height());
782 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
783 kN32_SkColorType, kPremul_SkAlphaType);
784 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
785 SkDebugf("readPixels failed\n");
786 return false;
787 }
788
789 SkBitmap bm;
790 bm.installPixels(dstInfo, buffer.get(), rowBytes);
791 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
792
793 SkDynamicMemoryWStream out;
794 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
795 out, false);
796 sk_sp<SkData> encoded = out.detachAsData();
797 Json::Value jsonData;
798 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
799 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
800 return true;
801 }
802
color_type_name(SkColorType colorType)803 static const char* color_type_name(SkColorType colorType) {
804 switch (colorType) {
805 case kARGB_4444_SkColorType:
806 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
807 case kRGBA_8888_SkColorType:
808 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
809 case kBGRA_8888_SkColorType:
810 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
811 case kRGB_565_SkColorType:
812 return SKDEBUGCANVAS_COLORTYPE_565;
813 case kGray_8_SkColorType:
814 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
815 case kAlpha_8_SkColorType:
816 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
817 default:
818 SkASSERT(false);
819 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
820 }
821 }
822
alpha_type_name(SkAlphaType alphaType)823 static const char* alpha_type_name(SkAlphaType alphaType) {
824 switch (alphaType) {
825 case kOpaque_SkAlphaType:
826 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
827 case kPremul_SkAlphaType:
828 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
829 case kUnpremul_SkAlphaType:
830 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
831 default:
832 SkASSERT(false);
833 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
834 }
835 }
836
decode_data(Json::Value data,UrlDataManager & urlDataManager,const void ** target)837 static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
838 const void** target) {
839 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
840 if (urlData == nullptr) {
841 SkASSERT(false);
842 *target = nullptr;
843 return 0;
844 }
845 *target = urlData->fData->data();
846 // cast should be safe for any reasonably-sized object...
847 return (Json::ArrayIndex) urlData->fData->size();
848 }
849
load_flattenable(Json::Value jsonFlattenable,UrlDataManager & urlDataManager)850 static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
851 UrlDataManager& urlDataManager) {
852 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
853 return nullptr;
854 }
855 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
856 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
857 if (factory == nullptr) {
858 SkDebugf("no factory for loading '%s'\n", name);
859 return nullptr;
860 }
861 const void* data;
862 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
863 SkValidatingReadBuffer buffer(data, size);
864 sk_sp<SkFlattenable> result = factory(buffer);
865 if (!buffer.isValid()) {
866 SkDebugf("invalid buffer loading flattenable\n");
867 return nullptr;
868 }
869 return result.release();
870 }
871
colortype_from_name(const char * name)872 static SkColorType colortype_from_name(const char* name) {
873 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
874 return kARGB_4444_SkColorType;
875 }
876 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
877 return kRGBA_8888_SkColorType;
878 }
879 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
880 return kBGRA_8888_SkColorType;
881 }
882 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
883 return kRGB_565_SkColorType;
884 }
885 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
886 return kGray_8_SkColorType;
887 }
888 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
889 return kAlpha_8_SkColorType;
890 }
891 SkASSERT(false);
892 return kN32_SkColorType;
893 }
894
convert_colortype(SkBitmap * bitmap,SkColorType colorType)895 static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
896 if (bitmap->colorType() == colorType ) {
897 return bitmap;
898 }
899 SkBitmap* dst = new SkBitmap();
900 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
901 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
902 {
903 delete bitmap;
904 return dst;
905 }
906 SkASSERT(false);
907 delete dst;
908 return bitmap;
909 }
910
911 // caller is responsible for freeing return value
load_bitmap(const Json::Value & jsonBitmap,UrlDataManager & urlDataManager)912 static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
913 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
914 SkDebugf("invalid bitmap\n");
915 return nullptr;
916 }
917 const void* data;
918 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
919 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
920 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
921
922 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
923 if (nullptr != image) {
924 if (!image->asLegacyBitmap(bitmap.get(), SkImage::kRW_LegacyBitmapMode)) {
925 SkDebugf("image decode failed\n");
926 return nullptr;
927 }
928
929 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
930 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
931 SkColorType ct = colortype_from_name(ctName);
932 bitmap.reset(convert_colortype(bitmap.release(), ct));
933 }
934 return bitmap.release();
935 }
936 SkDebugf("image decode failed\n");
937 return nullptr;
938 }
939
load_image(const Json::Value & jsonImage,UrlDataManager & urlDataManager)940 static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
941 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
942 if (bitmap == nullptr) {
943 return nullptr;
944 }
945 auto result = SkImage::MakeFromBitmap(*bitmap);
946 delete bitmap;
947 return result;
948 }
949
flatten(const SkBitmap & bitmap,Json::Value * target,UrlDataManager & urlDataManager)950 bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
951 UrlDataManager& urlDataManager) {
952 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
953 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
954 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
955 bool success = flatten(*image, target, urlDataManager);
956 return success;
957 }
958
apply_paint_hinting(const SkPaint & paint,Json::Value * target)959 static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
960 SkPaint::Hinting hinting = paint.getHinting();
961 if (hinting != SkPaintDefaults_Hinting) {
962 switch (hinting) {
963 case SkPaint::kNo_Hinting:
964 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
965 break;
966 case SkPaint::kSlight_Hinting:
967 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
968 break;
969 case SkPaint::kNormal_Hinting:
970 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
971 break;
972 case SkPaint::kFull_Hinting:
973 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
974 break;
975 }
976 }
977 }
978
apply_paint_color(const SkPaint & paint,Json::Value * target)979 static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
980 SkColor color = paint.getColor();
981 if (color != SK_ColorBLACK) {
982 Json::Value colorValue(Json::arrayValue);
983 colorValue.append(Json::Value(SkColorGetA(color)));
984 colorValue.append(Json::Value(SkColorGetR(color)));
985 colorValue.append(Json::Value(SkColorGetG(color)));
986 colorValue.append(Json::Value(SkColorGetB(color)));
987 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
988 }
989 }
990
apply_paint_style(const SkPaint & paint,Json::Value * target)991 static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
992 SkPaint::Style style = paint.getStyle();
993 if (style != SkPaint::kFill_Style) {
994 switch (style) {
995 case SkPaint::kStroke_Style: {
996 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
997 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
998 break;
999 }
1000 case SkPaint::kStrokeAndFill_Style: {
1001 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1002 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1003 break;
1004 }
1005 default: SkASSERT(false);
1006 }
1007 }
1008 }
1009
apply_paint_cap(const SkPaint & paint,Json::Value * target)1010 static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1011 SkPaint::Cap cap = paint.getStrokeCap();
1012 if (cap != SkPaint::kDefault_Cap) {
1013 switch (cap) {
1014 case SkPaint::kButt_Cap:
1015 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1016 break;
1017 case SkPaint::kRound_Cap:
1018 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1019 break;
1020 case SkPaint::kSquare_Cap:
1021 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1022 break;
1023 default: SkASSERT(false);
1024 }
1025 }
1026 }
1027
apply_paint_join(const SkPaint & paint,Json::Value * target)1028 static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1029 SkPaint::Join join = paint.getStrokeJoin();
1030 if (join != SkPaint::kDefault_Join) {
1031 switch (join) {
1032 case SkPaint::kMiter_Join:
1033 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1034 SKDEBUGCANVAS_MITER_JOIN);
1035 break;
1036 case SkPaint::kRound_Join:
1037 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1038 SKDEBUGCANVAS_ROUND_JOIN);
1039 break;
1040 case SkPaint::kBevel_Join:
1041 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1042 SKDEBUGCANVAS_BEVEL_JOIN);
1043 break;
1044 default: SkASSERT(false);
1045 }
1046 }
1047 }
1048
apply_paint_filterquality(const SkPaint & paint,Json::Value * target)1049 static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1050 SkFilterQuality quality = paint.getFilterQuality();
1051 switch (quality) {
1052 case kNone_SkFilterQuality:
1053 break;
1054 case kLow_SkFilterQuality:
1055 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1056 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1057 break;
1058 case kMedium_SkFilterQuality:
1059 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1060 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1061 break;
1062 case kHigh_SkFilterQuality:
1063 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1064 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1065 break;
1066 }
1067 }
1068
apply_paint_maskfilter(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1069 static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
1070 UrlDataManager& urlDataManager) {
1071 SkMaskFilter* maskFilter = paint.getMaskFilter();
1072 if (maskFilter != nullptr) {
1073 SkMaskFilter::BlurRec blurRec;
1074 if (maskFilter->asABlur(&blurRec)) {
1075 Json::Value blur(Json::objectValue);
1076 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1077 switch (blurRec.fStyle) {
1078 case SkBlurStyle::kNormal_SkBlurStyle:
1079 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1080 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
1081 break;
1082 case SkBlurStyle::kSolid_SkBlurStyle:
1083 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1084 SKDEBUGCANVAS_BLURSTYLE_SOLID);
1085 break;
1086 case SkBlurStyle::kOuter_SkBlurStyle:
1087 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1088 SKDEBUGCANVAS_BLURSTYLE_OUTER);
1089 break;
1090 case SkBlurStyle::kInner_SkBlurStyle:
1091 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1092 SKDEBUGCANVAS_BLURSTYLE_INNER);
1093 break;
1094 default:
1095 SkASSERT(false);
1096 }
1097 switch (blurRec.fQuality) {
1098 case SkBlurQuality::kLow_SkBlurQuality:
1099 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
1100 SKDEBUGCANVAS_BLURQUALITY_LOW);
1101 break;
1102 case SkBlurQuality::kHigh_SkBlurQuality:
1103 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
1104 SKDEBUGCANVAS_BLURQUALITY_HIGH);
1105 break;
1106 default:
1107 SkASSERT(false);
1108 }
1109 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1110 } else {
1111 Json::Value jsonMaskFilter;
1112 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
1113 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1114 }
1115 }
1116 }
1117
apply_paint_patheffect(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1118 static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
1119 UrlDataManager& urlDataManager) {
1120 SkPathEffect* pathEffect = paint.getPathEffect();
1121 if (pathEffect != nullptr) {
1122 SkPathEffect::DashInfo dashInfo;
1123 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1124 if (dashType == SkPathEffect::kDash_DashType) {
1125 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1126 pathEffect->asADash(&dashInfo);
1127 Json::Value dashing(Json::objectValue);
1128 Json::Value intervals(Json::arrayValue);
1129 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1130 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1131 }
1132 sk_free(dashInfo.fIntervals);
1133 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1134 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1135 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1136 } else {
1137 Json::Value jsonPathEffect;
1138 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
1139 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1140 }
1141 }
1142 }
1143
apply_paint_textalign(const SkPaint & paint,Json::Value * target)1144 static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1145 SkPaint::Align textAlign = paint.getTextAlign();
1146 if (textAlign != SkPaint::kLeft_Align) {
1147 switch (textAlign) {
1148 case SkPaint::kCenter_Align: {
1149 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1150 break;
1151 }
1152 case SkPaint::kRight_Align: {
1153 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1154 break;
1155 }
1156 default: SkASSERT(false);
1157 }
1158 }
1159 }
1160
apply_paint_typeface(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1161 static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
1162 UrlDataManager& urlDataManager) {
1163 SkTypeface* typeface = paint.getTypeface();
1164 if (typeface != nullptr) {
1165 Json::Value jsonTypeface;
1166 SkDynamicMemoryWStream buffer;
1167 typeface->serialize(&buffer);
1168 void* data = sk_malloc_throw(buffer.bytesWritten());
1169 buffer.copyTo(data);
1170 Json::Value jsonData;
1171 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
1172 &jsonData);
1173 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1174 sk_free(data);
1175 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
1176 }
1177 }
1178
apply_paint_shader(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1179 static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
1180 UrlDataManager& urlDataManager) {
1181 SkFlattenable* shader = paint.getShader();
1182 if (shader != nullptr) {
1183 Json::Value jsonShader;
1184 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
1185 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1186 }
1187 }
1188
apply_paint_imagefilter(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1189 static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1190 UrlDataManager& urlDataManager) {
1191 SkFlattenable* imageFilter = paint.getImageFilter();
1192 if (imageFilter != nullptr) {
1193 Json::Value jsonImageFilter;
1194 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
1195 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1196 }
1197 }
1198
apply_paint_colorfilter(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1199 static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
1200 UrlDataManager& urlDataManager) {
1201 SkFlattenable* colorFilter = paint.getColorFilter();
1202 if (colorFilter != nullptr) {
1203 Json::Value jsonColorFilter;
1204 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
1205 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1206 }
1207 }
1208
apply_paint_looper(const SkPaint & paint,Json::Value * target,UrlDataManager & urlDataManager)1209 static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
1210 UrlDataManager& urlDataManager) {
1211 SkFlattenable* looper = paint.getLooper();
1212 if (looper != nullptr) {
1213 Json::Value jsonLooper;
1214 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
1215 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1216 }
1217 }
1218
MakeJsonPaint(const SkPaint & paint,UrlDataManager & urlDataManager)1219 Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
1220 Json::Value result(Json::objectValue);
1221 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
1222 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
1223 SkPaintDefaults_MiterLimit);
1224 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
1225 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
1226 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1227 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1228 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
1229 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT, paint.isDevKernText(), false);
1230 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1231 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1232 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1233 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1234 //kGenA8FromLCD_Flag
1235
1236 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
1237 SkPaintDefaults_TextSize);
1238 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1239 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
1240 apply_paint_hinting(paint, &result);
1241 apply_paint_color(paint, &result);
1242 apply_paint_style(paint, &result);
1243 apply_paint_blend_mode(paint, &result);
1244 apply_paint_cap(paint, &result);
1245 apply_paint_join(paint, &result);
1246 apply_paint_filterquality(paint, &result);
1247 apply_paint_textalign(paint, &result);
1248 apply_paint_patheffect(paint, &result, urlDataManager);
1249 apply_paint_maskfilter(paint, &result, urlDataManager);
1250 apply_paint_shader(paint, &result, urlDataManager);
1251 apply_paint_looper(paint, &result, urlDataManager);
1252 apply_paint_imagefilter(paint, &result, urlDataManager);
1253 apply_paint_colorfilter(paint, &result, urlDataManager);
1254 apply_paint_typeface(paint, &result, urlDataManager);
1255 return result;
1256 }
1257
MakeJsonLattice(const SkCanvas::Lattice & lattice)1258 Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1259 Json::Value result(Json::objectValue);
1260 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1261 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1262 if (nullptr != lattice.fBounds) {
1263 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1264 }
1265 Json::Value XDivs(Json::arrayValue);
1266 for (int i = 0; i < lattice.fXCount; i++) {
1267 XDivs.append(Json::Value(lattice.fXDivs[i]));
1268 }
1269 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1270 Json::Value YDivs(Json::arrayValue);
1271 for (int i = 0; i < lattice.fYCount; i++) {
1272 YDivs.append(Json::Value(lattice.fYDivs[i]));
1273 }
1274 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
1275 if (nullptr != lattice.fFlags) {
1276 Json::Value flags(Json::arrayValue);
1277 int flagCount = 0;
1278 for (int row = 0; row < lattice.fYCount+1; row++) {
1279 Json::Value flagsRow(Json::arrayValue);
1280 for (int column = 0; column < lattice.fXCount+1; column++) {
1281 flagsRow.append(Json::Value(lattice.fFlags[flagCount++]));
1282 }
1283 flags.append(flagsRow);
1284 }
1285 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1286 }
1287 return result;
1288 }
1289
get_json_point(Json::Value point)1290 static SkPoint get_json_point(Json::Value point) {
1291 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1292 }
1293
get_json_color(Json::Value color)1294 static SkColor get_json_color(Json::Value color) {
1295 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1296 }
1297
extract_json_paint_color(Json::Value & jsonPaint,SkPaint * target)1298 static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1299 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
1300 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
1301 }
1302 }
1303
extract_json_paint_shader(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1304 static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1305 SkPaint* target) {
1306 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1307 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
1308 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
1309 if (shader != nullptr) {
1310 target->setShader(sk_ref_sp(shader));
1311 }
1312 }
1313 }
1314
extract_json_paint_patheffect(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1315 static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1316 SkPaint* target) {
1317 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1318 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
1319 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1320 urlDataManager));
1321 if (pathEffect != nullptr) {
1322 target->setPathEffect(pathEffect);
1323 }
1324 }
1325 }
1326
extract_json_paint_maskfilter(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1327 static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1328 SkPaint* target) {
1329 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1330 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
1331 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1332 urlDataManager));
1333 if (maskFilter) {
1334 target->setMaskFilter(std::move(maskFilter));
1335 }
1336 }
1337 }
1338
extract_json_paint_colorfilter(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1339 static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1340 SkPaint* target) {
1341 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1342 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
1343 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1344 urlDataManager));
1345 if (colorFilter != nullptr) {
1346 target->setColorFilter(colorFilter);
1347 }
1348 }
1349 }
1350
extract_json_paint_looper(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1351 static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1352 SkPaint* target) {
1353 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1354 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
1355 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
1356 if (looper != nullptr) {
1357 target->setLooper(std::move(looper));
1358 }
1359 }
1360 }
1361
extract_json_paint_imagefilter(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1362 static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1363 SkPaint* target) {
1364 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1365 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
1366 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1367 urlDataManager));
1368 if (imageFilter != nullptr) {
1369 target->setImageFilter(imageFilter);
1370 }
1371 }
1372 }
1373
extract_json_paint_typeface(Json::Value & jsonPaint,UrlDataManager & urlDataManager,SkPaint * target)1374 static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
1375 SkPaint* target) {
1376 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1377 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1378 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1379 const void* data;
1380 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1381 SkMemoryStream buffer(data, length);
1382 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
1383 }
1384 }
1385
extract_json_paint_hinting(Json::Value & jsonPaint,SkPaint * target)1386 static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1387 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1388 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1389 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1390 target->setHinting(SkPaint::kNo_Hinting);
1391 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1392 target->setHinting(SkPaint::kSlight_Hinting);
1393 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1394 target->setHinting(SkPaint::kNormal_Hinting);
1395 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1396 target->setHinting(SkPaint::kFull_Hinting);
1397 }
1398 }
1399 }
1400
extract_json_paint_style(Json::Value & jsonPaint,SkPaint * target)1401 static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1402 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1403 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1404 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1405 target->setStyle(SkPaint::kFill_Style);
1406 }
1407 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1408 target->setStyle(SkPaint::kStroke_Style);
1409 }
1410 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1411 target->setStyle(SkPaint::kStrokeAndFill_Style);
1412 }
1413 }
1414 }
1415
extract_json_paint_strokewidth(Json::Value & jsonPaint,SkPaint * target)1416 static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1417 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1418 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1419 target->setStrokeWidth(strokeWidth);
1420 }
1421 }
1422
extract_json_paint_strokemiter(Json::Value & jsonPaint,SkPaint * target)1423 static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1424 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1425 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1426 target->setStrokeMiter(strokeMiter);
1427 }
1428 }
1429
extract_json_paint_strokejoin(Json::Value & jsonPaint,SkPaint * target)1430 static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1431 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1432 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1433 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1434 target->setStrokeJoin(SkPaint::kMiter_Join);
1435 }
1436 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1437 target->setStrokeJoin(SkPaint::kRound_Join);
1438 }
1439 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1440 target->setStrokeJoin(SkPaint::kBevel_Join);
1441 }
1442 else {
1443 SkASSERT(false);
1444 }
1445 }
1446 }
1447
extract_json_paint_cap(Json::Value & jsonPaint,SkPaint * target)1448 static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1449 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1450 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1451 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1452 target->setStrokeCap(SkPaint::kButt_Cap);
1453 }
1454 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1455 target->setStrokeCap(SkPaint::kRound_Cap);
1456 }
1457 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1458 target->setStrokeCap(SkPaint::kSquare_Cap);
1459 }
1460 }
1461 }
1462
extract_json_paint_filterquality(Json::Value & jsonPaint,SkPaint * target)1463 static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1464 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1465 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1466 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1467 target->setFilterQuality(kNone_SkFilterQuality);
1468 }
1469 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1470 target->setFilterQuality(kLow_SkFilterQuality);
1471 }
1472 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1473 target->setFilterQuality(kMedium_SkFilterQuality);
1474 }
1475 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1476 target->setFilterQuality(kHigh_SkFilterQuality);
1477 }
1478 }
1479 }
1480
extract_json_paint_antialias(Json::Value & jsonPaint,SkPaint * target)1481 static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1482 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1483 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1484 }
1485 }
1486
extract_json_paint_dither(Json::Value & jsonPaint,SkPaint * target)1487 static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1488 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1489 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1490 }
1491 }
1492
extract_json_paint_fakeboldtext(Json::Value & jsonPaint,SkPaint * target)1493 static void extract_json_paint_fakeboldtext(Json::Value& jsonPaint, SkPaint* target) {
1494 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT)) {
1495 target->setFakeBoldText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT].asBool());
1496 }
1497 }
1498
extract_json_paint_lineartext(Json::Value & jsonPaint,SkPaint * target)1499 static void extract_json_paint_lineartext(Json::Value& jsonPaint, SkPaint* target) {
1500 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT)) {
1501 target->setLinearText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT].asBool());
1502 }
1503 }
1504
extract_json_paint_subpixeltext(Json::Value & jsonPaint,SkPaint * target)1505 static void extract_json_paint_subpixeltext(Json::Value& jsonPaint, SkPaint* target) {
1506 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT)) {
1507 target->setSubpixelText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT].asBool());
1508 }
1509 }
1510
extract_json_paint_devkerntext(Json::Value & jsonPaint,SkPaint * target)1511 static void extract_json_paint_devkerntext(Json::Value& jsonPaint, SkPaint* target) {
1512 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT)) {
1513 target->setDevKernText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT].asBool());
1514 }
1515 }
1516
extract_json_paint_lcdrendertext(Json::Value & jsonPaint,SkPaint * target)1517 static void extract_json_paint_lcdrendertext(Json::Value& jsonPaint, SkPaint* target) {
1518 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT)) {
1519 target->setLCDRenderText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT].asBool());
1520 }
1521 }
1522
extract_json_paint_embeddedbitmaptext(Json::Value & jsonPaint,SkPaint * target)1523 static void extract_json_paint_embeddedbitmaptext(Json::Value& jsonPaint, SkPaint* target) {
1524 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT)) {
1525 target->setEmbeddedBitmapText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT].asBool());
1526 }
1527 }
1528
extract_json_paint_autohinting(Json::Value & jsonPaint,SkPaint * target)1529 static void extract_json_paint_autohinting(Json::Value& jsonPaint, SkPaint* target) {
1530 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING)) {
1531 target->setAutohinted(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING].asBool());
1532 }
1533 }
1534
extract_json_paint_verticaltext(Json::Value & jsonPaint,SkPaint * target)1535 static void extract_json_paint_verticaltext(Json::Value& jsonPaint, SkPaint* target) {
1536 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT)) {
1537 target->setVerticalText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT].asBool());
1538 }
1539 }
1540
extract_json_paint_blur(Json::Value & jsonPaint,SkPaint * target)1541 static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1542 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1543 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1544 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1545 SkBlurStyle style;
1546 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1547 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1548 style = SkBlurStyle::kNormal_SkBlurStyle;
1549 }
1550 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1551 style = SkBlurStyle::kSolid_SkBlurStyle;
1552 }
1553 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1554 style = SkBlurStyle::kOuter_SkBlurStyle;
1555 }
1556 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1557 style = SkBlurStyle::kInner_SkBlurStyle;
1558 }
1559 else {
1560 SkASSERT(false);
1561 style = SkBlurStyle::kNormal_SkBlurStyle;
1562 }
1563 SkBlurMaskFilter::BlurFlags flags;
1564 const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString();
1565 if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) {
1566 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1567 }
1568 else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) {
1569 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag;
1570 }
1571 else {
1572 SkASSERT(false);
1573 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1574 }
1575 target->setMaskFilter(SkBlurMaskFilter::Make(style, sigma, flags));
1576 }
1577 }
1578
extract_json_paint_dashing(Json::Value & jsonPaint,SkPaint * target)1579 static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1580 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1581 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1582 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1583 Json::ArrayIndex count = jsonIntervals.size();
1584 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1585 for (Json::ArrayIndex i = 0; i < count; i++) {
1586 intervals[i] = jsonIntervals[i].asFloat();
1587 }
1588 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
1589 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
1590 sk_free(intervals);
1591 }
1592 }
1593
extract_json_paint_textalign(Json::Value & jsonPaint,SkPaint * target)1594 static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1595 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1596 SkPaint::Align textAlign;
1597 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1598 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1599 textAlign = SkPaint::kLeft_Align;
1600 }
1601 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1602 textAlign = SkPaint::kCenter_Align;
1603 }
1604 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1605 textAlign = SkPaint::kRight_Align;
1606 }
1607 else {
1608 SkASSERT(false);
1609 textAlign = SkPaint::kLeft_Align;
1610 }
1611 target->setTextAlign(textAlign);
1612 }
1613 }
1614
extract_json_paint_textsize(Json::Value & jsonPaint,SkPaint * target)1615 static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1616 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1617 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1618 target->setTextSize(textSize);
1619 }
1620 }
1621
extract_json_paint_textscalex(Json::Value & jsonPaint,SkPaint * target)1622 static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1623 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1624 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1625 target->setTextScaleX(textScaleX);
1626 }
1627 }
1628
extract_json_paint_textskewx(Json::Value & jsonPaint,SkPaint * target)1629 static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1630 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1631 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1632 target->setTextSkewX(textSkewX);
1633 }
1634 }
1635
extract_json_paint(Json::Value & paint,UrlDataManager & urlDataManager,SkPaint * result)1636 static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
1637 SkPaint* result) {
1638 extract_json_paint_hinting(paint, result);
1639 extract_json_paint_color(paint, result);
1640 extract_json_paint_shader(paint, urlDataManager, result);
1641 extract_json_paint_patheffect(paint, urlDataManager, result);
1642 extract_json_paint_maskfilter(paint, urlDataManager, result);
1643 extract_json_paint_colorfilter(paint, urlDataManager, result);
1644 extract_json_paint_looper(paint, urlDataManager, result);
1645 extract_json_paint_imagefilter(paint, urlDataManager, result);
1646 extract_json_paint_typeface(paint, urlDataManager, result);
1647 extract_json_paint_style(paint, result);
1648 extract_json_paint_blend_mode(paint, result);
1649 extract_json_paint_strokewidth(paint, result);
1650 extract_json_paint_strokemiter(paint, result);
1651 extract_json_paint_strokejoin(paint, result);
1652 extract_json_paint_cap(paint, result);
1653 extract_json_paint_filterquality(paint, result);
1654 extract_json_paint_antialias(paint, result);
1655 extract_json_paint_dither(paint, result);
1656 extract_json_paint_fakeboldtext(paint, result);
1657 extract_json_paint_lineartext(paint, result);
1658 extract_json_paint_subpixeltext(paint, result);
1659 extract_json_paint_devkerntext(paint, result);
1660 extract_json_paint_lcdrendertext(paint, result);
1661 extract_json_paint_embeddedbitmaptext(paint, result);
1662 extract_json_paint_autohinting(paint, result);
1663 extract_json_paint_verticaltext(paint, result);
1664 extract_json_paint_blur(paint, result);
1665 extract_json_paint_dashing(paint, result);
1666 extract_json_paint_textalign(paint, result);
1667 extract_json_paint_textsize(paint, result);
1668 extract_json_paint_textscalex(paint, result);
1669 extract_json_paint_textskewx(paint, result);
1670 }
1671
extract_json_rect(Json::Value & rect,SkRect * result)1672 static void extract_json_rect(Json::Value& rect, SkRect* result) {
1673 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1674 }
1675
extract_json_irect(Json::Value & rect,SkIRect * result)1676 static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1677 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1678 }
1679
extract_json_rrect(Json::Value & rrect,SkRRect * result)1680 static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1681 SkVector radii[4] = {
1682 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1683 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1684 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
1685 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1686 };
1687 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1688 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
1689 radii);
1690 }
1691
extract_json_matrix(Json::Value & matrix,SkMatrix * result)1692 static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
1693 SkScalar values[] = {
1694 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1695 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
1696 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
1697 };
1698 result->set9(values);
1699 }
1700
extract_json_path(Json::Value & path,SkPath * result)1701 static void extract_json_path(Json::Value& path, SkPath* result) {
1702 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1703 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1704 result->setFillType(SkPath::kWinding_FillType);
1705 }
1706 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1707 result->setFillType(SkPath::kEvenOdd_FillType);
1708 }
1709 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1710 result->setFillType(SkPath::kInverseWinding_FillType);
1711 }
1712 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1713 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1714 }
1715 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1716 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1717 Json::Value verb = verbs[i];
1718 if (verb.isString()) {
1719 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1720 result->close();
1721 }
1722 else {
1723 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1724 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1725 result->moveTo(move[0].asFloat(), move[1].asFloat());
1726 }
1727 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1728 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1729 result->lineTo(line[0].asFloat(), line[1].asFloat());
1730 }
1731 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1732 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1733 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1734 quad[1][0].asFloat(), quad[1][1].asFloat());
1735 }
1736 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1737 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1738 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1739 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1740 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1741 }
1742 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1743 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1744 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1745 conic[1][0].asFloat(), conic[1][1].asFloat(),
1746 conic[2].asFloat());
1747 }
1748 else {
1749 SkASSERT(false);
1750 }
1751 }
1752 }
1753 }
1754
get_json_clipop(Json::Value & jsonOp)1755 SkClipOp get_json_clipop(Json::Value& jsonOp) {
1756 const char* op = jsonOp.asCString();
1757 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
1758 return kDifference_SkClipOp;
1759 }
1760 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
1761 return kIntersect_SkClipOp;
1762 }
1763 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
1764 return kUnion_SkClipOp;
1765 }
1766 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
1767 return kXOR_SkClipOp;
1768 }
1769 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
1770 return kReverseDifference_SkClipOp;
1771 }
1772 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
1773 return kReplace_SkClipOp;
1774 }
1775 SkASSERT(false);
1776 return kIntersect_SkClipOp;
1777 }
1778
SkClearCommand(SkColor color)1779 SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kDrawClear_OpType) {
1780 fColor = color;
1781 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
1782 }
1783
execute(SkCanvas * canvas) const1784 void SkClearCommand::execute(SkCanvas* canvas) const {
1785 canvas->clear(fColor);
1786 }
1787
toJSON(UrlDataManager & urlDataManager) const1788 Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1789 Json::Value result = INHERITED::toJSON(urlDataManager);
1790 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
1791 return result;
1792 }
1793
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1794 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
1795 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1796 return new SkClearCommand(get_json_color(color));
1797 }
1798
SkClipPathCommand(const SkPath & path,SkClipOp op,bool doAA)1799 SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
1800 : INHERITED(kClipPath_OpType) {
1801 fPath = path;
1802 fOp = op;
1803 fDoAA = doAA;
1804
1805 fInfo.push(SkObjectParser::PathToString(path));
1806 fInfo.push(SkObjectParser::ClipOpToString(op));
1807 fInfo.push(SkObjectParser::BoolToString(doAA));
1808 }
1809
execute(SkCanvas * canvas) const1810 void SkClipPathCommand::execute(SkCanvas* canvas) const {
1811 canvas->clipPath(fPath, fOp, fDoAA);
1812 }
1813
render(SkCanvas * canvas) const1814 bool SkClipPathCommand::render(SkCanvas* canvas) const {
1815 render_path(canvas, fPath);
1816 return true;
1817 }
1818
toJSON(UrlDataManager & urlDataManager) const1819 Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1820 Json::Value result = INHERITED::toJSON(urlDataManager);
1821 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
1822 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1823 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1824 return result;
1825 }
1826
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1827 SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
1828 UrlDataManager& urlDataManager) {
1829 SkPath path;
1830 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
1831 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1832 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1833 }
1834
SkClipRegionCommand(const SkRegion & region,SkClipOp op)1835 SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
1836 : INHERITED(kClipRegion_OpType) {
1837 fRegion = region;
1838 fOp = op;
1839
1840 fInfo.push(SkObjectParser::RegionToString(region));
1841 fInfo.push(SkObjectParser::ClipOpToString(op));
1842 }
1843
execute(SkCanvas * canvas) const1844 void SkClipRegionCommand::execute(SkCanvas* canvas) const {
1845 canvas->clipRegion(fRegion, fOp);
1846 }
1847
toJSON(UrlDataManager & urlDataManager) const1848 Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1849 Json::Value result = INHERITED::toJSON(urlDataManager);
1850 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
1851 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1852 return result;
1853 }
1854
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1855 SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
1856 UrlDataManager& urlDataManager) {
1857 SkASSERT(false);
1858 return nullptr;
1859 }
1860
SkClipRectCommand(const SkRect & rect,SkClipOp op,bool doAA)1861 SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
1862 : INHERITED(kClipRect_OpType) {
1863 fRect = rect;
1864 fOp = op;
1865 fDoAA = doAA;
1866
1867 fInfo.push(SkObjectParser::RectToString(rect));
1868 fInfo.push(SkObjectParser::ClipOpToString(op));
1869 fInfo.push(SkObjectParser::BoolToString(doAA));
1870 }
1871
execute(SkCanvas * canvas) const1872 void SkClipRectCommand::execute(SkCanvas* canvas) const {
1873 canvas->clipRect(fRect, fOp, fDoAA);
1874 }
1875
toJSON(UrlDataManager & urlDataManager) const1876 Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1877 Json::Value result = INHERITED::toJSON(urlDataManager);
1878 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1879 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1880 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1881
1882 SkString desc;
1883 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1884
1885 return result;
1886 }
1887
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1888 SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
1889 UrlDataManager& urlDataManager) {
1890 SkRect rect;
1891 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
1892 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1893 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1894 }
1895
SkClipRRectCommand(const SkRRect & rrect,SkClipOp op,bool doAA)1896 SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
1897 : INHERITED(kClipRRect_OpType) {
1898 fRRect = rrect;
1899 fOp = op;
1900 fDoAA = doAA;
1901
1902 fInfo.push(SkObjectParser::RRectToString(rrect));
1903 fInfo.push(SkObjectParser::ClipOpToString(op));
1904 fInfo.push(SkObjectParser::BoolToString(doAA));
1905 }
1906
execute(SkCanvas * canvas) const1907 void SkClipRRectCommand::execute(SkCanvas* canvas) const {
1908 canvas->clipRRect(fRRect, fOp, fDoAA);
1909 }
1910
render(SkCanvas * canvas) const1911 bool SkClipRRectCommand::render(SkCanvas* canvas) const {
1912 render_rrect(canvas, fRRect);
1913 return true;
1914 }
1915
toJSON(UrlDataManager & urlDataManager) const1916 Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1917 Json::Value result = INHERITED::toJSON(urlDataManager);
1918 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1919 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1920 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1921 return result;
1922 }
1923
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1924 SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
1925 UrlDataManager& urlDataManager) {
1926 SkRRect rrect;
1927 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
1928 return new SkClipRRectCommand(rrect,
1929 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1930 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1931 }
1932
SkConcatCommand(const SkMatrix & matrix)1933 SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
1934 : INHERITED(kConcat_OpType) {
1935 fMatrix = matrix;
1936
1937 fInfo.push(SkObjectParser::MatrixToString(matrix));
1938 }
1939
execute(SkCanvas * canvas) const1940 void SkConcatCommand::execute(SkCanvas* canvas) const {
1941 canvas->concat(fMatrix);
1942 }
1943
toJSON(UrlDataManager & urlDataManager) const1944 Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1945 Json::Value result = INHERITED::toJSON(urlDataManager);
1946 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
1947 return result;
1948 }
1949
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1950 SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
1951 SkMatrix matrix;
1952 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1953 return new SkConcatCommand(matrix);
1954 }
1955
1956 ////
1957
SkDrawAnnotationCommand(const SkRect & rect,const char key[],sk_sp<SkData> value)1958 SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1959 sk_sp<SkData> value)
1960 : INHERITED(kDrawAnnotation_OpType)
1961 , fRect(rect)
1962 , fKey(key)
1963 , fValue(std::move(value))
1964 {
1965 SkString str;
1966 str.appendf("Key: %s Value: ", key);
1967 if (fValue && fValue->size()) {
1968 str.append((const char*) fValue->bytes(), fValue->size());
1969 } else {
1970 str.appendf("no value");
1971 }
1972 str.appendf("\n");
1973 fInfo.push(new SkString(str));
1974 }
1975
execute(SkCanvas * canvas) const1976 void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1977 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1978 }
1979
toJSON(UrlDataManager & urlDataManager) const1980 Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1981 Json::Value result = INHERITED::toJSON(urlDataManager);
1982
1983 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1984 result["key"] = Json::Value(fKey.c_str());
1985 if (fValue.get()) {
1986 // TODO: dump out the "value"
1987 }
1988
1989 SkString desc;
1990 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
1991 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
1992
1993 return result;
1994 }
1995
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)1996 SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
1997 UrlDataManager& urlDataManager) {
1998 SkRect rect;
1999 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
2000 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
2001 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
2002 }
2003
2004 ////
2005
SkDrawBitmapCommand(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint)2006 SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
2007 const SkPaint* paint)
2008 : INHERITED(kDrawBitmap_OpType) {
2009 fBitmap = bitmap;
2010 fLeft = left;
2011 fTop = top;
2012 if (paint) {
2013 fPaint = *paint;
2014 fPaintPtr = &fPaint;
2015 } else {
2016 fPaintPtr = nullptr;
2017 }
2018
2019 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2020 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
2021 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
2022 if (paint) {
2023 fInfo.push(SkObjectParser::PaintToString(*paint));
2024 }
2025 }
2026
execute(SkCanvas * canvas) const2027 void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
2028 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
2029 }
2030
render(SkCanvas * canvas) const2031 bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
2032 render_bitmap(canvas, fBitmap);
2033 return true;
2034 }
2035
toJSON(UrlDataManager & urlDataManager) const2036 Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
2037 Json::Value result = INHERITED::toJSON(urlDataManager);
2038 Json::Value encoded;
2039 if (flatten(fBitmap, &encoded, urlDataManager)) {
2040 Json::Value command(Json::objectValue);
2041 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2042 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
2043 if (fPaintPtr != nullptr) {
2044 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2045 }
2046 }
2047 return result;
2048 }
2049
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2050 SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
2051 UrlDataManager& urlDataManager) {
2052 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
2053 if (bitmap == nullptr) {
2054 return nullptr;
2055 }
2056 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2057 SkPaint* paintPtr;
2058 SkPaint paint;
2059 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2060 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2061 paintPtr = &paint;
2062 }
2063 else {
2064 paintPtr = nullptr;
2065 }
2066 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
2067 point[1].asFloat(), paintPtr);
2068 delete bitmap;
2069 return result;
2070 }
2071
SkDrawBitmapNineCommand(const SkBitmap & bitmap,const SkIRect & center,const SkRect & dst,const SkPaint * paint)2072 SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
2073 const SkRect& dst, const SkPaint* paint)
2074 : INHERITED(kDrawBitmapNine_OpType) {
2075 fBitmap = bitmap;
2076 fCenter = center;
2077 fDst = dst;
2078 if (paint) {
2079 fPaint = *paint;
2080 fPaintPtr = &fPaint;
2081 } else {
2082 fPaintPtr = nullptr;
2083 }
2084
2085 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2086 fInfo.push(SkObjectParser::IRectToString(center));
2087 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2088 if (paint) {
2089 fInfo.push(SkObjectParser::PaintToString(*paint));
2090 }
2091 }
2092
execute(SkCanvas * canvas) const2093 void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
2094 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
2095 }
2096
render(SkCanvas * canvas) const2097 bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
2098 SkRect tmp = SkRect::Make(fCenter);
2099 render_bitmap(canvas, fBitmap, &tmp);
2100 return true;
2101 }
2102
toJSON(UrlDataManager & urlDataManager) const2103 Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2104 Json::Value result = INHERITED::toJSON(urlDataManager);
2105 Json::Value encoded;
2106 if (flatten(fBitmap, &encoded, urlDataManager)) {
2107 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2108 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
2109 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2110 if (fPaintPtr != nullptr) {
2111 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2112 }
2113 }
2114 return result;
2115 }
2116
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2117 SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
2118 UrlDataManager& urlDataManager) {
2119 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
2120 if (bitmap == nullptr) {
2121 return nullptr;
2122 }
2123 SkIRect center;
2124 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], ¢er);
2125 SkRect dst;
2126 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2127 SkPaint* paintPtr;
2128 SkPaint paint;
2129 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2130 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2131 paintPtr = &paint;
2132 }
2133 else {
2134 paintPtr = nullptr;
2135 }
2136 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2137 delete bitmap;
2138 return result;
2139 }
2140
SkDrawBitmapRectCommand(const SkBitmap & bitmap,const SkRect * src,const SkRect & dst,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)2141 SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
2142 const SkRect& dst, const SkPaint* paint,
2143 SkCanvas::SrcRectConstraint constraint)
2144 : INHERITED(kDrawBitmapRect_OpType) {
2145 fBitmap = bitmap;
2146 if (src) {
2147 fSrc = *src;
2148 } else {
2149 fSrc.setEmpty();
2150 }
2151 fDst = dst;
2152
2153 if (paint) {
2154 fPaint = *paint;
2155 fPaintPtr = &fPaint;
2156 } else {
2157 fPaintPtr = nullptr;
2158 }
2159 fConstraint = constraint;
2160
2161 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2162 if (src) {
2163 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2164 }
2165 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2166 if (paint) {
2167 fInfo.push(SkObjectParser::PaintToString(*paint));
2168 }
2169 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
2170 }
2171
execute(SkCanvas * canvas) const2172 void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
2173 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
2174 }
2175
render(SkCanvas * canvas) const2176 bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
2177 render_bitmap(canvas, fBitmap, this->srcRect());
2178 return true;
2179 }
2180
toJSON(UrlDataManager & urlDataManager) const2181 Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2182 Json::Value result = INHERITED::toJSON(urlDataManager);
2183 Json::Value encoded;
2184 if (flatten(fBitmap, &encoded, urlDataManager)) {
2185 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2186 if (!fSrc.isEmpty()) {
2187 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
2188 }
2189 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2190 if (fPaintPtr != nullptr) {
2191 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2192 }
2193 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2194 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2195 }
2196 }
2197
2198 SkString desc;
2199 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2200
2201 return result;
2202 }
2203
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2204 SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
2205 UrlDataManager& urlDataManager) {
2206 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
2207 if (bitmap == nullptr) {
2208 return nullptr;
2209 }
2210 SkRect dst;
2211 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2212 SkPaint* paintPtr;
2213 SkPaint paint;
2214 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2215 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2216 paintPtr = &paint;
2217 }
2218 else {
2219 paintPtr = nullptr;
2220 }
2221 SkCanvas::SrcRectConstraint constraint;
2222 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
2223 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2224 constraint = SkCanvas::kStrict_SrcRectConstraint;
2225 }
2226 else {
2227 constraint = SkCanvas::kFast_SrcRectConstraint;
2228 }
2229 SkRect* srcPtr;
2230 SkRect src;
2231 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2232 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2233 srcPtr = &src;
2234 }
2235 else {
2236 srcPtr = nullptr;
2237 }
2238 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2239 constraint);
2240 delete bitmap;
2241 return result;
2242 }
2243
SkDrawImageCommand(const SkImage * image,SkScalar left,SkScalar top,const SkPaint * paint)2244 SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2245 const SkPaint* paint)
2246 : INHERITED(kDrawImage_OpType)
2247 , fImage(SkRef(image))
2248 , fLeft(left)
2249 , fTop(top) {
2250
2251 fInfo.push(SkObjectParser::ImageToString(image));
2252 fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
2253 fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));
2254
2255 if (paint) {
2256 fPaint.set(*paint);
2257 fInfo.push(SkObjectParser::PaintToString(*paint));
2258 }
2259 }
2260
execute(SkCanvas * canvas) const2261 void SkDrawImageCommand::execute(SkCanvas* canvas) const {
2262 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
2263 }
2264
render(SkCanvas * canvas) const2265 bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2266 SkAutoCanvasRestore acr(canvas, true);
2267 canvas->clear(0xFFFFFFFF);
2268
2269 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2270 SkIntToScalar(fImage->width()),
2271 SkIntToScalar(fImage->height())));
2272 this->execute(canvas);
2273 return true;
2274 }
2275
toJSON(UrlDataManager & urlDataManager) const2276 Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2277 Json::Value result = INHERITED::toJSON(urlDataManager);
2278 Json::Value encoded;
2279 if (flatten(*fImage, &encoded, urlDataManager)) {
2280 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
2281 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
2282 if (fPaint.isValid()) {
2283 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2284 }
2285
2286 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2287 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2288 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2289 switch (fImage->alphaType()) {
2290 case kOpaque_SkAlphaType:
2291 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2292 break;
2293 case kPremul_SkAlphaType:
2294 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2295 break;
2296 case kUnpremul_SkAlphaType:
2297 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2298 break;
2299 default:
2300 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2301 break;
2302 }
2303 }
2304 return result;
2305 }
2306
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2307 SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
2308 UrlDataManager& urlDataManager) {
2309 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2310 if (image == nullptr) {
2311 return nullptr;
2312 }
2313 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2314 SkPaint* paintPtr;
2315 SkPaint paint;
2316 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2317 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2318 paintPtr = &paint;
2319 }
2320 else {
2321 paintPtr = nullptr;
2322 }
2323 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
2324 point[1].asFloat(), paintPtr);
2325 return result;
2326 }
2327
SkDrawImageLatticeCommand(const SkImage * image,const SkCanvas::Lattice & lattice,const SkRect & dst,const SkPaint * paint)2328 SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2329 const SkCanvas::Lattice& lattice,
2330 const SkRect& dst, const SkPaint* paint)
2331 : INHERITED(kDrawImageLattice_OpType)
2332 , fImage(SkRef(image))
2333 , fLattice(lattice)
2334 , fDst(dst) {
2335
2336 fInfo.push(SkObjectParser::ImageToString(image));
2337 fInfo.push(SkObjectParser::LatticeToString(lattice));
2338 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2339 if (paint) {
2340 fPaint.set(*paint);
2341 fInfo.push(SkObjectParser::PaintToString(*paint));
2342 }
2343 }
2344
execute(SkCanvas * canvas) const2345 void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
2346 SkLatticeIter iter(fLattice, fDst);
2347 SkRect srcR, dstR;
2348 while (iter.next(&srcR, &dstR)) {
2349 canvas->legacy_drawImageRect(fImage.get(), &srcR, dstR,
2350 fPaint.getMaybeNull(), SkCanvas::kStrict_SrcRectConstraint);
2351 }
2352 }
2353
render(SkCanvas * canvas) const2354 bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2355 SkAutoCanvasRestore acr(canvas, true);
2356 canvas->clear(0xFFFFFFFF);
2357
2358 xlate_and_scale_to_bounds(canvas, fDst);
2359
2360 this->execute(canvas);
2361 return true;
2362 }
2363
toJSON(UrlDataManager & urlDataManager) const2364 Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2365 Json::Value result = INHERITED::toJSON(urlDataManager);
2366 Json::Value encoded;
2367 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2368 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2369 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2370 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2371 if (fPaint.isValid()) {
2372 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2373 }
2374 }
2375
2376 SkString desc;
2377 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2378
2379 return result;
2380 }
2381
SkDrawImageRectCommand(const SkImage * image,const SkRect * src,const SkRect & dst,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)2382 SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2383 const SkRect& dst, const SkPaint* paint,
2384 SkCanvas::SrcRectConstraint constraint)
2385 : INHERITED(kDrawImageRect_OpType)
2386 , fImage(SkRef(image))
2387 , fDst(dst)
2388 , fConstraint(constraint) {
2389
2390 if (src) {
2391 fSrc.set(*src);
2392 }
2393
2394 if (paint) {
2395 fPaint.set(*paint);
2396 }
2397
2398 fInfo.push(SkObjectParser::ImageToString(image));
2399 if (src) {
2400 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2401 }
2402 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2403 if (paint) {
2404 fInfo.push(SkObjectParser::PaintToString(*paint));
2405 }
2406 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
2407 }
2408
execute(SkCanvas * canvas) const2409 void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
2410 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2411 fPaint.getMaybeNull(), fConstraint);
2412 }
2413
render(SkCanvas * canvas) const2414 bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2415 SkAutoCanvasRestore acr(canvas, true);
2416 canvas->clear(0xFFFFFFFF);
2417
2418 xlate_and_scale_to_bounds(canvas, fDst);
2419
2420 this->execute(canvas);
2421 return true;
2422 }
2423
toJSON(UrlDataManager & urlDataManager) const2424 Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2425 Json::Value result = INHERITED::toJSON(urlDataManager);
2426 Json::Value encoded;
2427 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2428 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2429 if (fSrc.isValid()) {
2430 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
2431 }
2432 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2433 if (fPaint.isValid()) {
2434 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2435 }
2436 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2437 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2438 }
2439 }
2440
2441 SkString desc;
2442 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2443
2444 return result;
2445 }
2446
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2447 SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
2448 UrlDataManager& urlDataManager) {
2449 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2450 if (image == nullptr) {
2451 return nullptr;
2452 }
2453 SkRect dst;
2454 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2455 SkPaint* paintPtr;
2456 SkPaint paint;
2457 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2458 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2459 paintPtr = &paint;
2460 }
2461 else {
2462 paintPtr = nullptr;
2463 }
2464 SkCanvas::SrcRectConstraint constraint;
2465 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
2466 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2467 constraint = SkCanvas::kStrict_SrcRectConstraint;
2468 }
2469 else {
2470 constraint = SkCanvas::kFast_SrcRectConstraint;
2471 }
2472 SkRect* srcPtr;
2473 SkRect src;
2474 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2475 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2476 srcPtr = &src;
2477 }
2478 else {
2479 srcPtr = nullptr;
2480 }
2481 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
2482 constraint);
2483 return result;
2484 }
2485
SkDrawOvalCommand(const SkRect & oval,const SkPaint & paint)2486 SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
2487 : INHERITED(kDrawOval_OpType) {
2488 fOval = oval;
2489 fPaint = paint;
2490
2491 fInfo.push(SkObjectParser::RectToString(oval));
2492 fInfo.push(SkObjectParser::PaintToString(paint));
2493 }
2494
execute(SkCanvas * canvas) const2495 void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
2496 canvas->drawOval(fOval, fPaint);
2497 }
2498
render(SkCanvas * canvas) const2499 bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
2500 canvas->clear(0xFFFFFFFF);
2501 canvas->save();
2502
2503 xlate_and_scale_to_bounds(canvas, fOval);
2504
2505 SkPaint p;
2506 p.setColor(SK_ColorBLACK);
2507 p.setStyle(SkPaint::kStroke_Style);
2508
2509 canvas->drawOval(fOval, p);
2510 canvas->restore();
2511
2512 return true;
2513 }
2514
toJSON(UrlDataManager & urlDataManager) const2515 Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2516 Json::Value result = INHERITED::toJSON(urlDataManager);
2517 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2518 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2519 return result;
2520 }
2521
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2522 SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
2523 UrlDataManager& urlDataManager) {
2524 SkRect coords;
2525 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2526 SkPaint paint;
2527 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2528 return new SkDrawOvalCommand(coords, paint);
2529 }
2530
SkDrawArcCommand(const SkRect & oval,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)2531 SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2532 bool useCenter, const SkPaint& paint)
2533 : INHERITED(kDrawOval_OpType) {
2534 fOval = oval;
2535 fStartAngle = startAngle;
2536 fSweepAngle = sweepAngle;
2537 fUseCenter = useCenter;
2538 fPaint = paint;
2539
2540 fInfo.push(SkObjectParser::RectToString(oval));
2541 fInfo.push(SkObjectParser::ScalarToString(startAngle, "StartAngle: "));
2542 fInfo.push(SkObjectParser::ScalarToString(sweepAngle, "SweepAngle: "));
2543 fInfo.push(SkObjectParser::BoolToString(useCenter));
2544 fInfo.push(SkObjectParser::PaintToString(paint));
2545 }
2546
execute(SkCanvas * canvas) const2547 void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2548 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2549 }
2550
render(SkCanvas * canvas) const2551 bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2552 canvas->clear(0xFFFFFFFF);
2553 canvas->save();
2554
2555 xlate_and_scale_to_bounds(canvas, fOval);
2556
2557 SkPaint p;
2558 p.setColor(SK_ColorBLACK);
2559 p.setStyle(SkPaint::kStroke_Style);
2560
2561 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2562 canvas->restore();
2563
2564 return true;
2565 }
2566
toJSON(UrlDataManager & urlDataManager) const2567 Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2568 Json::Value result = INHERITED::toJSON(urlDataManager);
2569 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2570 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2571 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2572 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2573 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2574 return result;
2575 }
2576
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2577 SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2578 UrlDataManager& urlDataManager) {
2579 SkRect coords;
2580 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2581 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2582 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2583 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2584 SkPaint paint;
2585 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2586 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2587 }
2588
SkDrawPaintCommand(const SkPaint & paint)2589 SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
2590 : INHERITED(kDrawPaint_OpType) {
2591 fPaint = paint;
2592
2593 fInfo.push(SkObjectParser::PaintToString(paint));
2594 }
2595
execute(SkCanvas * canvas) const2596 void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
2597 canvas->drawPaint(fPaint);
2598 }
2599
render(SkCanvas * canvas) const2600 bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
2601 canvas->clear(0xFFFFFFFF);
2602 canvas->drawPaint(fPaint);
2603 return true;
2604 }
2605
toJSON(UrlDataManager & urlDataManager) const2606 Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2607 Json::Value result = INHERITED::toJSON(urlDataManager);
2608 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2609 return result;
2610 }
2611
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2612 SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
2613 UrlDataManager& urlDataManager) {
2614 SkPaint paint;
2615 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2616 return new SkDrawPaintCommand(paint);
2617 }
2618
SkDrawPathCommand(const SkPath & path,const SkPaint & paint)2619 SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
2620 : INHERITED(kDrawPath_OpType) {
2621 fPath = path;
2622 fPaint = paint;
2623
2624 fInfo.push(SkObjectParser::PathToString(path));
2625 fInfo.push(SkObjectParser::PaintToString(paint));
2626 }
2627
execute(SkCanvas * canvas) const2628 void SkDrawPathCommand::execute(SkCanvas* canvas) const {
2629 canvas->drawPath(fPath, fPaint);
2630 }
2631
render(SkCanvas * canvas) const2632 bool SkDrawPathCommand::render(SkCanvas* canvas) const {
2633 render_path(canvas, fPath);
2634 return true;
2635 }
2636
toJSON(UrlDataManager & urlDataManager) const2637 Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2638 Json::Value result = INHERITED::toJSON(urlDataManager);
2639 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2640 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2641 return result;
2642 }
2643
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2644 SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
2645 UrlDataManager& urlDataManager) {
2646 SkPath path;
2647 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2648 SkPaint paint;
2649 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2650 return new SkDrawPathCommand(path, paint);
2651 }
2652
SkBeginDrawPictureCommand(const SkPicture * picture,const SkMatrix * matrix,const SkPaint * paint)2653 SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2654 const SkMatrix* matrix,
2655 const SkPaint* paint)
2656 : INHERITED(kBeginDrawPicture_OpType)
2657 , fPicture(SkRef(picture)) {
2658
2659 SkString* str = new SkString;
2660 str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
2661 picture->cullRect().fLeft, picture->cullRect().fTop,
2662 picture->cullRect().fRight, picture->cullRect().fBottom);
2663 fInfo.push(str);
2664
2665 if (matrix) {
2666 fMatrix.set(*matrix);
2667 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2668 }
2669
2670 if (paint) {
2671 fPaint.set(*paint);
2672 fInfo.push(SkObjectParser::PaintToString(*paint));
2673 }
2674
2675 }
2676
execute(SkCanvas * canvas) const2677 void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2678 if (fPaint.isValid()) {
2679 SkRect bounds = fPicture->cullRect();
2680 if (fMatrix.isValid()) {
2681 fMatrix.get()->mapRect(&bounds);
2682 }
2683 canvas->saveLayer(&bounds, fPaint.get());
2684 }
2685
2686 if (fMatrix.isValid()) {
2687 if (!fPaint.isValid()) {
2688 canvas->save();
2689 }
2690 canvas->concat(*fMatrix.get());
2691 }
2692 }
2693
render(SkCanvas * canvas) const2694 bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
2695 canvas->clear(0xFFFFFFFF);
2696 canvas->save();
2697
2698 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
2699
2700 canvas->drawPicture(fPicture.get());
2701
2702 canvas->restore();
2703
2704 return true;
2705 }
2706
SkEndDrawPictureCommand(bool restore)2707 SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2708 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2709
execute(SkCanvas * canvas) const2710 void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2711 if (fRestore) {
2712 canvas->restore();
2713 }
2714 }
2715
SkDrawPointsCommand(SkCanvas::PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)2716 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
2717 const SkPoint pts[], const SkPaint& paint)
2718 : INHERITED(kDrawPoints_OpType) {
2719 fMode = mode;
2720 fCount = count;
2721 fPts = new SkPoint[count];
2722 memcpy(fPts, pts, count * sizeof(SkPoint));
2723 fPaint = paint;
2724
2725 fInfo.push(SkObjectParser::PointsToString(pts, count));
2726 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
2727 "Points: "));
2728 fInfo.push(SkObjectParser::PointModeToString(mode));
2729 fInfo.push(SkObjectParser::PaintToString(paint));
2730 }
2731
execute(SkCanvas * canvas) const2732 void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
2733 canvas->drawPoints(fMode, fCount, fPts, fPaint);
2734 }
2735
render(SkCanvas * canvas) const2736 bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
2737 canvas->clear(0xFFFFFFFF);
2738 canvas->save();
2739
2740 SkRect bounds;
2741
2742 bounds.setEmpty();
2743 for (unsigned int i = 0; i < fCount; ++i) {
2744 bounds.growToInclude(fPts[i].fX, fPts[i].fY);
2745 }
2746
2747 xlate_and_scale_to_bounds(canvas, bounds);
2748
2749 SkPaint p;
2750 p.setColor(SK_ColorBLACK);
2751 p.setStyle(SkPaint::kStroke_Style);
2752
2753 canvas->drawPoints(fMode, fCount, fPts, p);
2754 canvas->restore();
2755
2756 return true;
2757 }
2758
toJSON(UrlDataManager & urlDataManager) const2759 Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2760 Json::Value result = INHERITED::toJSON(urlDataManager);
2761 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2762 Json::Value points(Json::arrayValue);
2763 for (size_t i = 0; i < fCount; i++) {
2764 points.append(MakeJsonPoint(fPts[i]));
2765 }
2766 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
2767 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2768 return result;
2769 }
2770
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2771 SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
2772 UrlDataManager& urlDataManager) {
2773 SkCanvas::PointMode mode;
2774 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2775 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2776 mode = SkCanvas::kPoints_PointMode;
2777 }
2778 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2779 mode = SkCanvas::kLines_PointMode;
2780 }
2781 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2782 mode = SkCanvas::kPolygon_PointMode;
2783 }
2784 else {
2785 SkASSERT(false);
2786 return nullptr;
2787 }
2788 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2789 int count = (int) jsonPoints.size();
2790 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2791 for (int i = 0; i < count; i++) {
2792 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2793 }
2794 SkPaint paint;
2795 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2796 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2797 sk_free(points);
2798 return result;
2799 }
2800
SkDrawPosTextCommand(const void * text,size_t byteLength,const SkPoint pos[],const SkPaint & paint)2801 SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
2802 const SkPoint pos[], const SkPaint& paint)
2803 : INHERITED(kDrawPosText_OpType) {
2804 size_t numPts = paint.countText(text, byteLength);
2805
2806 fText = new char[byteLength];
2807 memcpy(fText, text, byteLength);
2808 fByteLength = byteLength;
2809
2810 fPos = new SkPoint[numPts];
2811 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2812
2813 fPaint = paint;
2814
2815 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2816 // TODO(chudy): Test that this works.
2817 fInfo.push(SkObjectParser::PointsToString(pos, 1));
2818 fInfo.push(SkObjectParser::PaintToString(paint));
2819 }
2820
execute(SkCanvas * canvas) const2821 void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
2822 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
2823 }
2824
toJSON(UrlDataManager & urlDataManager) const2825 Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2826 Json::Value result = INHERITED::toJSON(urlDataManager);
2827 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2828 ((const char*) fText) + fByteLength);
2829 Json::Value coords(Json::arrayValue);
2830 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2831 for (size_t i = 0; i < numCoords; i++) {
2832 coords.append(MakeJsonPoint(fPos[i]));
2833 }
2834 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
2835 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2836 return result;
2837 }
2838
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2839 SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
2840 UrlDataManager& urlDataManager) {
2841 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2842 SkPaint paint;
2843 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2844 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2845 int count = (int) coords.size();
2846 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2847 for (int i = 0; i < count; i++) {
2848 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2849 }
2850 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2851 }
2852
SkDrawPosTextHCommand(const void * text,size_t byteLength,const SkScalar xpos[],SkScalar constY,const SkPaint & paint)2853 SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2854 const SkScalar xpos[], SkScalar constY,
2855 const SkPaint& paint)
2856 : INHERITED(kDrawPosTextH_OpType) {
2857 size_t numPts = paint.countText(text, byteLength);
2858
2859 fText = new char[byteLength];
2860 memcpy(fText, text, byteLength);
2861 fByteLength = byteLength;
2862
2863 fXpos = new SkScalar[numPts];
2864 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2865
2866 fConstY = constY;
2867 fPaint = paint;
2868
2869 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2870 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
2871 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
2872 fInfo.push(SkObjectParser::PaintToString(paint));
2873 }
2874
execute(SkCanvas * canvas) const2875 void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
2876 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
2877 }
2878
toJSON(UrlDataManager & urlDataManager) const2879 Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
2880 Json::Value result = INHERITED::toJSON(urlDataManager);
2881 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2882 ((const char*) fText) + fByteLength);
2883 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
2884 Json::Value xpos(Json::arrayValue);
2885 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2886 for (size_t i = 0; i < numXpos; i++) {
2887 xpos.append(Json::Value(fXpos[i]));
2888 }
2889 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
2890 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2891 return result;
2892 }
2893
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)2894 SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
2895 UrlDataManager& urlDataManager) {
2896 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2897 SkPaint paint;
2898 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2899 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2900 int count = (int) jsonXpos.size();
2901 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
2902 for (int i = 0; i < count; i++) {
2903 xpos[i] = jsonXpos[i].asFloat();
2904 }
2905 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2906 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
2907 }
2908
2909 static const char* gPositioningLabels[] = {
2910 "kDefault_Positioning",
2911 "kHorizontal_Positioning",
2912 "kFull_Positioning",
2913 };
2914
SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob,SkScalar x,SkScalar y,const SkPaint & paint)2915 SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
2916 const SkPaint& paint)
2917 : INHERITED(kDrawTextBlob_OpType)
2918 , fBlob(std::move(blob))
2919 , fXPos(x)
2920 , fYPos(y)
2921 , fPaint(paint) {
2922
2923 std::unique_ptr<SkString> runsStr(new SkString);
2924 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
2925 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
2926 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
2927 fInfo.push(runsStr.get());
2928 fInfo.push(SkObjectParser::PaintToString(paint));
2929
2930 unsigned runs = 0;
2931 SkPaint runPaint(paint);
2932 SkTextBlobRunIterator iter(fBlob.get());
2933 while (!iter.done()) {
2934 std::unique_ptr<SkString> tmpStr(new SkString);
2935 tmpStr->printf("==== Run [%d] ====", runs++);
2936 fInfo.push(tmpStr.release());
2937
2938 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
2939 tmpStr.reset(new SkString("GlyphPositioning: "));
2940 tmpStr->append(gPositioningLabels[iter.positioning()]);
2941 fInfo.push(tmpStr.release());
2942
2943 iter.applyFontToPaint(&runPaint);
2944 fInfo.push(SkObjectParser::PaintToString(runPaint));
2945
2946 iter.next();
2947 }
2948
2949 runsStr->printf("Runs: %d", runs);
2950 // runStr is owned by fInfo at this point.
2951 runsStr.release();
2952 }
2953
execute(SkCanvas * canvas) const2954 void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
2955 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2956 }
2957
render(SkCanvas * canvas) const2958 bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
2959 canvas->clear(SK_ColorWHITE);
2960 canvas->save();
2961
2962 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
2963 xlate_and_scale_to_bounds(canvas, bounds);
2964
2965 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2966
2967 canvas->restore();
2968
2969 return true;
2970 }
2971
toJSON(UrlDataManager & urlDataManager) const2972 Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
2973 Json::Value result = INHERITED::toJSON(urlDataManager);
2974 Json::Value runs(Json::arrayValue);
2975 SkTextBlobRunIterator iter(fBlob.get());
2976 while (!iter.done()) {
2977 Json::Value run(Json::objectValue);
2978 Json::Value jsonPositions(Json::arrayValue);
2979 Json::Value jsonGlyphs(Json::arrayValue);
2980 const SkScalar* iterPositions = iter.pos();
2981 const uint16_t* iterGlyphs = iter.glyphs();
2982 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
2983 switch (iter.positioning()) {
2984 case SkTextBlob::kFull_Positioning:
2985 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
2986 iterPositions[i * 2 + 1]));
2987 break;
2988 case SkTextBlob::kHorizontal_Positioning:
2989 jsonPositions.append(Json::Value(iterPositions[i]));
2990 break;
2991 case SkTextBlob::kDefault_Positioning:
2992 break;
2993 }
2994 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
2995 }
2996 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
2997 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
2998 }
2999 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
3000 SkPaint fontPaint;
3001 iter.applyFontToPaint(&fontPaint);
3002 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
3003 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
3004 runs.append(run);
3005 iter.next();
3006 }
3007 SkRect bounds = fBlob->bounds();
3008 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
3009 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
3010 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
3011 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
3012 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3013
3014 SkString desc;
3015 // make the bounds local by applying the x,y
3016 bounds.offset(fXPos, fYPos);
3017 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
3018
3019 return result;
3020 }
3021
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3022 SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
3023 UrlDataManager& urlDataManager) {
3024 SkTextBlobBuilder builder;
3025 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
3026 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
3027 Json::Value run = runs[i];
3028 SkPaint font;
3029 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
3030 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
3031 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
3032 int count = glyphs.size();
3033 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3034 SkScalar x = coords[0].asFloat();
3035 SkScalar y = coords[1].asFloat();
3036 SkRect bounds;
3037 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
3038
3039 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
3040 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3041 if (positions.size() > 0 && positions[0].isNumeric()) {
3042 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
3043 for (int j = 0; j < count; j++) {
3044 buffer.glyphs[j] = glyphs[j].asUInt();
3045 buffer.pos[j] = positions[j].asFloat();
3046 }
3047 }
3048 else {
3049 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
3050 for (int j = 0; j < count; j++) {
3051 buffer.glyphs[j] = glyphs[j].asUInt();
3052 buffer.pos[j * 2] = positions[j][0].asFloat();
3053 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
3054 }
3055 }
3056 }
3057 else {
3058 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
3059 for (int j = 0; j < count; j++) {
3060 buffer.glyphs[j] = glyphs[j].asUInt();
3061 }
3062 }
3063 }
3064 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
3065 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3066 SkPaint paint;
3067 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3068 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
3069 }
3070
SkDrawPatchCommand(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode bmode,const SkPaint & paint)3071 SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
3072 const SkPoint texCoords[4], SkBlendMode bmode,
3073 const SkPaint& paint)
3074 : INHERITED(kDrawPatch_OpType)
3075 , fBlendMode(bmode)
3076 {
3077 memcpy(fCubics, cubics, sizeof(fCubics));
3078 if (colors != nullptr) {
3079 memcpy(fColors, colors, sizeof(fColors));
3080 fColorsPtr = fColors;
3081 } else {
3082 fColorsPtr = nullptr;
3083 }
3084 if (texCoords != nullptr) {
3085 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3086 fTexCoordsPtr = fTexCoords;
3087 } else {
3088 fTexCoordsPtr = nullptr;
3089 }
3090 fPaint = paint;
3091
3092 fInfo.push(SkObjectParser::PaintToString(paint));
3093 }
3094
execute(SkCanvas * canvas) const3095 void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
3096 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
3097 }
3098
toJSON(UrlDataManager & urlDataManager) const3099 Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3100 Json::Value result = INHERITED::toJSON(urlDataManager);
3101 Json::Value cubics = Json::Value(Json::arrayValue);
3102 for (int i = 0; i < 12; i++) {
3103 cubics.append(MakeJsonPoint(fCubics[i]));
3104 }
3105 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3106 if (fColorsPtr != nullptr) {
3107 Json::Value colors = Json::Value(Json::arrayValue);
3108 for (int i = 0; i < 4; i++) {
3109 colors.append(MakeJsonColor(fColorsPtr[i]));
3110 }
3111 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3112 }
3113 if (fTexCoordsPtr != nullptr) {
3114 Json::Value texCoords = Json::Value(Json::arrayValue);
3115 for (int i = 0; i < 4; i++) {
3116 texCoords.append(MakeJsonPoint(fTexCoords[i]));
3117 }
3118 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3119 }
3120 // fBlendMode
3121 return result;
3122 }
3123
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3124 SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
3125 UrlDataManager& urlDataManager) {
3126 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3127 SkPoint cubics[12];
3128 for (int i = 0; i < 12; i++) {
3129 cubics[i] = get_json_point(jsonCubics[i]);
3130 }
3131 SkColor* colorsPtr;
3132 SkColor colors[4];
3133 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3134 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3135 for (int i = 0; i < 4; i++) {
3136 colors[i] = get_json_color(jsonColors[i]);
3137 }
3138 colorsPtr = colors;
3139 }
3140 else {
3141 colorsPtr = nullptr;
3142 }
3143 SkPoint* texCoordsPtr;
3144 SkPoint texCoords[4];
3145 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3146 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3147 for (int i = 0; i < 4; i++) {
3148 texCoords[i] = get_json_point(jsonTexCoords[i]);
3149 }
3150 texCoordsPtr = texCoords;
3151 }
3152 else {
3153 texCoordsPtr = nullptr;
3154 }
3155
3156 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3157
3158 SkPaint paint;
3159 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3160 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
3161 }
3162
SkDrawRectCommand(const SkRect & rect,const SkPaint & paint)3163 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
3164 : INHERITED(kDrawRect_OpType) {
3165 fRect = rect;
3166 fPaint = paint;
3167
3168 fInfo.push(SkObjectParser::RectToString(rect));
3169 fInfo.push(SkObjectParser::PaintToString(paint));
3170 }
3171
execute(SkCanvas * canvas) const3172 void SkDrawRectCommand::execute(SkCanvas* canvas) const {
3173 canvas->drawRect(fRect, fPaint);
3174 }
3175
toJSON(UrlDataManager & urlDataManager) const3176 Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3177 Json::Value result = INHERITED::toJSON(urlDataManager);
3178 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3179 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3180
3181 SkString desc;
3182 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3183
3184 return result;
3185 }
3186
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3187 SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
3188 UrlDataManager& urlDataManager) {
3189 SkRect coords;
3190 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3191 SkPaint paint;
3192 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3193 return new SkDrawRectCommand(coords, paint);
3194 }
3195
SkDrawRRectCommand(const SkRRect & rrect,const SkPaint & paint)3196 SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
3197 : INHERITED(kDrawRRect_OpType) {
3198 fRRect = rrect;
3199 fPaint = paint;
3200
3201 fInfo.push(SkObjectParser::RRectToString(rrect));
3202 fInfo.push(SkObjectParser::PaintToString(paint));
3203 }
3204
execute(SkCanvas * canvas) const3205 void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
3206 canvas->drawRRect(fRRect, fPaint);
3207 }
3208
render(SkCanvas * canvas) const3209 bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
3210 render_rrect(canvas, fRRect);
3211 return true;
3212 }
3213
toJSON(UrlDataManager & urlDataManager) const3214 Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3215 Json::Value result = INHERITED::toJSON(urlDataManager);
3216 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
3217 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3218 return result;
3219 }
3220
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3221 SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
3222 UrlDataManager& urlDataManager) {
3223 SkRRect coords;
3224 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3225 SkPaint paint;
3226 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3227 return new SkDrawRRectCommand(coords, paint);
3228 }
3229
SkDrawDRRectCommand(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)3230 SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
3231 const SkRRect& inner,
3232 const SkPaint& paint)
3233 : INHERITED(kDrawDRRect_OpType) {
3234 fOuter = outer;
3235 fInner = inner;
3236 fPaint = paint;
3237
3238 fInfo.push(SkObjectParser::RRectToString(outer));
3239 fInfo.push(SkObjectParser::RRectToString(inner));
3240 fInfo.push(SkObjectParser::PaintToString(paint));
3241 }
3242
execute(SkCanvas * canvas) const3243 void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
3244 canvas->drawDRRect(fOuter, fInner, fPaint);
3245 }
3246
render(SkCanvas * canvas) const3247 bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3248 render_drrect(canvas, fOuter, fInner);
3249 return true;
3250 }
3251
toJSON(UrlDataManager & urlDataManager) const3252 Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3253 Json::Value result = INHERITED::toJSON(urlDataManager);
3254 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3255 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
3256 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3257 return result;
3258 }
3259
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3260 SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
3261 UrlDataManager& urlDataManager) {
3262 SkRRect outer;
3263 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3264 SkRRect inner;
3265 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3266 SkPaint paint;
3267 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3268 return new SkDrawDRRectCommand(outer, inner, paint);
3269 }
3270
SkDrawTextCommand(const void * text,size_t byteLength,SkScalar x,SkScalar y,const SkPaint & paint)3271 SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
3272 const SkPaint& paint)
3273 : INHERITED(kDrawText_OpType) {
3274 fText = new char[byteLength];
3275 memcpy(fText, text, byteLength);
3276 fByteLength = byteLength;
3277 fX = x;
3278 fY = y;
3279 fPaint = paint;
3280
3281 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3282 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
3283 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
3284 fInfo.push(SkObjectParser::PaintToString(paint));
3285 }
3286
execute(SkCanvas * canvas) const3287 void SkDrawTextCommand::execute(SkCanvas* canvas) const {
3288 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
3289 }
3290
toJSON(UrlDataManager & urlDataManager) const3291 Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3292 Json::Value result = INHERITED::toJSON(urlDataManager);
3293 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3294 ((const char*) fText) + fByteLength);
3295 Json::Value coords(Json::arrayValue);
3296 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3297 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3298 return result;
3299 }
3300
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3301 SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
3302 UrlDataManager& urlDataManager) {
3303 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3304 SkPaint paint;
3305 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3306 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3307 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
3308 paint);
3309 }
3310
3311 ///////////////////////////////////////////////////////////////////////////////////////////////////
3312
SkDrawTextOnPathCommand(const void * text,size_t byteLength,const SkPath & path,const SkMatrix * matrix,const SkPaint & paint)3313 SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3314 const SkPath& path, const SkMatrix* matrix,
3315 const SkPaint& paint)
3316 : INHERITED(kDrawTextOnPath_OpType) {
3317 fText = new char[byteLength];
3318 memcpy(fText, text, byteLength);
3319 fByteLength = byteLength;
3320 fPath = path;
3321 if (matrix) {
3322 fMatrix = *matrix;
3323 } else {
3324 fMatrix.setIdentity();
3325 }
3326 fPaint = paint;
3327
3328 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3329 fInfo.push(SkObjectParser::PathToString(path));
3330 if (matrix) {
3331 fInfo.push(SkObjectParser::MatrixToString(*matrix));
3332 }
3333 fInfo.push(SkObjectParser::PaintToString(paint));
3334 }
3335
execute(SkCanvas * canvas) const3336 void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
3337 canvas->drawTextOnPath(fText, fByteLength, fPath,
3338 fMatrix.isIdentity() ? nullptr : &fMatrix,
3339 fPaint);
3340 }
3341
toJSON(UrlDataManager & urlDataManager) const3342 Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3343 Json::Value result = INHERITED::toJSON(urlDataManager);
3344 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3345 ((const char*) fText) + fByteLength);
3346 Json::Value coords(Json::arrayValue);
3347 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3348 if (!fMatrix.isIdentity()) {
3349 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
3350 }
3351 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3352 return result;
3353 }
3354
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3355 SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
3356 UrlDataManager& urlDataManager) {
3357 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3358 SkPaint paint;
3359 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3360 SkPath path;
3361 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3362 SkMatrix* matrixPtr;
3363 SkMatrix matrix;
3364 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3365 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3366 matrixPtr = &matrix;
3367 }
3368 else {
3369 matrixPtr = nullptr;
3370 }
3371 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3372 }
3373
3374 ///////////////////////////////////////////////////////////////////////////////////////////////////
3375
SkDrawTextRSXformCommand(const void * text,size_t byteLength,const SkRSXform xform[],const SkRect * cull,const SkPaint & paint)3376 SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3377 const SkRSXform xform[], const SkRect* cull,
3378 const SkPaint& paint)
3379 : INHERITED(kDrawTextRSXform_OpType)
3380 {
3381 fText = new char[byteLength];
3382 memcpy(fText, text, byteLength);
3383 fByteLength = byteLength;
3384 int count = paint.countText(text, byteLength);
3385 fXform = new SkRSXform[count];
3386 memcpy(fXform, xform, count * sizeof(SkRSXform));
3387 if (cull) {
3388 fCullStorage = *cull;
3389 fCull = &fCullStorage;
3390 } else {
3391 fCull = nullptr;
3392 }
3393 fPaint = paint;
3394
3395 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3396 fInfo.push(SkObjectParser::PaintToString(paint));
3397 }
3398
execute(SkCanvas * canvas) const3399 void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3400 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3401 }
3402
toJSON(UrlDataManager & urlDataManager) const3403 Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3404 Json::Value result = INHERITED::toJSON(urlDataManager);
3405 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3406 ((const char*) fText) + fByteLength);
3407 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3408 return result;
3409 }
3410
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3411 SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3412 UrlDataManager& urlDataManager) {
3413 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3414 size_t byteLength = strlen(text);
3415 SkPaint paint;
3416 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3417
3418 // TODO: handle xform and cull
3419 int count = paint.countText(text, byteLength);
3420 SkAutoTArray<SkRSXform> xform(count);
3421 for (int i = 0; i < count; ++i) {
3422 xform[i].fSCos = 1;
3423 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3424 }
3425 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3426 }
3427
3428 ///////////////////////////////////////////////////////////////////////////////////////////////////
3429
SkDrawVerticesCommand(sk_sp<SkVertices> vertices,SkBlendMode bmode,const SkPaint & paint)3430 SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
3431 const SkPaint& paint)
3432 : INHERITED(kDrawVertices_OpType)
3433 , fVertices(std::move(vertices))
3434 , fBlendMode(bmode)
3435 , fPaint(paint)
3436 {
3437 // TODO(chudy)
3438 fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
3439 fInfo.push(SkObjectParser::PaintToString(paint));
3440 }
3441
execute(SkCanvas * canvas) const3442 void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
3443 canvas->drawVertices(fVertices, fBlendMode, fPaint);
3444 }
3445
SkRestoreCommand()3446 SkRestoreCommand::SkRestoreCommand()
3447 : INHERITED(kRestore_OpType) {
3448 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
3449 }
3450
execute(SkCanvas * canvas) const3451 void SkRestoreCommand::execute(SkCanvas* canvas) const {
3452 canvas->restore();
3453 }
3454
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3455 SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
3456 return new SkRestoreCommand();
3457 }
3458
SkSaveCommand()3459 SkSaveCommand::SkSaveCommand()
3460 : INHERITED(kSave_OpType) {
3461 }
3462
execute(SkCanvas * canvas) const3463 void SkSaveCommand::execute(SkCanvas* canvas) const {
3464 canvas->save();
3465 }
3466
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3467 SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
3468 return new SkSaveCommand();
3469 }
3470
SkSaveLayerCommand(const SkCanvas::SaveLayerRec & rec)3471 SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
3472 : INHERITED(kSaveLayer_OpType) {
3473 if (rec.fBounds) {
3474 fBounds = *rec.fBounds;
3475 } else {
3476 fBounds.setEmpty();
3477 }
3478
3479 if (rec.fPaint) {
3480 fPaint = *rec.fPaint;
3481 fPaintPtr = &fPaint;
3482 } else {
3483 fPaintPtr = nullptr;
3484 }
3485 fSaveLayerFlags = rec.fSaveLayerFlags;
3486
3487 if (rec.fBackdrop) {
3488 fBackdrop = rec.fBackdrop;
3489 fBackdrop->ref();
3490 } else {
3491 fBackdrop = nullptr;
3492 }
3493
3494 if (rec.fBounds) {
3495 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
3496 }
3497 if (rec.fPaint) {
3498 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
3499 }
3500 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
3501 }
3502
~SkSaveLayerCommand()3503 SkSaveLayerCommand::~SkSaveLayerCommand() {
3504 if (fBackdrop != nullptr) {
3505 fBackdrop->unref();
3506 }
3507 }
3508
execute(SkCanvas * canvas) const3509 void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
3510 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3511 fPaintPtr,
3512 fSaveLayerFlags));
3513 }
3514
vizExecute(SkCanvas * canvas) const3515 void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
3516 canvas->save();
3517 }
3518
toJSON(UrlDataManager & urlDataManager) const3519 Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3520 Json::Value result = INHERITED::toJSON(urlDataManager);
3521 if (!fBounds.isEmpty()) {
3522 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
3523 }
3524 if (fPaintPtr != nullptr) {
3525 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
3526 urlDataManager);
3527 }
3528 if (fBackdrop != nullptr) {
3529 Json::Value jsonBackdrop;
3530 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
3531 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3532 }
3533 if (fSaveLayerFlags != 0) {
3534 SkDebugf("unsupported: saveLayer flags\n");
3535 SkASSERT(false);
3536 }
3537 return result;
3538 }
3539
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3540 SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
3541 UrlDataManager& urlDataManager) {
3542 SkCanvas::SaveLayerRec rec;
3543 SkRect bounds;
3544 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3545 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3546 rec.fBounds = &bounds;
3547 }
3548 SkPaint paint;
3549 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
3550 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3551 rec.fPaint = &paint;
3552 }
3553 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3554 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
3555 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
3556 }
3557 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3558 if (rec.fBackdrop != nullptr) {
3559 rec.fBackdrop->unref();
3560 }
3561 return result;
3562 }
3563
SkSetMatrixCommand(const SkMatrix & matrix)3564 SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
3565 : INHERITED(kSetMatrix_OpType) {
3566 fUserMatrix.reset();
3567 fMatrix = matrix;
3568 fInfo.push(SkObjectParser::MatrixToString(matrix));
3569 }
3570
setUserMatrix(const SkMatrix & userMatrix)3571 void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
3572 fUserMatrix = userMatrix;
3573 }
3574
execute(SkCanvas * canvas) const3575 void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
3576 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
3577 canvas->setMatrix(temp);
3578 }
3579
toJSON(UrlDataManager & urlDataManager) const3580 Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3581 Json::Value result = INHERITED::toJSON(urlDataManager);
3582 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
3583 return result;
3584 }
3585
fromJSON(Json::Value & command,UrlDataManager & urlDataManager)3586 SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
3587 UrlDataManager& urlDataManager) {
3588 SkMatrix matrix;
3589 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3590 return new SkSetMatrixCommand(matrix);
3591 }
3592