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 <algorithm>
11 #include "SkAutoMalloc.h"
12 #include "SkCanvasPriv.h"
13 #include "SkClipOpPriv.h"
14 #include "SkColorFilter.h"
15 #include "SkDashPathEffect.h"
16 #include "SkDrawable.h"
17 #include "SkImageFilter.h"
18 #include "SkJsonWriteBuffer.h"
19 #include "SkLatticeIter.h"
20 #include "SkMaskFilterBase.h"
21 #include "SkPaintDefaults.h"
22 #include "SkPathEffect.h"
23 #include "SkPicture.h"
24 #include "SkPngEncoder.h"
25 #include "SkReadBuffer.h"
26 #include "SkRectPriv.h"
27 #include "SkShadowFlags.h"
28 #include "SkTHash.h"
29 #include "SkTextBlobPriv.h"
30 #include "SkTypeface.h"
31 #include "SkWriteBuffer.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_EDGING "edging"
39 #define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
40 #define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
41 #define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
42 #define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
43 #define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
44 #define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
45 #define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
46 #define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
47 #define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
48 #define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
49 #define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
50 #define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
51 #define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
52 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
53 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
54 #define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
55 #define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
56 #define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
57 #define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
58 #define SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
59 #define SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
60 #define SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
61 #define SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
62 #define SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
63 #define SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
64 #define SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
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_TEXTSIZE "textSize"
73 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
74 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
75 #define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
76 #define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
77 #define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
78 #define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
79 #define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
80 #define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
81 #define SKDEBUGCANVAS_ATTRIBUTE_DATA "data"
82 #define SKDEBUGCANVAS_ATTRIBUTE_VALUES "values"
83 #define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
84 #define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
85 #define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
86 #define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
87 #define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
88 #define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
89 #define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
90 #define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
91 #define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
92 #define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
93 #define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
94 #define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
95 #define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
96 #define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
97 #define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
98 #define SKDEBUGCANVAS_ATTRIBUTE_X "x"
99 #define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
100 #define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
101 #define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
102 #define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
103 #define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
104 #define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
105 #define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
106 #define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors"
107 #define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
108 #define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
109 #define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
110 #define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
111 #define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
112 #define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
113 #define SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
114 #define SKDEBUGCANVAS_ATTRIBUTE_WIDTH "width"
115 #define SKDEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
116 #define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
117 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
118 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
119 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
120 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
121 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
122 #define SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
123 #define SKDEBUGCANVAS_ATTRIBUTE_ZPLANE "zPlane"
124 #define SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION "lightPositions"
125 #define SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR "ambientColor"
126 #define SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR "spotColor"
127 #define SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS "lightRadius"
128
129 #define SKDEBUGCANVAS_VERB_MOVE "move"
130 #define SKDEBUGCANVAS_VERB_LINE "line"
131 #define SKDEBUGCANVAS_VERB_QUAD "quad"
132 #define SKDEBUGCANVAS_VERB_CUBIC "cubic"
133 #define SKDEBUGCANVAS_VERB_CONIC "conic"
134 #define SKDEBUGCANVAS_VERB_CLOSE "close"
135
136 #define SKDEBUGCANVAS_STYLE_FILL "fill"
137 #define SKDEBUGCANVAS_STYLE_STROKE "stroke"
138 #define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
139
140 #define SKDEBUGCANVAS_POINTMODE_POINTS "points"
141 #define SKDEBUGCANVAS_POINTMODE_LINES "lines"
142 #define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
143
144 #define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
145 #define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
146 #define SKDEBUGCANVAS_REGIONOP_UNION "union"
147 #define SKDEBUGCANVAS_REGIONOP_XOR "xor"
148 #define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
149 #define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
150
151 #define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
152 #define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
153 #define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
154 #define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
155
156 #define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
157 #define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
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 #define SKDEBUGCANVAS_EDGING_ALIAS "alias"
196 #define SKDEBUGCANVAS_EDGING_ANTIALIAS "antialias"
197 #define SKDEBUGCANVAS_EDGING_SUBPIXELANTIALIAS "subpixelantialias"
198
199 #define SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC "transparentOccluder"
200 #define SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY "geometricOnly"
201
str_append(SkString * str,const SkRect & r)202 static SkString* str_append(SkString* str, const SkRect& r) {
203 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
204 return str;
205 }
206
SkDrawCommand(OpType type)207 SkDrawCommand::SkDrawCommand(OpType type)
208 : fOpType(type)
209 , fVisible(true) {
210 }
211
GetCommandString(OpType type)212 const char* SkDrawCommand::GetCommandString(OpType type) {
213 switch (type) {
214 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
215 case kClear_OpType: return "DrawClear";
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 kDrawBitmapLattice_OpType: return "DrawBitmapLattice";
224 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
225 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
226 case kDrawDRRect_OpType: return "DrawDRRect";
227 case kDrawImage_OpType: return "DrawImage";
228 case kDrawImageLattice_OpType: return "DrawImageLattice";
229 case kDrawImageNine_OpType: return "DrawImageNine";
230 case kDrawImageRect_OpType: return "DrawImageRect";
231 case kDrawImageSet_OpType: return "DrawImageSet";
232 case kDrawOval_OpType: return "DrawOval";
233 case kDrawPaint_OpType: return "DrawPaint";
234 case kDrawPatch_OpType: return "DrawPatch";
235 case kDrawPath_OpType: return "DrawPath";
236 case kDrawArc_OpType: return "DrawArc";
237 case kDrawPoints_OpType: return "DrawPoints";
238 case kDrawRect_OpType: return "DrawRect";
239 case kDrawRRect_OpType: return "DrawRRect";
240 case kDrawRegion_OpType: return "DrawRegion";
241 case kDrawShadow_OpType: return "DrawShadow";
242 case kDrawTextBlob_OpType: return "DrawTextBlob";
243 case kDrawVertices_OpType: return "DrawVertices";
244 case kDrawAtlas_OpType: return "DrawAtlas";
245 case kDrawDrawable_OpType: return "DrawDrawable";
246 case kEndDrawPicture_OpType: return "EndDrawPicture";
247 case kRestore_OpType: return "Restore";
248 case kSave_OpType: return "Save";
249 case kSaveLayer_OpType: return "SaveLayer";
250 case kSetMatrix_OpType: return "SetMatrix";
251 default:
252 SkDebugf("OpType error 0x%08x\n", type);
253 SkASSERT(0);
254 break;
255 }
256 SkDEBUGFAIL("DrawType UNUSED\n");
257 return nullptr;
258 }
259
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const260 void SkDrawCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
261 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_COMMAND, this->GetCommandString(fOpType));
262 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_VISIBLE, this->isVisible());
263 }
264
265 namespace {
266
xlate_and_scale_to_bounds(SkCanvas * canvas,const SkRect & bounds)267 void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
268 const SkISize& size = canvas->getBaseLayerSize();
269
270 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
271
272 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
273 if (bounds.width() > bounds.height()) {
274 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
275 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
276 } else {
277 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
278 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
279 }
280 canvas->translate(-bounds.centerX(), -bounds.centerY());
281 }
282
283
render_path(SkCanvas * canvas,const SkPath & path)284 void render_path(SkCanvas* canvas, const SkPath& path) {
285 canvas->clear(0xFFFFFFFF);
286
287 const SkRect& bounds = path.getBounds();
288 if (bounds.isEmpty()) {
289 return;
290 }
291
292 SkAutoCanvasRestore acr(canvas, true);
293 xlate_and_scale_to_bounds(canvas, bounds);
294
295 SkPaint p;
296 p.setColor(SK_ColorBLACK);
297 p.setStyle(SkPaint::kStroke_Style);
298
299 canvas->drawPath(path, p);
300 }
301
render_region(SkCanvas * canvas,const SkRegion & region)302 void render_region(SkCanvas* canvas, const SkRegion& region) {
303 canvas->clear(0xFFFFFFFF);
304
305 const SkIRect& bounds = region.getBounds();
306 if (bounds.isEmpty()) {
307 return;
308 }
309
310 SkAutoCanvasRestore acr(canvas, true);
311 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
312
313 SkPaint p;
314 p.setColor(SK_ColorBLACK);
315 p.setStyle(SkPaint::kStroke_Style);
316
317 canvas->drawRegion(region, p);
318 }
319
render_bitmap(SkCanvas * canvas,const SkBitmap & input,const SkRect * srcRect=nullptr)320 void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
321 const SkISize& size = canvas->getBaseLayerSize();
322
323 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
324 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
325
326 if (input.width() > input.height()) {
327 yScale *= input.height() / (float) input.width();
328 } else {
329 xScale *= input.width() / (float) input.height();
330 }
331
332 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
333 xScale * input.width(),
334 yScale * input.height());
335
336 static const int kNumBlocks = 8;
337
338 canvas->clear(0xFFFFFFFF);
339 SkISize block = {
340 canvas->imageInfo().width()/kNumBlocks,
341 canvas->imageInfo().height()/kNumBlocks
342 };
343 for (int y = 0; y < kNumBlocks; ++y) {
344 for (int x = 0; x < kNumBlocks; ++x) {
345 SkPaint paint;
346 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
347 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
348 SkIntToScalar(y*block.height()),
349 SkIntToScalar(block.width()),
350 SkIntToScalar(block.height()));
351 canvas->drawRect(r, paint);
352 }
353 }
354
355 canvas->drawBitmapRect(input, dst, nullptr);
356
357 if (srcRect) {
358 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
359 srcRect->fTop * yScale + SK_Scalar1,
360 srcRect->fRight * xScale + SK_Scalar1,
361 srcRect->fBottom * yScale + SK_Scalar1);
362 SkPaint p;
363 p.setColor(SK_ColorRED);
364 p.setStyle(SkPaint::kStroke_Style);
365
366 canvas->drawRect(r, p);
367 }
368 }
369
render_rrect(SkCanvas * canvas,const SkRRect & rrect)370 void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
371 canvas->clear(0xFFFFFFFF);
372 canvas->save();
373
374 const SkRect& bounds = rrect.getBounds();
375
376 xlate_and_scale_to_bounds(canvas, bounds);
377
378 SkPaint p;
379 p.setColor(SK_ColorBLACK);
380 p.setStyle(SkPaint::kStroke_Style);
381
382 canvas->drawRRect(rrect, p);
383 canvas->restore();
384 }
385
render_drrect(SkCanvas * canvas,const SkRRect & outer,const SkRRect & inner)386 void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
387 canvas->clear(0xFFFFFFFF);
388 canvas->save();
389
390 const SkRect& bounds = outer.getBounds();
391
392 xlate_and_scale_to_bounds(canvas, bounds);
393
394 SkPaint p;
395 p.setColor(SK_ColorBLACK);
396 p.setStyle(SkPaint::kStroke_Style);
397
398 canvas->drawDRRect(outer, inner, p);
399 canvas->restore();
400 }
401
render_shadow(SkCanvas * canvas,const SkPath & path,SkDrawShadowRec rec)402 void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
403 canvas->clear(0xFFFFFFFF);
404
405 const SkRect& bounds = path.getBounds();
406 if (bounds.isEmpty()) {
407 return;
408 }
409
410 SkAutoCanvasRestore acr(canvas, true);
411 xlate_and_scale_to_bounds(canvas, bounds);
412
413 rec.fAmbientColor = SK_ColorBLACK;
414 rec.fSpotColor = SK_ColorBLACK;
415 canvas->private_draw_shadow_rec(path, rec);
416 }
417
418 static const char* const gBlendModeMap[] = {
419 "clear",
420 "src",
421 "dst",
422 "srcOver",
423 "dstOver",
424 "srcIn",
425 "dstIn",
426 "srcOut",
427 "dstOut",
428 "srcATop",
429 "dstATop",
430 "xor",
431 "plus",
432 "modulate",
433
434 "screen",
435
436 "overlay",
437 "darken",
438 "lighten",
439 "colorDodge",
440 "colorBurn",
441 "hardLight",
442 "softLight",
443 "difference",
444 "exclusion",
445 "multiply",
446
447 "hue",
448 "saturation",
449 "color",
450 "luminosity",
451 };
452
453 static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
454 "blendMode mismatch");
455 static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
456 "blendMode mismatch");
457
apply_paint_blend_mode(const SkPaint & paint,SkJSONWriter & writer)458 void apply_paint_blend_mode(const SkPaint& paint, SkJSONWriter& writer) {
459 const auto mode = paint.getBlendMode();
460 if (mode != SkBlendMode::kSrcOver) {
461 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
462 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE,
463 gBlendModeMap[static_cast<size_t>(mode)]);
464 }
465 }
466
467 };
468
MakeJsonColor(SkJSONWriter & writer,const SkColor color)469 void SkDrawCommand::MakeJsonColor(SkJSONWriter& writer, const SkColor color) {
470 writer.beginArray(nullptr, false);
471 writer.appendS32(SkColorGetA(color));
472 writer.appendS32(SkColorGetR(color));
473 writer.appendS32(SkColorGetG(color));
474 writer.appendS32(SkColorGetB(color));
475 writer.endArray();
476 }
477
MakeJsonColor4f(SkJSONWriter & writer,const SkColor4f & color)478 void SkDrawCommand::MakeJsonColor4f(SkJSONWriter& writer, const SkColor4f& color) {
479 writer.beginArray(nullptr, false);
480 writer.appendFloat(color.fA);
481 writer.appendFloat(color.fR);
482 writer.appendFloat(color.fG);
483 writer.appendFloat(color.fB);
484 writer.endArray();
485 }
486
MakeJsonPoint(SkJSONWriter & writer,const SkPoint & point)487 void SkDrawCommand::MakeJsonPoint(SkJSONWriter& writer, const SkPoint& point) {
488 writer.beginArray(nullptr, false);
489 writer.appendFloat(point.x());
490 writer.appendFloat(point.y());
491 writer.endArray();
492 }
493
MakeJsonPoint(SkJSONWriter & writer,SkScalar x,SkScalar y)494 void SkDrawCommand::MakeJsonPoint(SkJSONWriter& writer, SkScalar x, SkScalar y) {
495 writer.beginArray(nullptr, false);
496 writer.appendFloat(x);
497 writer.appendFloat(y);
498 writer.endArray();
499 }
500
MakeJsonPoint3(SkJSONWriter & writer,const SkPoint3 & point)501 void SkDrawCommand::MakeJsonPoint3(SkJSONWriter& writer, const SkPoint3& point) {
502 writer.beginArray(nullptr, false);
503 writer.appendFloat(point.x());
504 writer.appendFloat(point.y());
505 writer.appendFloat(point.z());
506 writer.endArray();
507 }
508
MakeJsonRect(SkJSONWriter & writer,const SkRect & rect)509 void SkDrawCommand::MakeJsonRect(SkJSONWriter& writer, const SkRect& rect) {
510 writer.beginArray(nullptr, false);
511 writer.appendFloat(rect.left());
512 writer.appendFloat(rect.top());
513 writer.appendFloat(rect.right());
514 writer.appendFloat(rect.bottom());
515 writer.endArray();
516 }
517
MakeJsonIRect(SkJSONWriter & writer,const SkIRect & rect)518 void SkDrawCommand::MakeJsonIRect(SkJSONWriter& writer, const SkIRect& rect) {
519 writer.beginArray(nullptr, false);
520 writer.appendS32(rect.left());
521 writer.appendS32(rect.top());
522 writer.appendS32(rect.right());
523 writer.appendS32(rect.bottom());
524 writer.endArray();
525 }
526
make_json_rrect(SkJSONWriter & writer,const SkRRect & rrect)527 static void make_json_rrect(SkJSONWriter& writer, const SkRRect& rrect) {
528 writer.beginArray(nullptr, false);
529 SkDrawCommand::MakeJsonRect(writer, rrect.rect());
530 SkDrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperLeft_Corner));
531 SkDrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperRight_Corner));
532 SkDrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerRight_Corner));
533 SkDrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerLeft_Corner));
534 writer.endArray();
535 }
536
MakeJsonMatrix(SkJSONWriter & writer,const SkMatrix & matrix)537 void SkDrawCommand::MakeJsonMatrix(SkJSONWriter& writer, const SkMatrix& matrix) {
538 writer.beginArray();
539 for (int r = 0; r < 3; ++r) {
540 writer.beginArray(nullptr, false);
541 for (int c = 0; c < 3; ++c) {
542 writer.appendFloat(matrix[r * 3 + c]);
543 }
544 writer.endArray();
545 }
546 writer.endArray();
547 }
548
MakeJsonPath(SkJSONWriter & writer,const SkPath & path)549 void SkDrawCommand::MakeJsonPath(SkJSONWriter& writer, const SkPath& path) {
550 writer.beginObject();
551 switch (path.getFillType()) {
552 case SkPath::kWinding_FillType:
553 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE, SKDEBUGCANVAS_FILLTYPE_WINDING);
554 break;
555 case SkPath::kEvenOdd_FillType:
556 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE, SKDEBUGCANVAS_FILLTYPE_EVENODD);
557 break;
558 case SkPath::kInverseWinding_FillType:
559 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING);
560 break;
561 case SkPath::kInverseEvenOdd_FillType:
562 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD);
563 break;
564 }
565 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_VERBS);
566 SkPath::Iter iter(path, false);
567 SkPoint pts[4];
568 SkPath::Verb verb;
569 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
570 if (verb == SkPath::kClose_Verb) {
571 writer.appendString(SKDEBUGCANVAS_VERB_CLOSE);
572 continue;
573 }
574 writer.beginObject(); // verb
575 switch (verb) {
576 case SkPath::kLine_Verb: {
577 writer.appendName(SKDEBUGCANVAS_VERB_LINE);
578 MakeJsonPoint(writer, pts[1]);
579 break;
580 }
581 case SkPath::kQuad_Verb: {
582 writer.beginArray(SKDEBUGCANVAS_VERB_QUAD);
583 MakeJsonPoint(writer, pts[1]);
584 MakeJsonPoint(writer, pts[2]);
585 writer.endArray(); // quad coords
586 break;
587 }
588 case SkPath::kCubic_Verb: {
589 writer.beginArray(SKDEBUGCANVAS_VERB_CUBIC);
590 MakeJsonPoint(writer, pts[1]);
591 MakeJsonPoint(writer, pts[2]);
592 MakeJsonPoint(writer, pts[3]);
593 writer.endArray(); // cubic coords
594 break;
595 }
596 case SkPath::kConic_Verb: {
597 writer.beginArray(SKDEBUGCANVAS_VERB_CONIC);
598 MakeJsonPoint(writer, pts[1]);
599 MakeJsonPoint(writer, pts[2]);
600 writer.appendFloat(iter.conicWeight());
601 writer.endArray(); // conic coords
602 break;
603 }
604 case SkPath::kMove_Verb: {
605 writer.appendName(SKDEBUGCANVAS_VERB_MOVE);
606 MakeJsonPoint(writer, pts[0]);
607 break;
608 }
609 case SkPath::kClose_Verb:
610 case SkPath::kDone_Verb:
611 // Unreachable
612 break;
613 }
614 writer.endObject(); // verb
615 }
616 writer.endArray(); // verbs
617 writer.endObject(); // path
618 }
619
MakeJsonRegion(SkJSONWriter & writer,const SkRegion & region)620 void SkDrawCommand::MakeJsonRegion(SkJSONWriter& writer, const SkRegion& region) {
621 // TODO: Actually serialize the rectangles, rather than just devolving to path
622 SkPath path;
623 region.getBoundaryPath(&path);
624 MakeJsonPath(writer, path);
625 }
626
regionop_name(SkClipOp op)627 static const char* regionop_name(SkClipOp op) {
628 switch (op) {
629 case kDifference_SkClipOp:
630 return SKDEBUGCANVAS_REGIONOP_DIFFERENCE;
631 case kIntersect_SkClipOp:
632 return SKDEBUGCANVAS_REGIONOP_INTERSECT;
633 case kUnion_SkClipOp:
634 return SKDEBUGCANVAS_REGIONOP_UNION;
635 case kXOR_SkClipOp:
636 return SKDEBUGCANVAS_REGIONOP_XOR;
637 case kReverseDifference_SkClipOp:
638 return SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE;
639 case kReplace_SkClipOp:
640 return SKDEBUGCANVAS_REGIONOP_REPLACE;
641 default:
642 SkASSERT(false);
643 return "<invalid region op>";
644 }
645 }
646
pointmode_name(SkCanvas::PointMode mode)647 static const char* pointmode_name(SkCanvas::PointMode mode) {
648 switch (mode) {
649 case SkCanvas::kPoints_PointMode:
650 return SKDEBUGCANVAS_POINTMODE_POINTS;
651 case SkCanvas::kLines_PointMode:
652 return SKDEBUGCANVAS_POINTMODE_LINES;
653 case SkCanvas::kPolygon_PointMode:
654 return SKDEBUGCANVAS_POINTMODE_POLYGON;
655 default:
656 SkASSERT(false);
657 return "<invalid point mode>";
658 }
659 }
660
store_scalar(SkJSONWriter & writer,const char * key,SkScalar value,SkScalar defaultValue)661 static void store_scalar(SkJSONWriter& writer, const char* key, SkScalar value,
662 SkScalar defaultValue) {
663 if (value != defaultValue) {
664 writer.appendFloat(key, value);
665 }
666 }
667
store_bool(SkJSONWriter & writer,const char * key,bool value,bool defaultValue)668 static void store_bool(SkJSONWriter& writer,const char* key, bool value, bool defaultValue) {
669 if (value != defaultValue) {
670 writer.appendBool(key, value);
671 }
672 }
673
encode_data(const void * bytes,size_t count,const char * contentType,UrlDataManager & urlDataManager)674 static SkString encode_data(const void* bytes, size_t count, const char* contentType,
675 UrlDataManager& urlDataManager) {
676 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
677 return urlDataManager.addData(data.get(), contentType);
678 }
679
flatten(const SkFlattenable * flattenable,SkJSONWriter & writer,UrlDataManager & urlDataManager)680 void SkDrawCommand::flatten(const SkFlattenable* flattenable, SkJSONWriter& writer,
681 UrlDataManager& urlDataManager) {
682 SkBinaryWriteBuffer buffer;
683 flattenable->flatten(buffer);
684 void* data = sk_malloc_throw(buffer.bytesWritten());
685 buffer.writeToMemory(data);
686 SkString url = encode_data(data, buffer.bytesWritten(), "application/octet-stream",
687 urlDataManager);
688 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_NAME, flattenable->getTypeName());
689 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
690
691 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_VALUES);
692 SkJsonWriteBuffer jsonBuffer(&writer, &urlDataManager);
693 flattenable->flatten(jsonBuffer);
694 writer.endObject(); // values
695
696 sk_free(data);
697 }
698
WritePNG(SkBitmap bitmap,SkWStream & out)699 void SkDrawCommand::WritePNG(SkBitmap bitmap, SkWStream& out) {
700 SkPixmap pm;
701 SkAssertResult(bitmap.peekPixels(&pm));
702
703 SkPngEncoder::Options options;
704 options.fZLibLevel = 1;
705 options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
706 SkPngEncoder::Encode(&out, pm, options);
707 }
708
flatten(const SkImage & image,SkJSONWriter & writer,UrlDataManager & urlDataManager)709 bool SkDrawCommand::flatten(const SkImage& image, SkJSONWriter& writer,
710 UrlDataManager& urlDataManager) {
711 size_t rowBytes = 4 * image.width();
712 SkAutoMalloc buffer(rowBytes * image.height());
713 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
714 kN32_SkColorType, kPremul_SkAlphaType);
715 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
716 SkDebugf("readPixels failed\n");
717 return false;
718 }
719
720 SkBitmap bm;
721 bm.installPixels(dstInfo, buffer.get(), rowBytes);
722
723 SkDynamicMemoryWStream out;
724 SkDrawCommand::WritePNG(bm, out);
725 sk_sp<SkData> encoded = out.detachAsData();
726 SkString url = encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager);
727 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
728 return true;
729 }
730
color_type_name(SkColorType colorType)731 static const char* color_type_name(SkColorType colorType) {
732 switch (colorType) {
733 case kARGB_4444_SkColorType:
734 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
735 case kRGBA_8888_SkColorType:
736 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
737 case kBGRA_8888_SkColorType:
738 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
739 case kRGB_565_SkColorType:
740 return SKDEBUGCANVAS_COLORTYPE_565;
741 case kGray_8_SkColorType:
742 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
743 case kAlpha_8_SkColorType:
744 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
745 default:
746 SkASSERT(false);
747 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
748 }
749 }
750
alpha_type_name(SkAlphaType alphaType)751 static const char* alpha_type_name(SkAlphaType alphaType) {
752 switch (alphaType) {
753 case kOpaque_SkAlphaType:
754 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
755 case kPremul_SkAlphaType:
756 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
757 case kUnpremul_SkAlphaType:
758 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
759 default:
760 SkASSERT(false);
761 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
762 }
763 }
764
flatten(const SkBitmap & bitmap,SkJSONWriter & writer,UrlDataManager & urlDataManager)765 bool SkDrawCommand::flatten(const SkBitmap& bitmap, SkJSONWriter& writer,
766 UrlDataManager& urlDataManager) {
767 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
768 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_COLOR, color_type_name(bitmap.colorType()));
769 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_ALPHA, alpha_type_name(bitmap.alphaType()));
770 bool success = flatten(*image, writer, urlDataManager);
771 return success;
772 }
773
apply_font_hinting(const SkFont & font,SkJSONWriter & writer)774 static void apply_font_hinting(const SkFont& font, SkJSONWriter& writer) {
775 SkFontHinting hinting = font.getHinting();
776 if (hinting != SkPaintDefaults_Hinting) {
777 switch (hinting) {
778 case kNo_SkFontHinting:
779 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_HINTING, SKDEBUGCANVAS_HINTING_NONE);
780 break;
781 case kSlight_SkFontHinting:
782 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_HINTING, SKDEBUGCANVAS_HINTING_SLIGHT);
783 break;
784 case kNormal_SkFontHinting:
785 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_HINTING, SKDEBUGCANVAS_HINTING_NORMAL);
786 break;
787 case kFull_SkFontHinting:
788 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_HINTING, SKDEBUGCANVAS_HINTING_FULL);
789 break;
790 }
791 }
792 }
793
apply_font_edging(const SkFont & font,SkJSONWriter & writer)794 static void apply_font_edging(const SkFont& font, SkJSONWriter& writer) {
795 switch (font.getEdging()) {
796 case SkFont::Edging::kAlias:
797 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_EDGING, SKDEBUGCANVAS_EDGING_ALIAS);
798 break;
799 case SkFont::Edging::kAntiAlias:
800 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_EDGING, SKDEBUGCANVAS_EDGING_ANTIALIAS);
801 break;
802 case SkFont::Edging::kSubpixelAntiAlias:
803 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_EDGING, SKDEBUGCANVAS_EDGING_SUBPIXELANTIALIAS);
804 break;
805 }
806 }
807
apply_paint_color(const SkPaint & paint,SkJSONWriter & writer)808 static void apply_paint_color(const SkPaint& paint, SkJSONWriter& writer) {
809 SkColor color = paint.getColor();
810 if (color != SK_ColorBLACK) {
811 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COLOR);
812 SkDrawCommand::MakeJsonColor(writer, color);
813 }
814 }
815
apply_paint_style(const SkPaint & paint,SkJSONWriter & writer)816 static void apply_paint_style(const SkPaint& paint, SkJSONWriter& writer) {
817 SkPaint::Style style = paint.getStyle();
818 if (style != SkPaint::kFill_Style) {
819 switch (style) {
820 case SkPaint::kStroke_Style: {
821 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STYLE, SKDEBUGCANVAS_STYLE_STROKE);
822 break;
823 }
824 case SkPaint::kStrokeAndFill_Style: {
825 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STYLE, SKDEBUGCANVAS_STYLE_STROKEANDFILL);
826 break;
827 }
828 default: SkASSERT(false);
829 }
830 }
831 }
832
apply_paint_cap(const SkPaint & paint,SkJSONWriter & writer)833 static void apply_paint_cap(const SkPaint& paint, SkJSONWriter& writer) {
834 SkPaint::Cap cap = paint.getStrokeCap();
835 if (cap != SkPaint::kDefault_Cap) {
836 switch (cap) {
837 case SkPaint::kButt_Cap:
838 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_CAP, SKDEBUGCANVAS_CAP_BUTT);
839 break;
840 case SkPaint::kRound_Cap:
841 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_CAP, SKDEBUGCANVAS_CAP_ROUND);
842 break;
843 case SkPaint::kSquare_Cap:
844 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_CAP, SKDEBUGCANVAS_CAP_SQUARE);
845 break;
846 default: SkASSERT(false);
847 }
848 }
849 }
850
apply_paint_join(const SkPaint & paint,SkJSONWriter & writer)851 static void apply_paint_join(const SkPaint& paint, SkJSONWriter& writer) {
852 SkPaint::Join join = paint.getStrokeJoin();
853 if (join != SkPaint::kDefault_Join) {
854 switch (join) {
855 case SkPaint::kMiter_Join:
856 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN, SKDEBUGCANVAS_MITER_JOIN);
857 break;
858 case SkPaint::kRound_Join:
859 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN, SKDEBUGCANVAS_ROUND_JOIN);
860 break;
861 case SkPaint::kBevel_Join:
862 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN, SKDEBUGCANVAS_BEVEL_JOIN);
863 break;
864 default: SkASSERT(false);
865 }
866 }
867 }
868
apply_paint_filterquality(const SkPaint & paint,SkJSONWriter & writer)869 static void apply_paint_filterquality(const SkPaint& paint, SkJSONWriter& writer) {
870 SkFilterQuality quality = paint.getFilterQuality();
871 switch (quality) {
872 case kNone_SkFilterQuality:
873 break;
874 case kLow_SkFilterQuality:
875 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
876 SKDEBUGCANVAS_FILTERQUALITY_LOW);
877 break;
878 case kMedium_SkFilterQuality:
879 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
880 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
881 break;
882 case kHigh_SkFilterQuality:
883 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
884 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
885 break;
886 }
887 }
888
apply_paint_maskfilter(const SkPaint & paint,SkJSONWriter & writer,UrlDataManager & urlDataManager)889 static void apply_paint_maskfilter(const SkPaint& paint, SkJSONWriter& writer,
890 UrlDataManager& urlDataManager) {
891 SkMaskFilter* maskFilter = paint.getMaskFilter();
892 if (maskFilter != nullptr) {
893 SkMaskFilterBase::BlurRec blurRec;
894 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
895 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_BLUR);
896 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_SIGMA, blurRec.fSigma);
897 switch (blurRec.fStyle) {
898 case SkBlurStyle::kNormal_SkBlurStyle:
899 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STYLE,
900 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
901 break;
902 case SkBlurStyle::kSolid_SkBlurStyle:
903 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STYLE,
904 SKDEBUGCANVAS_BLURSTYLE_SOLID);
905 break;
906 case SkBlurStyle::kOuter_SkBlurStyle:
907 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STYLE,
908 SKDEBUGCANVAS_BLURSTYLE_OUTER);
909 break;
910 case SkBlurStyle::kInner_SkBlurStyle:
911 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_STYLE,
912 SKDEBUGCANVAS_BLURSTYLE_INNER);
913 break;
914 default:
915 SkASSERT(false);
916 }
917 writer.endObject(); // blur
918 } else {
919 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER);
920 SkDrawCommand::flatten(maskFilter, writer, urlDataManager);
921 writer.endObject(); // maskFilter
922 }
923 }
924 }
925
apply_paint_patheffect(const SkPaint & paint,SkJSONWriter & writer,UrlDataManager & urlDataManager)926 static void apply_paint_patheffect(const SkPaint& paint, SkJSONWriter& writer,
927 UrlDataManager& urlDataManager) {
928 SkPathEffect* pathEffect = paint.getPathEffect();
929 if (pathEffect != nullptr) {
930 SkPathEffect::DashInfo dashInfo;
931 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
932 if (dashType == SkPathEffect::kDash_DashType) {
933 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
934 pathEffect->asADash(&dashInfo);
935 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_DASHING);
936 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_INTERVALS, false);
937 for (int32_t i = 0; i < dashInfo.fCount; i++) {
938 writer.appendFloat(dashInfo.fIntervals[i]);
939 }
940 writer.endArray(); // intervals
941 sk_free(dashInfo.fIntervals);
942 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_PHASE, dashInfo.fPhase);
943 writer.endObject(); // dashing
944 } else {
945 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT);
946 SkDrawCommand::flatten(pathEffect, writer, urlDataManager);
947 writer.endObject(); // pathEffect
948 }
949 }
950 }
951
apply_font_typeface(const SkFont & font,SkJSONWriter & writer,UrlDataManager & urlDataManager)952 static void apply_font_typeface(const SkFont& font, SkJSONWriter& writer,
953 UrlDataManager& urlDataManager) {
954 SkTypeface* typeface = font.getTypefaceOrDefault();
955 if (typeface != nullptr) {
956 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE);
957 SkDynamicMemoryWStream buffer;
958 typeface->serialize(&buffer);
959 void* data = sk_malloc_throw(buffer.bytesWritten());
960 buffer.copyTo(data);
961 SkString url = encode_data(data, buffer.bytesWritten(), "application/octet-stream",
962 urlDataManager);
963 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
964 sk_free(data);
965 writer.endObject();
966 }
967 }
968
apply_flattenable(const char * key,SkFlattenable * flattenable,SkJSONWriter & writer,UrlDataManager & urlDataManager)969 static void apply_flattenable(const char* key, SkFlattenable* flattenable, SkJSONWriter& writer,
970 UrlDataManager& urlDataManager) {
971 if (flattenable != nullptr) {
972 writer.beginObject(key);
973 SkDrawCommand::flatten(flattenable, writer, urlDataManager);
974 writer.endObject();
975 }
976 }
977
MakeJsonPaint(SkJSONWriter & writer,const SkPaint & paint,UrlDataManager & urlDataManager)978 void SkDrawCommand::MakeJsonPaint(SkJSONWriter& writer, const SkPaint& paint,
979 UrlDataManager& urlDataManager) {
980 writer.beginObject();
981 store_scalar(writer, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
982 store_scalar(writer, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
983 SkPaintDefaults_MiterLimit);
984 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
985 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
986
987 apply_paint_color(paint, writer);
988 apply_paint_style(paint, writer);
989 apply_paint_blend_mode(paint, writer);
990 apply_paint_cap(paint, writer);
991 apply_paint_join(paint, writer);
992 apply_paint_filterquality(paint, writer);
993 apply_paint_patheffect(paint, writer, urlDataManager);
994 apply_paint_maskfilter(paint, writer, urlDataManager);
995 apply_flattenable(SKDEBUGCANVAS_ATTRIBUTE_SHADER, paint.getShader(), writer, urlDataManager);
996 apply_flattenable(SKDEBUGCANVAS_ATTRIBUTE_LOOPER, paint.getLooper(), writer, urlDataManager);
997 apply_flattenable(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER, paint.getImageFilter(), writer,
998 urlDataManager);
999 apply_flattenable(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER, paint.getColorFilter(), writer,
1000 urlDataManager);
1001 writer.endObject(); // paint
1002 }
1003
MakeJsonFont(const SkFont & font,SkJSONWriter & writer,UrlDataManager & urlDataManager)1004 static void MakeJsonFont(const SkFont& font, SkJSONWriter& writer, UrlDataManager& urlDataManager) {
1005 writer.beginObject();
1006 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, font.isEmbolden(), false);
1007 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, font.isLinearMetrics(), false);
1008 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, font.isSubpixel(), false);
1009 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, font.isEmbeddedBitmaps(), false);
1010 store_bool(writer, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, font.isForceAutoHinting(), false);
1011
1012 store_scalar(writer, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, font.getSize(),
1013 SkPaintDefaults_TextSize);
1014 store_scalar(writer, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getScaleX(), SK_Scalar1);
1015 store_scalar(writer, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getSkewX(), 0.0f);
1016 apply_font_edging(font, writer);
1017 apply_font_hinting(font, writer);
1018 apply_font_typeface(font, writer, urlDataManager);
1019 writer.endObject(); // font
1020 }
1021
MakeJsonLattice(SkJSONWriter & writer,const SkCanvas::Lattice & lattice)1022 void SkDrawCommand::MakeJsonLattice(SkJSONWriter& writer, const SkCanvas::Lattice& lattice) {
1023 writer.beginObject();
1024 writer.appendS32(SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT, lattice.fXCount);
1025 writer.appendS32(SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT, lattice.fYCount);
1026 if (nullptr != lattice.fBounds) {
1027 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS);
1028 MakeJsonIRect(writer, *lattice.fBounds);
1029 }
1030 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS);
1031 for (int i = 0; i < lattice.fXCount; i++) {
1032 writer.appendS32(lattice.fXDivs[i]);
1033 }
1034 writer.endArray(); // xdivs
1035 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS);
1036 for (int i = 0; i < lattice.fYCount; i++) {
1037 writer.appendS32(lattice.fYDivs[i]);
1038 }
1039 writer.endArray(); // ydivs
1040 if (nullptr != lattice.fRectTypes) {
1041 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS);
1042 int flagCount = 0;
1043 for (int row = 0; row < lattice.fYCount+1; row++) {
1044 writer.beginArray();
1045 for (int column = 0; column < lattice.fXCount+1; column++) {
1046 writer.appendS32(lattice.fRectTypes[flagCount++]);
1047 }
1048 writer.endArray(); // row
1049 }
1050 writer.endArray();
1051 }
1052 writer.endObject();
1053 }
1054
SkClearCommand(SkColor color)1055 SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
1056 fColor = color;
1057 }
1058
execute(SkCanvas * canvas) const1059 void SkClearCommand::execute(SkCanvas* canvas) const {
1060 canvas->clear(fColor);
1061 }
1062
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1063 void SkClearCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1064 INHERITED::toJSON(writer, urlDataManager);
1065 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COLOR);
1066 MakeJsonColor(writer, fColor);
1067 }
1068
SkClipPathCommand(const SkPath & path,SkClipOp op,bool doAA)1069 SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
1070 : INHERITED(kClipPath_OpType) {
1071 fPath = path;
1072 fOp = op;
1073 fDoAA = doAA;
1074 }
1075
execute(SkCanvas * canvas) const1076 void SkClipPathCommand::execute(SkCanvas* canvas) const {
1077 canvas->clipPath(fPath, fOp, fDoAA);
1078 }
1079
render(SkCanvas * canvas) const1080 bool SkClipPathCommand::render(SkCanvas* canvas) const {
1081 render_path(canvas, fPath);
1082 return true;
1083 }
1084
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1085 void SkClipPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1086 INHERITED::toJSON(writer, urlDataManager);
1087 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PATH); MakeJsonPath(writer, fPath);
1088 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1089 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
1090 }
1091
SkClipRegionCommand(const SkRegion & region,SkClipOp op)1092 SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
1093 : INHERITED(kClipRegion_OpType) {
1094 fRegion = region;
1095 fOp = op;
1096 }
1097
execute(SkCanvas * canvas) const1098 void SkClipRegionCommand::execute(SkCanvas* canvas) const {
1099 canvas->clipRegion(fRegion, fOp);
1100 }
1101
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1102 void SkClipRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1103 INHERITED::toJSON(writer, urlDataManager);
1104 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_REGION); MakeJsonRegion(writer, fRegion);
1105 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1106 }
1107
SkClipRectCommand(const SkRect & rect,SkClipOp op,bool doAA)1108 SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
1109 : INHERITED(kClipRect_OpType) {
1110 fRect = rect;
1111 fOp = op;
1112 fDoAA = doAA;
1113 }
1114
execute(SkCanvas * canvas) const1115 void SkClipRectCommand::execute(SkCanvas* canvas) const {
1116 canvas->clipRect(fRect, fOp, fDoAA);
1117 }
1118
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1119 void SkClipRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1120 INHERITED::toJSON(writer, urlDataManager);
1121 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonRect(writer, fRect);
1122 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1123 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
1124
1125 SkString desc;
1126 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fRect)->c_str());
1127 }
1128
SkClipRRectCommand(const SkRRect & rrect,SkClipOp op,bool doAA)1129 SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
1130 : INHERITED(kClipRRect_OpType) {
1131 fRRect = rrect;
1132 fOp = op;
1133 fDoAA = doAA;
1134 }
1135
execute(SkCanvas * canvas) const1136 void SkClipRRectCommand::execute(SkCanvas* canvas) const {
1137 canvas->clipRRect(fRRect, fOp, fDoAA);
1138 }
1139
render(SkCanvas * canvas) const1140 bool SkClipRRectCommand::render(SkCanvas* canvas) const {
1141 render_rrect(canvas, fRRect);
1142 return true;
1143 }
1144
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1145 void SkClipRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1146 INHERITED::toJSON(writer, urlDataManager);
1147 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); make_json_rrect(writer, fRRect);
1148 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1149 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
1150 }
1151
SkConcatCommand(const SkMatrix & matrix)1152 SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
1153 : INHERITED(kConcat_OpType) {
1154 fMatrix = matrix;
1155 }
1156
execute(SkCanvas * canvas) const1157 void SkConcatCommand::execute(SkCanvas* canvas) const {
1158 canvas->concat(fMatrix);
1159 }
1160
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1161 void SkConcatCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1162 INHERITED::toJSON(writer, urlDataManager);
1163 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_MATRIX); MakeJsonMatrix(writer, fMatrix);
1164 }
1165
1166 ////
1167
SkDrawAnnotationCommand(const SkRect & rect,const char key[],sk_sp<SkData> value)1168 SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1169 sk_sp<SkData> value)
1170 : INHERITED(kDrawAnnotation_OpType)
1171 , fRect(rect)
1172 , fKey(key)
1173 , fValue(std::move(value))
1174 {
1175 }
1176
execute(SkCanvas * canvas) const1177 void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1178 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1179 }
1180
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1181 void SkDrawAnnotationCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1182 INHERITED::toJSON(writer, urlDataManager);
1183
1184 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonRect(writer, fRect);
1185 writer.appendString("key", fKey.c_str());
1186 if (fValue.get()) {
1187 // TODO: dump out the "value"
1188 }
1189
1190 SkString desc;
1191 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
1192 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, desc.c_str());
1193 }
1194
1195 ////
1196
SkDrawBitmapCommand(const SkBitmap & bitmap,SkScalar left,SkScalar top,const SkPaint * paint)1197 SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
1198 const SkPaint* paint)
1199 : INHERITED(kDrawBitmap_OpType)
1200 , fBitmap(bitmap)
1201 , fLeft(left)
1202 , fTop(top)
1203 , fPaint(paint) {}
1204
execute(SkCanvas * canvas) const1205 void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
1206 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaint.getMaybeNull());
1207 }
1208
render(SkCanvas * canvas) const1209 bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
1210 render_bitmap(canvas, fBitmap);
1211 return true;
1212 }
1213
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1214 void SkDrawBitmapCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1215 INHERITED::toJSON(writer, urlDataManager);
1216 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_BITMAP);
1217 flatten(fBitmap, writer, urlDataManager);
1218 writer.endObject();
1219 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonPoint(writer, fLeft, fTop);
1220 if (fPaint.isValid()) {
1221 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1222 MakeJsonPaint(writer, *fPaint, urlDataManager);
1223 }
1224 }
1225
SkDrawBitmapLatticeCommand(const SkBitmap & bitmap,const SkCanvas::Lattice & lattice,const SkRect & dst,const SkPaint * paint)1226 SkDrawBitmapLatticeCommand::SkDrawBitmapLatticeCommand(const SkBitmap& bitmap,
1227 const SkCanvas::Lattice& lattice,
1228 const SkRect& dst, const SkPaint* paint)
1229 : INHERITED(kDrawBitmapLattice_OpType)
1230 , fBitmap(bitmap)
1231 , fLattice(lattice)
1232 , fDst(dst)
1233 , fPaint(paint) {}
1234
execute(SkCanvas * canvas) const1235 void SkDrawBitmapLatticeCommand::execute(SkCanvas* canvas) const {
1236 canvas->drawBitmapLattice(fBitmap, fLattice, fDst, fPaint.getMaybeNull());
1237 }
1238
render(SkCanvas * canvas) const1239 bool SkDrawBitmapLatticeCommand::render(SkCanvas* canvas) const {
1240 SkAutoCanvasRestore acr(canvas, true);
1241 canvas->clear(0xFFFFFFFF);
1242
1243 xlate_and_scale_to_bounds(canvas, fDst);
1244
1245 this->execute(canvas);
1246 return true;
1247 }
1248
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1249 void SkDrawBitmapLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1250 INHERITED::toJSON(writer, urlDataManager);
1251 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_BITMAP);
1252 flatten(fBitmap, writer, urlDataManager);
1253 writer.endObject(); // bitmap
1254
1255 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_LATTICE); MakeJsonLattice(writer, fLattice);
1256 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_DST); MakeJsonRect(writer, fDst);
1257 if (fPaint.isValid()) {
1258 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1259 MakeJsonPaint(writer, *fPaint, urlDataManager);
1260 }
1261
1262 SkString desc;
1263 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
1264 }
1265
SkDrawBitmapNineCommand(const SkBitmap & bitmap,const SkIRect & center,const SkRect & dst,const SkPaint * paint)1266 SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
1267 const SkRect& dst, const SkPaint* paint)
1268 : INHERITED(kDrawBitmapNine_OpType)
1269 , fBitmap(bitmap)
1270 , fCenter(center)
1271 , fDst(dst)
1272 , fPaint(paint) {}
1273
execute(SkCanvas * canvas) const1274 void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
1275 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaint.getMaybeNull());
1276 }
1277
render(SkCanvas * canvas) const1278 bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
1279 SkRect tmp = SkRect::Make(fCenter);
1280 render_bitmap(canvas, fBitmap, &tmp);
1281 return true;
1282 }
1283
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1284 void SkDrawBitmapNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1285 INHERITED::toJSON(writer, urlDataManager);
1286 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_BITMAP);
1287 flatten(fBitmap, writer, urlDataManager);
1288 writer.endObject(); // bitmap
1289
1290 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_CENTER); MakeJsonIRect(writer, fCenter);
1291 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_DST); MakeJsonRect(writer, fDst);
1292 if (fPaint.isValid()) {
1293 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1294 MakeJsonPaint(writer, *fPaint, urlDataManager);
1295 }
1296 }
1297
SkDrawBitmapRectCommand(const SkBitmap & bitmap,const SkRect * src,const SkRect & dst,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)1298 SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
1299 const SkRect& dst, const SkPaint* paint,
1300 SkCanvas::SrcRectConstraint constraint)
1301 : INHERITED(kDrawBitmapRect_OpType)
1302 , fBitmap(bitmap)
1303 , fSrc(src)
1304 , fDst(dst)
1305 , fPaint(paint)
1306 , fConstraint(constraint) {}
1307
execute(SkCanvas * canvas) const1308 void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
1309 canvas->legacy_drawBitmapRect(fBitmap, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(),
1310 fConstraint);
1311 }
1312
render(SkCanvas * canvas) const1313 bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
1314 render_bitmap(canvas, fBitmap, fSrc.getMaybeNull());
1315 return true;
1316 }
1317
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1318 void SkDrawBitmapRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1319 INHERITED::toJSON(writer, urlDataManager);
1320 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_BITMAP);
1321 flatten(fBitmap, writer, urlDataManager);
1322 writer.endObject(); // bitmap
1323
1324 if (fSrc.isValid()) {
1325 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_SRC); MakeJsonRect(writer, *fSrc);
1326 }
1327 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_DST); MakeJsonRect(writer, fDst);
1328 if (fPaint.isValid()) {
1329 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1330 MakeJsonPaint(writer, *fPaint, urlDataManager);
1331 }
1332 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1333 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_STRICT, true);
1334 }
1335
1336 SkString desc;
1337 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
1338 }
1339
SkDrawImageCommand(const SkImage * image,SkScalar left,SkScalar top,const SkPaint * paint)1340 SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
1341 const SkPaint* paint)
1342 : INHERITED(kDrawImage_OpType)
1343 , fImage(SkRef(image))
1344 , fLeft(left)
1345 , fTop(top)
1346 , fPaint(paint) {}
1347
execute(SkCanvas * canvas) const1348 void SkDrawImageCommand::execute(SkCanvas* canvas) const {
1349 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
1350 }
1351
render(SkCanvas * canvas) const1352 bool SkDrawImageCommand::render(SkCanvas* canvas) const {
1353 SkAutoCanvasRestore acr(canvas, true);
1354 canvas->clear(0xFFFFFFFF);
1355
1356 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
1357 SkIntToScalar(fImage->width()),
1358 SkIntToScalar(fImage->height())));
1359 this->execute(canvas);
1360 return true;
1361 }
1362
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1363 void SkDrawImageCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1364 INHERITED::toJSON(writer, urlDataManager);
1365 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_IMAGE);
1366 flatten(*fImage, writer, urlDataManager);
1367 writer.endObject(); // image
1368
1369 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonPoint(writer, fLeft, fTop);
1370 if (fPaint.isValid()) {
1371 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1372 MakeJsonPaint(writer, *fPaint, urlDataManager);
1373 }
1374
1375 writer.appendU32(SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID, fImage->uniqueID());
1376 writer.appendS32(SKDEBUGCANVAS_ATTRIBUTE_WIDTH, fImage->width());
1377 writer.appendS32(SKDEBUGCANVAS_ATTRIBUTE_HEIGHT, fImage->height());
1378 switch (fImage->alphaType()) {
1379 case kOpaque_SkAlphaType:
1380 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_ALPHA, SKDEBUGCANVAS_ALPHATYPE_OPAQUE);
1381 break;
1382 case kPremul_SkAlphaType:
1383 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_ALPHA, SKDEBUGCANVAS_ALPHATYPE_PREMUL);
1384 break;
1385 case kUnpremul_SkAlphaType:
1386 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_ALPHA, SKDEBUGCANVAS_ALPHATYPE_UNPREMUL);
1387 break;
1388 default:
1389 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_ALPHA, SKDEBUGCANVAS_ALPHATYPE_UNKNOWN);
1390 break;
1391 }
1392 }
1393
SkDrawImageLatticeCommand(const SkImage * image,const SkCanvas::Lattice & lattice,const SkRect & dst,const SkPaint * paint)1394 SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
1395 const SkCanvas::Lattice& lattice,
1396 const SkRect& dst, const SkPaint* paint)
1397 : INHERITED(kDrawImageLattice_OpType)
1398 , fImage(SkRef(image))
1399 , fLattice(lattice)
1400 , fDst(dst)
1401 , fPaint(paint) {}
1402
execute(SkCanvas * canvas) const1403 void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
1404 canvas->drawImageLattice(fImage.get(), fLattice, fDst, fPaint.getMaybeNull());
1405 }
1406
render(SkCanvas * canvas) const1407 bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
1408 SkAutoCanvasRestore acr(canvas, true);
1409 canvas->clear(0xFFFFFFFF);
1410
1411 xlate_and_scale_to_bounds(canvas, fDst);
1412
1413 this->execute(canvas);
1414 return true;
1415 }
1416
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1417 void SkDrawImageLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1418 INHERITED::toJSON(writer, urlDataManager);
1419 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_IMAGE);
1420 flatten(*fImage, writer, urlDataManager);
1421 writer.endObject(); // image
1422
1423 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_LATTICE); MakeJsonLattice(writer, fLattice);
1424 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_DST); MakeJsonRect(writer, fDst);
1425 if (fPaint.isValid()) {
1426 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1427 MakeJsonPaint(writer, *fPaint, urlDataManager);
1428 }
1429
1430 SkString desc;
1431 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
1432 }
1433
SkDrawImageRectCommand(const SkImage * image,const SkRect * src,const SkRect & dst,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)1434 SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
1435 const SkRect& dst, const SkPaint* paint,
1436 SkCanvas::SrcRectConstraint constraint)
1437 : INHERITED(kDrawImageRect_OpType)
1438 , fImage(SkRef(image))
1439 , fSrc(src)
1440 , fDst(dst)
1441 , fPaint(paint)
1442 , fConstraint(constraint) {}
1443
execute(SkCanvas * canvas) const1444 void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
1445 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
1446 fPaint.getMaybeNull(), fConstraint);
1447 }
1448
render(SkCanvas * canvas) const1449 bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
1450 SkAutoCanvasRestore acr(canvas, true);
1451 canvas->clear(0xFFFFFFFF);
1452
1453 xlate_and_scale_to_bounds(canvas, fDst);
1454
1455 this->execute(canvas);
1456 return true;
1457 }
1458
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1459 void SkDrawImageRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1460 INHERITED::toJSON(writer, urlDataManager);
1461 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_IMAGE);
1462 flatten(*fImage, writer, urlDataManager);
1463 writer.endObject(); // image
1464
1465 if (fSrc.isValid()) {
1466 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_SRC); MakeJsonRect(writer, *fSrc);
1467 }
1468 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_DST); MakeJsonRect(writer, fDst);
1469 if (fPaint.isValid()) {
1470 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1471 MakeJsonPaint(writer, *fPaint, urlDataManager);
1472 }
1473 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1474 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_STRICT, true);
1475 }
1476
1477 SkString desc;
1478 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
1479 }
1480
SkDrawImageSetCommand(const SkCanvas::ImageSetEntry set[],int count,SkFilterQuality filterQuality,SkBlendMode mode)1481 SkDrawImageSetCommand::SkDrawImageSetCommand(const SkCanvas::ImageSetEntry set[], int count,
1482 SkFilterQuality filterQuality, SkBlendMode mode)
1483 : INHERITED(kDrawImageSet_OpType)
1484 , fSet(count)
1485 , fCount(count)
1486 , fFilterQuality(filterQuality)
1487 , fMode(mode) {
1488 std::copy_n(set, count, fSet.get());
1489 }
1490
execute(SkCanvas * canvas) const1491 void SkDrawImageSetCommand::execute(SkCanvas* canvas) const {
1492 canvas->experimental_DrawImageSetV1(fSet.get(), fCount, fFilterQuality, fMode);
1493 }
1494
SkDrawImageNineCommand(const SkImage * image,const SkIRect & center,const SkRect & dst,const SkPaint * paint)1495 SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
1496 const SkRect& dst, const SkPaint* paint)
1497 : INHERITED(kDrawImageNine_OpType)
1498 , fImage(SkRef(image))
1499 , fCenter(center)
1500 , fDst(dst)
1501 , fPaint(paint) {}
1502
execute(SkCanvas * canvas) const1503 void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
1504 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaint.getMaybeNull());
1505 }
1506
render(SkCanvas * canvas) const1507 bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
1508 SkAutoCanvasRestore acr(canvas, true);
1509 canvas->clear(0xFFFFFFFF);
1510
1511 xlate_and_scale_to_bounds(canvas, fDst);
1512
1513 this->execute(canvas);
1514 return true;
1515 }
1516
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1517 void SkDrawImageNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1518 INHERITED::toJSON(writer, urlDataManager);
1519 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_IMAGE);
1520 flatten(*fImage, writer, urlDataManager);
1521 writer.endObject(); // image
1522
1523 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_CENTER); MakeJsonIRect(writer, fCenter);
1524 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_DST); MakeJsonRect(writer, fDst);
1525 if (fPaint.isValid()) {
1526 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1527 MakeJsonPaint(writer, *fPaint, urlDataManager);
1528 }
1529 }
1530
SkDrawOvalCommand(const SkRect & oval,const SkPaint & paint)1531 SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
1532 : INHERITED(kDrawOval_OpType) {
1533 fOval = oval;
1534 fPaint = paint;
1535 }
1536
execute(SkCanvas * canvas) const1537 void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
1538 canvas->drawOval(fOval, fPaint);
1539 }
1540
render(SkCanvas * canvas) const1541 bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
1542 canvas->clear(0xFFFFFFFF);
1543 canvas->save();
1544
1545 xlate_and_scale_to_bounds(canvas, fOval);
1546
1547 SkPaint p;
1548 p.setColor(SK_ColorBLACK);
1549 p.setStyle(SkPaint::kStroke_Style);
1550
1551 canvas->drawOval(fOval, p);
1552 canvas->restore();
1553
1554 return true;
1555 }
1556
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1557 void SkDrawOvalCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1558 INHERITED::toJSON(writer, urlDataManager);
1559 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonRect(writer, fOval);
1560 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1561 }
1562
SkDrawArcCommand(const SkRect & oval,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)1563 SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
1564 bool useCenter, const SkPaint& paint)
1565 : INHERITED(kDrawArc_OpType) {
1566 fOval = oval;
1567 fStartAngle = startAngle;
1568 fSweepAngle = sweepAngle;
1569 fUseCenter = useCenter;
1570 fPaint = paint;
1571 }
1572
execute(SkCanvas * canvas) const1573 void SkDrawArcCommand::execute(SkCanvas* canvas) const {
1574 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
1575 }
1576
render(SkCanvas * canvas) const1577 bool SkDrawArcCommand::render(SkCanvas* canvas) const {
1578 canvas->clear(0xFFFFFFFF);
1579 canvas->save();
1580
1581 xlate_and_scale_to_bounds(canvas, fOval);
1582
1583 SkPaint p;
1584 p.setColor(SK_ColorBLACK);
1585 p.setStyle(SkPaint::kStroke_Style);
1586
1587 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
1588 canvas->restore();
1589
1590 return true;
1591 }
1592
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1593 void SkDrawArcCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1594 INHERITED::toJSON(writer, urlDataManager);
1595 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonRect(writer, fOval);
1596 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE, fStartAngle);
1597 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE, fSweepAngle);
1598 writer.appendBool(SKDEBUGCANVAS_ATTRIBUTE_USECENTER, fUseCenter);
1599 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1600 }
1601
SkDrawPaintCommand(const SkPaint & paint)1602 SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
1603 : INHERITED(kDrawPaint_OpType) {
1604 fPaint = paint;
1605 }
1606
execute(SkCanvas * canvas) const1607 void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
1608 canvas->drawPaint(fPaint);
1609 }
1610
render(SkCanvas * canvas) const1611 bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
1612 canvas->clear(0xFFFFFFFF);
1613 canvas->drawPaint(fPaint);
1614 return true;
1615 }
1616
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1617 void SkDrawPaintCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1618 INHERITED::toJSON(writer, urlDataManager);
1619 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1620 }
1621
SkDrawPathCommand(const SkPath & path,const SkPaint & paint)1622 SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
1623 : INHERITED(kDrawPath_OpType) {
1624 fPath = path;
1625 fPaint = paint;
1626 }
1627
execute(SkCanvas * canvas) const1628 void SkDrawPathCommand::execute(SkCanvas* canvas) const {
1629 canvas->drawPath(fPath, fPaint);
1630 }
1631
render(SkCanvas * canvas) const1632 bool SkDrawPathCommand::render(SkCanvas* canvas) const {
1633 render_path(canvas, fPath);
1634 return true;
1635 }
1636
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1637 void SkDrawPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1638 INHERITED::toJSON(writer, urlDataManager);
1639 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PATH); MakeJsonPath(writer, fPath);
1640 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1641 }
1642
SkDrawBehindCommand(const SkPaint & paint)1643 SkDrawBehindCommand::SkDrawBehindCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
1644 fPaint = paint;
1645 }
1646
execute(SkCanvas * canvas) const1647 void SkDrawBehindCommand::execute(SkCanvas* canvas) const {
1648 SkCanvasPriv::DrawBehind(canvas, fPaint);
1649 }
1650
render(SkCanvas * canvas) const1651 bool SkDrawBehindCommand::render(SkCanvas* canvas) const {
1652 canvas->clear(0xFFFFFFFF);
1653 SkCanvasPriv::DrawBehind(canvas, fPaint);
1654 return true;
1655 }
1656
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1657 void SkDrawBehindCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1658 INHERITED::toJSON(writer, urlDataManager);
1659 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
1660 MakeJsonPaint(writer, fPaint, urlDataManager);
1661 }
1662
1663
SkDrawRegionCommand(const SkRegion & region,const SkPaint & paint)1664 SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
1665 : INHERITED(kDrawRegion_OpType) {
1666 fRegion = region;
1667 fPaint = paint;
1668 }
1669
execute(SkCanvas * canvas) const1670 void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
1671 canvas->drawRegion(fRegion, fPaint);
1672 }
1673
render(SkCanvas * canvas) const1674 bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
1675 render_region(canvas, fRegion);
1676 return true;
1677 }
1678
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1679 void SkDrawRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1680 INHERITED::toJSON(writer, urlDataManager);
1681 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_REGION); MakeJsonRegion(writer, fRegion);
1682 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1683 }
1684
SkBeginDrawPictureCommand(const SkPicture * picture,const SkMatrix * matrix,const SkPaint * paint)1685 SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
1686 const SkMatrix* matrix,
1687 const SkPaint* paint)
1688 : INHERITED(kBeginDrawPicture_OpType)
1689 , fPicture(SkRef(picture))
1690 , fMatrix(matrix)
1691 , fPaint(paint) {}
1692
execute(SkCanvas * canvas) const1693 void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
1694 if (fPaint.isValid()) {
1695 SkRect bounds = fPicture->cullRect();
1696 if (fMatrix.isValid()) {
1697 fMatrix->mapRect(&bounds);
1698 }
1699 canvas->saveLayer(&bounds, fPaint.get());
1700 }
1701
1702 if (fMatrix.isValid()) {
1703 if (!fPaint.isValid()) {
1704 canvas->save();
1705 }
1706 canvas->concat(*fMatrix);
1707 }
1708 }
1709
render(SkCanvas * canvas) const1710 bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
1711 canvas->clear(0xFFFFFFFF);
1712 canvas->save();
1713
1714 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
1715
1716 canvas->drawPicture(fPicture.get());
1717
1718 canvas->restore();
1719
1720 return true;
1721 }
1722
SkEndDrawPictureCommand(bool restore)1723 SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
1724 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
1725
execute(SkCanvas * canvas) const1726 void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
1727 if (fRestore) {
1728 canvas->restore();
1729 }
1730 }
1731
SkDrawPointsCommand(SkCanvas::PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)1732 SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
1733 const SkPoint pts[], const SkPaint& paint)
1734 : INHERITED(kDrawPoints_OpType)
1735 , fMode(mode)
1736 , fPts(pts, count)
1737 , fPaint(paint) {}
1738
execute(SkCanvas * canvas) const1739 void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
1740 canvas->drawPoints(fMode, fPts.count(), fPts.begin(), fPaint);
1741 }
1742
render(SkCanvas * canvas) const1743 bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
1744 canvas->clear(0xFFFFFFFF);
1745 canvas->save();
1746
1747 SkRect bounds;
1748
1749 bounds.setEmpty();
1750 for (int i = 0; i < fPts.count(); ++i) {
1751 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
1752 }
1753
1754 xlate_and_scale_to_bounds(canvas, bounds);
1755
1756 SkPaint p;
1757 p.setColor(SK_ColorBLACK);
1758 p.setStyle(SkPaint::kStroke_Style);
1759
1760 canvas->drawPoints(fMode, fPts.count(), fPts.begin(), p);
1761 canvas->restore();
1762
1763 return true;
1764 }
1765
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1766 void SkDrawPointsCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1767 INHERITED::toJSON(writer, urlDataManager);
1768 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_MODE, pointmode_name(fMode));
1769 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_POINTS);
1770 for (int i = 0; i < fPts.count(); i++) {
1771 MakeJsonPoint(writer, fPts[i]);
1772 }
1773 writer.endArray(); // points
1774 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1775 }
1776
SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob,SkScalar x,SkScalar y,const SkPaint & paint)1777 SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
1778 const SkPaint& paint)
1779 : INHERITED(kDrawTextBlob_OpType)
1780 , fBlob(std::move(blob))
1781 , fXPos(x)
1782 , fYPos(y)
1783 , fPaint(paint) {}
1784
execute(SkCanvas * canvas) const1785 void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
1786 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
1787 }
1788
render(SkCanvas * canvas) const1789 bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
1790 canvas->clear(SK_ColorWHITE);
1791 canvas->save();
1792
1793 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
1794 xlate_and_scale_to_bounds(canvas, bounds);
1795
1796 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
1797
1798 canvas->restore();
1799
1800 return true;
1801 }
1802
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1803 void SkDrawTextBlobCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1804 INHERITED::toJSON(writer, urlDataManager);
1805 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_RUNS);
1806 SkTextBlobRunIterator iter(fBlob.get());
1807 while (!iter.done()) {
1808 writer.beginObject(); // run
1809 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_GLYPHS);
1810 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
1811 writer.appendU32(iter.glyphs()[i]);
1812 }
1813 writer.endArray(); // glyphs
1814 if (iter.positioning() != SkTextBlobRunIterator::kDefault_Positioning) {
1815 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS);
1816 const SkScalar* iterPositions = iter.pos();
1817 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
1818 switch (iter.positioning()) {
1819 case SkTextBlobRunIterator::kFull_Positioning:
1820 MakeJsonPoint(writer, iterPositions[i * 2], iterPositions[i * 2 + 1]);
1821 break;
1822 case SkTextBlobRunIterator::kHorizontal_Positioning:
1823 writer.appendFloat(iterPositions[i]);
1824 break;
1825 case SkTextBlobRunIterator::kDefault_Positioning:
1826 break;
1827 case SkTextBlobRunIterator::kRSXform_Positioning:
1828 // TODO_RSXFORM_BLOB
1829 break;
1830 }
1831 }
1832 writer.endArray(); // positions
1833 }
1834 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_FONT);
1835 MakeJsonFont(iter.font(), writer, urlDataManager);
1836 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS);
1837 MakeJsonPoint(writer, iter.offset());
1838
1839 writer.endObject(); // run
1840 iter.next();
1841 }
1842 writer.endArray(); // runs
1843 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_X, fXPos);
1844 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_Y, fYPos);
1845 SkRect bounds = fBlob->bounds();
1846 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonRect(writer, bounds);
1847 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1848
1849 SkString desc;
1850 // make the bounds local by applying the x,y
1851 bounds.offset(fXPos, fYPos);
1852 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, bounds)->c_str());
1853 }
1854
SkDrawPatchCommand(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode bmode,const SkPaint & paint)1855 SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
1856 const SkPoint texCoords[4], SkBlendMode bmode,
1857 const SkPaint& paint)
1858 : INHERITED(kDrawPatch_OpType)
1859 , fBlendMode(bmode)
1860 {
1861 memcpy(fCubics, cubics, sizeof(fCubics));
1862 if (colors != nullptr) {
1863 memcpy(fColors, colors, sizeof(fColors));
1864 fColorsPtr = fColors;
1865 } else {
1866 fColorsPtr = nullptr;
1867 }
1868 if (texCoords != nullptr) {
1869 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
1870 fTexCoordsPtr = fTexCoords;
1871 } else {
1872 fTexCoordsPtr = nullptr;
1873 }
1874 fPaint = paint;
1875 }
1876
execute(SkCanvas * canvas) const1877 void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
1878 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
1879 }
1880
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1881 void SkDrawPatchCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1882 INHERITED::toJSON(writer, urlDataManager);
1883 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_CUBICS);
1884 for (int i = 0; i < 12; i++) {
1885 MakeJsonPoint(writer, fCubics[i]);
1886 }
1887 writer.endArray(); // cubics
1888 if (fColorsPtr != nullptr) {
1889 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_COLORS);
1890 for (int i = 0; i < 4; i++) {
1891 MakeJsonColor(writer, fColorsPtr[i]);
1892 }
1893 writer.endArray(); // colors
1894 }
1895 if (fTexCoordsPtr != nullptr) {
1896 writer.beginArray(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS);
1897 for (int i = 0; i < 4; i++) {
1898 MakeJsonPoint(writer, fTexCoords[i]);
1899 }
1900 writer.endArray(); // texCoords
1901 }
1902 // fBlendMode
1903 }
1904
SkDrawRectCommand(const SkRect & rect,const SkPaint & paint)1905 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
1906 : INHERITED(kDrawRect_OpType) {
1907 fRect = rect;
1908 fPaint = paint;
1909 }
1910
execute(SkCanvas * canvas) const1911 void SkDrawRectCommand::execute(SkCanvas* canvas) const {
1912 canvas->drawRect(fRect, fPaint);
1913 }
1914
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1915 void SkDrawRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1916 INHERITED::toJSON(writer, urlDataManager);
1917 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); MakeJsonRect(writer, fRect);
1918 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1919
1920 SkString desc;
1921 writer.appendString(SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fRect)->c_str());
1922 }
1923
SkDrawEdgeAARectCommand(const SkRect & rect,SkCanvas::QuadAAFlags aa,SkColor color,SkBlendMode mode)1924 SkDrawEdgeAARectCommand::SkDrawEdgeAARectCommand(const SkRect& rect, SkCanvas::QuadAAFlags aa,
1925 SkColor color, SkBlendMode mode)
1926 : INHERITED(kDrawEdgeAARect_OpType) {
1927 fRect = rect;
1928 fAA = aa;
1929 fColor = color;
1930 fMode = mode;
1931 }
1932
execute(SkCanvas * canvas) const1933 void SkDrawEdgeAARectCommand::execute(SkCanvas* canvas) const {
1934 canvas->experimental_DrawEdgeAARectV1(fRect, fAA, fColor, fMode);
1935 }
1936
SkDrawRRectCommand(const SkRRect & rrect,const SkPaint & paint)1937 SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
1938 : INHERITED(kDrawRRect_OpType) {
1939 fRRect = rrect;
1940 fPaint = paint;
1941 }
1942
execute(SkCanvas * canvas) const1943 void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
1944 canvas->drawRRect(fRRect, fPaint);
1945 }
1946
render(SkCanvas * canvas) const1947 bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
1948 render_rrect(canvas, fRRect);
1949 return true;
1950 }
1951
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1952 void SkDrawRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1953 INHERITED::toJSON(writer, urlDataManager);
1954 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_COORDS); make_json_rrect(writer, fRRect);
1955 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1956 }
1957
SkDrawDRRectCommand(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)1958 SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
1959 const SkRRect& inner,
1960 const SkPaint& paint)
1961 : INHERITED(kDrawDRRect_OpType) {
1962 fOuter = outer;
1963 fInner = inner;
1964 fPaint = paint;
1965 }
1966
execute(SkCanvas * canvas) const1967 void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
1968 canvas->drawDRRect(fOuter, fInner, fPaint);
1969 }
1970
render(SkCanvas * canvas) const1971 bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
1972 render_drrect(canvas, fOuter, fInner);
1973 return true;
1974 }
1975
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1976 void SkDrawDRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1977 INHERITED::toJSON(writer, urlDataManager);
1978 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_OUTER); make_json_rrect(writer, fOuter);
1979 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_INNER); make_json_rrect(writer, fInner);
1980 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
1981 }
1982
SkDrawShadowCommand(const SkPath & path,const SkDrawShadowRec & rec)1983 SkDrawShadowCommand::SkDrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
1984 : INHERITED(kDrawShadow_OpType) {
1985 fPath = path;
1986 fShadowRec = rec;
1987 }
1988
execute(SkCanvas * canvas) const1989 void SkDrawShadowCommand::execute(SkCanvas* canvas) const {
1990 canvas->private_draw_shadow_rec(fPath, fShadowRec);
1991 }
1992
render(SkCanvas * canvas) const1993 bool SkDrawShadowCommand::render(SkCanvas* canvas) const {
1994 render_shadow(canvas, fPath, fShadowRec);
1995 return true;
1996 }
1997
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const1998 void SkDrawShadowCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1999 INHERITED::toJSON(writer, urlDataManager);
2000
2001 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
2002 bool transparentOccluder =
2003 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
2004
2005 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PATH); MakeJsonPath(writer, fPath);
2006 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_ZPLANE);
2007 MakeJsonPoint3(writer, fShadowRec.fZPlaneParams);
2008 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION);
2009 MakeJsonPoint3(writer, fShadowRec.fLightPos);
2010 writer.appendFloat(SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS, fShadowRec.fLightRadius);
2011 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR);
2012 MakeJsonColor(writer, fShadowRec.fAmbientColor);
2013 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR);
2014 MakeJsonColor(writer, fShadowRec.fSpotColor);
2015 store_bool(writer, SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
2016 store_bool(writer, SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
2017 }
2018
2019 ///////////////////////////////////////////////////////////////////////////////////////////////////
2020
SkDrawDrawableCommand(SkDrawable * drawable,const SkMatrix * matrix)2021 SkDrawDrawableCommand::SkDrawDrawableCommand(SkDrawable* drawable, const SkMatrix* matrix)
2022 : INHERITED(kDrawDrawable_OpType)
2023 , fDrawable(SkRef(drawable))
2024 , fMatrix(matrix) {}
2025
execute(SkCanvas * canvas) const2026 void SkDrawDrawableCommand::execute(SkCanvas* canvas) const {
2027 canvas->drawDrawable(fDrawable.get(), fMatrix.getMaybeNull());
2028 }
2029
2030 ///////////////////////////////////////////////////////////////////////////////////////////////////
2031
SkDrawVerticesCommand(sk_sp<SkVertices> vertices,SkBlendMode bmode,const SkPaint & paint)2032 SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
2033 const SkPaint& paint)
2034 : INHERITED(kDrawVertices_OpType)
2035 , fVertices(std::move(vertices))
2036 , fBlendMode(bmode)
2037 , fPaint(paint) {}
2038
execute(SkCanvas * canvas) const2039 void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
2040 canvas->drawVertices(fVertices, fBlendMode, fPaint);
2041 }
2042
2043 ///////////////////////////////////////////////////////////////////////////////////////////////////
2044
SkDrawAtlasCommand(const SkImage * image,const SkRSXform xform[],const SkRect tex[],const SkColor colors[],int count,SkBlendMode bmode,const SkRect * cull,const SkPaint * paint)2045 SkDrawAtlasCommand::SkDrawAtlasCommand(const SkImage* image, const SkRSXform xform[],
2046 const SkRect tex[], const SkColor colors[], int count,
2047 SkBlendMode bmode, const SkRect* cull,
2048 const SkPaint* paint)
2049 : INHERITED(kDrawAtlas_OpType)
2050 , fImage(SkRef(image))
2051 , fXform(xform, count)
2052 , fTex(tex, count)
2053 , fColors(colors, colors ? count : 0)
2054 , fBlendMode(bmode)
2055 , fCull(cull)
2056 , fPaint(paint) {}
2057
execute(SkCanvas * canvas) const2058 void SkDrawAtlasCommand::execute(SkCanvas* canvas) const {
2059 canvas->drawAtlas(fImage.get(), fXform.begin(), fTex.begin(),
2060 fColors.isEmpty() ? nullptr : fColors.begin(), fXform.count(), fBlendMode,
2061 fCull.getMaybeNull(), fPaint.getMaybeNull());
2062 }
2063
2064 ///////////////////////////////////////////////////////////////////////////////////////////////////
2065
SkRestoreCommand()2066 SkRestoreCommand::SkRestoreCommand()
2067 : INHERITED(kRestore_OpType) {}
2068
execute(SkCanvas * canvas) const2069 void SkRestoreCommand::execute(SkCanvas* canvas) const {
2070 canvas->restore();
2071 }
2072
SkSaveCommand()2073 SkSaveCommand::SkSaveCommand()
2074 : INHERITED(kSave_OpType) {
2075 }
2076
execute(SkCanvas * canvas) const2077 void SkSaveCommand::execute(SkCanvas* canvas) const {
2078 canvas->save();
2079 }
2080
SkSaveLayerCommand(const SkCanvas::SaveLayerRec & rec)2081 SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
2082 : INHERITED(kSaveLayer_OpType)
2083 , fBounds(rec.fBounds)
2084 , fPaint(rec.fPaint)
2085 , fBackdrop(SkSafeRef(rec.fBackdrop))
2086 , fSaveLayerFlags(rec.fSaveLayerFlags) {}
2087
execute(SkCanvas * canvas) const2088 void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
2089 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.getMaybeNull(), fPaint.getMaybeNull(),
2090 fSaveLayerFlags));
2091 }
2092
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const2093 void SkSaveLayerCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
2094 INHERITED::toJSON(writer, urlDataManager);
2095 if (fBounds.isValid()) {
2096 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS); MakeJsonRect(writer, *fBounds);
2097 }
2098 if (fPaint.isValid()) {
2099 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
2100 MakeJsonPaint(writer, *fPaint, urlDataManager);
2101 }
2102 if (fBackdrop != nullptr) {
2103 writer.beginObject(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP);
2104 flatten(fBackdrop.get(), writer, urlDataManager);
2105 writer.endObject(); // backdrop
2106 }
2107 if (fSaveLayerFlags != 0) {
2108 SkDebugf("unsupported: saveLayer flags\n");
2109 SkASSERT(false);
2110 }
2111 }
2112
SkSetMatrixCommand(const SkMatrix & matrix)2113 SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
2114 : INHERITED(kSetMatrix_OpType) {
2115 fMatrix = matrix;
2116 }
2117
execute(SkCanvas * canvas) const2118 void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
2119 canvas->setMatrix(fMatrix);
2120 }
2121
toJSON(SkJSONWriter & writer,UrlDataManager & urlDataManager) const2122 void SkSetMatrixCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
2123 INHERITED::toJSON(writer, urlDataManager);
2124 writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_MATRIX); MakeJsonMatrix(writer, fMatrix);
2125 }
2126