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