blob: d689a5305579e6b0f9cccdc5653bb3d652737a04 [file] [log] [blame]
Mike Klein8f4e2242019-03-20 11:59:00 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "tools/debugger/DrawCommand.h"
Mike Klein8f4e2242019-03-20 11:59:00 -05009
10#include <algorithm>
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkColorFilter.h"
12#include "include/core/SkDrawable.h"
13#include "include/core/SkImageFilter.h"
14#include "include/core/SkPathEffect.h"
15#include "include/core/SkPicture.h"
16#include "include/core/SkTypeface.h"
17#include "include/effects/SkDashPathEffect.h"
18#include "include/encode/SkPngEncoder.h"
19#include "include/private/SkShadowFlags.h"
20#include "include/private/SkTHash.h"
21#include "src/core/SkAutoMalloc.h"
22#include "src/core/SkCanvasPriv.h"
23#include "src/core/SkClipOpPriv.h"
24#include "src/core/SkLatticeIter.h"
25#include "src/core/SkMaskFilterBase.h"
26#include "src/core/SkPaintDefaults.h"
27#include "src/core/SkReadBuffer.h"
28#include "src/core/SkRectPriv.h"
29#include "src/core/SkTextBlobPriv.h"
30#include "src/core/SkWriteBuffer.h"
31#include "tools/debugger/JsonWriteBuffer.h"
Mike Klein8f4e2242019-03-20 11:59:00 -050032
Mike Klein17428132019-03-20 13:02:32 -050033#define DEBUGCANVAS_ATTRIBUTE_COMMAND "command"
34#define DEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
35#define DEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
36#define DEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
37#define DEBUGCANVAS_ATTRIBUTE_COORDS "coords"
38#define DEBUGCANVAS_ATTRIBUTE_EDGING "edging"
39#define DEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
40#define DEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
41#define DEBUGCANVAS_ATTRIBUTE_PAINT "paint"
42#define DEBUGCANVAS_ATTRIBUTE_OUTER "outer"
43#define DEBUGCANVAS_ATTRIBUTE_INNER "inner"
44#define DEBUGCANVAS_ATTRIBUTE_MODE "mode"
45#define DEBUGCANVAS_ATTRIBUTE_POINTS "points"
46#define DEBUGCANVAS_ATTRIBUTE_PATH "path"
47#define DEBUGCANVAS_ATTRIBUTE_TEXT "text"
48#define DEBUGCANVAS_ATTRIBUTE_COLOR "color"
49#define DEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
50#define DEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
51#define DEBUGCANVAS_ATTRIBUTE_STYLE "style"
52#define DEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
53#define DEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
54#define DEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
55#define DEBUGCANVAS_ATTRIBUTE_CAP "cap"
56#define DEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
57#define DEBUGCANVAS_ATTRIBUTE_DITHER "dither"
58#define DEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
59#define DEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
60#define DEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
61#define DEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
62#define DEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
63#define DEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
64#define DEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
65#define DEBUGCANVAS_ATTRIBUTE_REGION "region"
66#define DEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
67#define DEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
68#define DEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
69#define DEBUGCANVAS_ATTRIBUTE_BLUR "blur"
70#define DEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
71#define DEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
72#define DEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
73#define DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
74#define DEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
75#define DEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
76#define DEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
77#define DEBUGCANVAS_ATTRIBUTE_PHASE "phase"
78#define DEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
79#define DEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
80#define DEBUGCANVAS_ATTRIBUTE_NAME "name"
81#define DEBUGCANVAS_ATTRIBUTE_DATA "data"
82#define DEBUGCANVAS_ATTRIBUTE_VALUES "values"
83#define DEBUGCANVAS_ATTRIBUTE_SHADER "shader"
84#define DEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
85#define DEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
86#define DEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
87#define DEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
88#define DEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
89#define DEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
90#define DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
91#define DEBUGCANVAS_ATTRIBUTE_IMAGE "image"
92#define DEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
93#define DEBUGCANVAS_ATTRIBUTE_SRC "src"
94#define DEBUGCANVAS_ATTRIBUTE_DST "dst"
95#define DEBUGCANVAS_ATTRIBUTE_CENTER "center"
96#define DEBUGCANVAS_ATTRIBUTE_STRICT "strict"
97#define DEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
98#define DEBUGCANVAS_ATTRIBUTE_X "x"
99#define DEBUGCANVAS_ATTRIBUTE_Y "y"
100#define DEBUGCANVAS_ATTRIBUTE_RUNS "runs"
101#define DEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
102#define DEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
103#define DEBUGCANVAS_ATTRIBUTE_FONT "font"
104#define DEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
105#define DEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
106#define DEBUGCANVAS_ATTRIBUTE_COLORS "colors"
107#define DEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
108#define DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
109#define DEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
110#define DEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
111#define DEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
112#define DEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
113#define DEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
114#define DEBUGCANVAS_ATTRIBUTE_WIDTH "width"
115#define DEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
116#define DEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
117#define DEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
118#define DEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
119#define DEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
120#define DEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
121#define DEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
122#define DEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
123#define DEBUGCANVAS_ATTRIBUTE_ZPLANE "zPlane"
124#define DEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION "lightPositions"
125#define DEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR "ambientColor"
126#define DEBUGCANVAS_ATTRIBUTE_SPOTCOLOR "spotColor"
127#define DEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS "lightRadius"
Mike Klein8f4e2242019-03-20 11:59:00 -0500128
Mike Klein17428132019-03-20 13:02:32 -0500129#define DEBUGCANVAS_VERB_MOVE "move"
130#define DEBUGCANVAS_VERB_LINE "line"
131#define DEBUGCANVAS_VERB_QUAD "quad"
132#define DEBUGCANVAS_VERB_CUBIC "cubic"
133#define DEBUGCANVAS_VERB_CONIC "conic"
134#define DEBUGCANVAS_VERB_CLOSE "close"
Mike Klein8f4e2242019-03-20 11:59:00 -0500135
Mike Klein17428132019-03-20 13:02:32 -0500136#define DEBUGCANVAS_STYLE_FILL "fill"
137#define DEBUGCANVAS_STYLE_STROKE "stroke"
138#define DEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
Mike Klein8f4e2242019-03-20 11:59:00 -0500139
Mike Klein17428132019-03-20 13:02:32 -0500140#define DEBUGCANVAS_POINTMODE_POINTS "points"
141#define DEBUGCANVAS_POINTMODE_LINES "lines"
142#define DEBUGCANVAS_POINTMODE_POLYGON "polygon"
Mike Klein8f4e2242019-03-20 11:59:00 -0500143
Mike Klein17428132019-03-20 13:02:32 -0500144#define DEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
145#define DEBUGCANVAS_REGIONOP_INTERSECT "intersect"
146#define DEBUGCANVAS_REGIONOP_UNION "union"
147#define DEBUGCANVAS_REGIONOP_XOR "xor"
148#define DEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
149#define DEBUGCANVAS_REGIONOP_REPLACE "replace"
Mike Klein8f4e2242019-03-20 11:59:00 -0500150
Mike Klein17428132019-03-20 13:02:32 -0500151#define DEBUGCANVAS_BLURSTYLE_NORMAL "normal"
152#define DEBUGCANVAS_BLURSTYLE_SOLID "solid"
153#define DEBUGCANVAS_BLURSTYLE_OUTER "outer"
154#define DEBUGCANVAS_BLURSTYLE_INNER "inner"
Mike Klein8f4e2242019-03-20 11:59:00 -0500155
Mike Klein17428132019-03-20 13:02:32 -0500156#define DEBUGCANVAS_BLURQUALITY_LOW "low"
157#define DEBUGCANVAS_BLURQUALITY_HIGH "high"
Mike Klein8f4e2242019-03-20 11:59:00 -0500158
Mike Klein17428132019-03-20 13:02:32 -0500159#define DEBUGCANVAS_FILLTYPE_WINDING "winding"
160#define DEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
161#define DEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
162#define DEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
Mike Klein8f4e2242019-03-20 11:59:00 -0500163
Mike Klein17428132019-03-20 13:02:32 -0500164#define DEBUGCANVAS_CAP_BUTT "butt"
165#define DEBUGCANVAS_CAP_ROUND "round"
166#define DEBUGCANVAS_CAP_SQUARE "square"
Mike Klein8f4e2242019-03-20 11:59:00 -0500167
Mike Klein17428132019-03-20 13:02:32 -0500168#define DEBUGCANVAS_MITER_JOIN "miter"
169#define DEBUGCANVAS_ROUND_JOIN "round"
170#define DEBUGCANVAS_BEVEL_JOIN "bevel"
Mike Klein8f4e2242019-03-20 11:59:00 -0500171
Mike Klein17428132019-03-20 13:02:32 -0500172#define DEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
173#define DEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
174#define DEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
175#define DEBUGCANVAS_COLORTYPE_565 "565"
176#define DEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
177#define DEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
178#define DEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
Mike Klein8f4e2242019-03-20 11:59:00 -0500179
Mike Klein17428132019-03-20 13:02:32 -0500180#define DEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
181#define DEBUGCANVAS_ALPHATYPE_PREMUL "premul"
182#define DEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
183#define DEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
Mike Klein8f4e2242019-03-20 11:59:00 -0500184
Mike Klein17428132019-03-20 13:02:32 -0500185#define DEBUGCANVAS_FILTERQUALITY_NONE "none"
186#define DEBUGCANVAS_FILTERQUALITY_LOW "low"
187#define DEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
188#define DEBUGCANVAS_FILTERQUALITY_HIGH "high"
Mike Klein8f4e2242019-03-20 11:59:00 -0500189
Mike Klein17428132019-03-20 13:02:32 -0500190#define DEBUGCANVAS_HINTING_NONE "none"
191#define DEBUGCANVAS_HINTING_SLIGHT "slight"
192#define DEBUGCANVAS_HINTING_NORMAL "normal"
193#define DEBUGCANVAS_HINTING_FULL "full"
Mike Klein8f4e2242019-03-20 11:59:00 -0500194
Mike Klein17428132019-03-20 13:02:32 -0500195#define DEBUGCANVAS_EDGING_ALIAS "alias"
196#define DEBUGCANVAS_EDGING_ANTIALIAS "antialias"
197#define DEBUGCANVAS_EDGING_SUBPIXELANTIALIAS "subpixelantialias"
Mike Klein8f4e2242019-03-20 11:59:00 -0500198
Mike Klein17428132019-03-20 13:02:32 -0500199#define DEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC "transparentOccluder"
200#define DEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY "geometricOnly"
Mike Klein8f4e2242019-03-20 11:59:00 -0500201
202static 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
207DrawCommand::DrawCommand(OpType type) : fOpType(type), fVisible(true) {}
208
209const char* DrawCommand::GetCommandString(OpType type) {
210 switch (type) {
211 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
212 case kClear_OpType: return "DrawClear";
213 case kClipPath_OpType: return "ClipPath";
214 case kClipRegion_OpType: return "ClipRegion";
215 case kClipRect_OpType: return "ClipRect";
216 case kClipRRect_OpType: return "ClipRRect";
217 case kConcat_OpType: return "Concat";
218 case kDrawAnnotation_OpType: return "DrawAnnotation";
219 case kDrawBitmap_OpType: return "DrawBitmap";
220 case kDrawBitmapLattice_OpType: return "DrawBitmapLattice";
221 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
222 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
223 case kDrawDRRect_OpType: return "DrawDRRect";
224 case kDrawImage_OpType: return "DrawImage";
225 case kDrawImageLattice_OpType: return "DrawImageLattice";
226 case kDrawImageNine_OpType: return "DrawImageNine";
227 case kDrawImageRect_OpType: return "DrawImageRect";
228 case kDrawOval_OpType: return "DrawOval";
229 case kDrawPaint_OpType: return "DrawPaint";
230 case kDrawPatch_OpType: return "DrawPatch";
231 case kDrawPath_OpType: return "DrawPath";
232 case kDrawArc_OpType: return "DrawArc";
233 case kDrawPoints_OpType: return "DrawPoints";
234 case kDrawRect_OpType: return "DrawRect";
235 case kDrawRRect_OpType: return "DrawRRect";
236 case kDrawRegion_OpType: return "DrawRegion";
237 case kDrawShadow_OpType: return "DrawShadow";
238 case kDrawTextBlob_OpType: return "DrawTextBlob";
239 case kDrawVertices_OpType: return "DrawVertices";
240 case kDrawAtlas_OpType: return "DrawAtlas";
241 case kDrawDrawable_OpType: return "DrawDrawable";
242 case kDrawEdgeAAQuad_OpType: return "DrawEdgeAAQuad";
243 case kDrawEdgeAAImageSet_OpType: return "DrawEdgeAAImageSet";
244 case kEndDrawPicture_OpType: return "EndDrawPicture";
245 case kRestore_OpType: return "Restore";
246 case kSave_OpType: return "Save";
247 case kSaveLayer_OpType: return "SaveLayer";
248 case kSetMatrix_OpType: return "SetMatrix";
249 default:
250 SkDebugf("OpType error 0x%08x\n", type);
251 SkASSERT(0);
252 break;
253 }
254 SkDEBUGFAIL("DrawType UNUSED\n");
255 return nullptr;
256}
257
258void DrawCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein17428132019-03-20 13:02:32 -0500259 writer.appendString(DEBUGCANVAS_ATTRIBUTE_COMMAND, this->GetCommandString(fOpType));
260 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_VISIBLE, this->isVisible());
Mike Klein8f4e2242019-03-20 11:59:00 -0500261}
262
263namespace {
264
265void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
266 const SkISize& size = canvas->getBaseLayerSize();
267
268 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
269
270 canvas->translate(size.fWidth / 2.0f, size.fHeight / 2.0f);
271 if (bounds.width() > bounds.height()) {
272 canvas->scale(SkDoubleToScalar((kInsetFrac * size.fWidth) / bounds.width()),
273 SkDoubleToScalar((kInsetFrac * size.fHeight) / bounds.width()));
274 } else {
275 canvas->scale(SkDoubleToScalar((kInsetFrac * size.fWidth) / bounds.height()),
276 SkDoubleToScalar((kInsetFrac * size.fHeight) / bounds.height()));
277 }
278 canvas->translate(-bounds.centerX(), -bounds.centerY());
279}
280
281void render_path(SkCanvas* canvas, const SkPath& path) {
282 canvas->clear(0xFFFFFFFF);
283
284 const SkRect& bounds = path.getBounds();
285 if (bounds.isEmpty()) {
286 return;
287 }
288
289 SkAutoCanvasRestore acr(canvas, true);
290 xlate_and_scale_to_bounds(canvas, bounds);
291
292 SkPaint p;
293 p.setColor(SK_ColorBLACK);
294 p.setStyle(SkPaint::kStroke_Style);
295
296 canvas->drawPath(path, p);
297}
298
299void render_region(SkCanvas* canvas, const SkRegion& region) {
300 canvas->clear(0xFFFFFFFF);
301
302 const SkIRect& bounds = region.getBounds();
303 if (bounds.isEmpty()) {
304 return;
305 }
306
307 SkAutoCanvasRestore acr(canvas, true);
308 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
309
310 SkPaint p;
311 p.setColor(SK_ColorBLACK);
312 p.setStyle(SkPaint::kStroke_Style);
313
314 canvas->drawRegion(region, p);
315}
316
317void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
318 const SkISize& size = canvas->getBaseLayerSize();
319
320 SkScalar xScale = SkIntToScalar(size.fWidth - 2) / input.width();
321 SkScalar yScale = SkIntToScalar(size.fHeight - 2) / input.height();
322
323 if (input.width() > input.height()) {
324 yScale *= input.height() / (float)input.width();
325 } else {
326 xScale *= input.width() / (float)input.height();
327 }
328
329 SkRect dst = SkRect::MakeXYWH(
330 SK_Scalar1, SK_Scalar1, xScale * input.width(), yScale * input.height());
331
332 static const int kNumBlocks = 8;
333
334 canvas->clear(0xFFFFFFFF);
335 SkISize block = {canvas->imageInfo().width() / kNumBlocks,
336 canvas->imageInfo().height() / kNumBlocks};
337 for (int y = 0; y < kNumBlocks; ++y) {
338 for (int x = 0; x < kNumBlocks; ++x) {
339 SkPaint paint;
340 paint.setColor((x + y) % 2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
341 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x * block.width()),
342 SkIntToScalar(y * block.height()),
343 SkIntToScalar(block.width()),
344 SkIntToScalar(block.height()));
345 canvas->drawRect(r, paint);
346 }
347 }
348
349 canvas->drawBitmapRect(input, dst, nullptr);
350
351 if (srcRect) {
352 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
353 srcRect->fTop * yScale + SK_Scalar1,
354 srcRect->fRight * xScale + SK_Scalar1,
355 srcRect->fBottom * yScale + SK_Scalar1);
356 SkPaint p;
357 p.setColor(SK_ColorRED);
358 p.setStyle(SkPaint::kStroke_Style);
359
360 canvas->drawRect(r, p);
361 }
362}
363
364void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
365 canvas->clear(0xFFFFFFFF);
366 canvas->save();
367
368 const SkRect& bounds = rrect.getBounds();
369
370 xlate_and_scale_to_bounds(canvas, bounds);
371
372 SkPaint p;
373 p.setColor(SK_ColorBLACK);
374 p.setStyle(SkPaint::kStroke_Style);
375
376 canvas->drawRRect(rrect, p);
377 canvas->restore();
378}
379
380void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
381 canvas->clear(0xFFFFFFFF);
382 canvas->save();
383
384 const SkRect& bounds = outer.getBounds();
385
386 xlate_and_scale_to_bounds(canvas, bounds);
387
388 SkPaint p;
389 p.setColor(SK_ColorBLACK);
390 p.setStyle(SkPaint::kStroke_Style);
391
392 canvas->drawDRRect(outer, inner, p);
393 canvas->restore();
394}
395
396void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
397 canvas->clear(0xFFFFFFFF);
398
399 const SkRect& bounds = path.getBounds();
400 if (bounds.isEmpty()) {
401 return;
402 }
403
404 SkAutoCanvasRestore acr(canvas, true);
405 xlate_and_scale_to_bounds(canvas, bounds);
406
407 rec.fAmbientColor = SK_ColorBLACK;
408 rec.fSpotColor = SK_ColorBLACK;
409 canvas->private_draw_shadow_rec(path, rec);
410}
411
412static const char* const gBlendModeMap[] = {
413 "clear", "src", "dst", "srcOver", "dstOver", "srcIn", "dstIn",
414 "srcOut", "dstOut", "srcATop", "dstATop", "xor", "plus", "modulate",
415
416 "screen",
417
418 "overlay", "darken", "lighten", "colorDodge", "colorBurn", "hardLight", "softLight",
419 "difference", "exclusion", "multiply",
420
421 "hue", "saturation", "color", "luminosity",
422};
423
424static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
425 "blendMode mismatch");
426static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
427 "blendMode mismatch");
428
429void apply_paint_blend_mode(const SkPaint& paint, SkJSONWriter& writer) {
430 const auto mode = paint.getBlendMode();
431 if (mode != SkBlendMode::kSrcOver) {
432 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
Mike Klein17428132019-03-20 13:02:32 -0500433 writer.appendString(DEBUGCANVAS_ATTRIBUTE_BLENDMODE,
Mike Klein8f4e2242019-03-20 11:59:00 -0500434 gBlendModeMap[static_cast<size_t>(mode)]);
435 }
436}
437
438}; // namespace
439
440void DrawCommand::MakeJsonColor(SkJSONWriter& writer, const SkColor color) {
441 writer.beginArray(nullptr, false);
442 writer.appendS32(SkColorGetA(color));
443 writer.appendS32(SkColorGetR(color));
444 writer.appendS32(SkColorGetG(color));
445 writer.appendS32(SkColorGetB(color));
446 writer.endArray();
447}
448
449void DrawCommand::MakeJsonColor4f(SkJSONWriter& writer, const SkColor4f& color) {
450 writer.beginArray(nullptr, false);
451 writer.appendFloat(color.fA);
452 writer.appendFloat(color.fR);
453 writer.appendFloat(color.fG);
454 writer.appendFloat(color.fB);
455 writer.endArray();
456}
457
458void DrawCommand::MakeJsonPoint(SkJSONWriter& writer, const SkPoint& point) {
459 writer.beginArray(nullptr, false);
460 writer.appendFloat(point.x());
461 writer.appendFloat(point.y());
462 writer.endArray();
463}
464
465void DrawCommand::MakeJsonPoint(SkJSONWriter& writer, SkScalar x, SkScalar y) {
466 writer.beginArray(nullptr, false);
467 writer.appendFloat(x);
468 writer.appendFloat(y);
469 writer.endArray();
470}
471
472void DrawCommand::MakeJsonPoint3(SkJSONWriter& writer, const SkPoint3& point) {
473 writer.beginArray(nullptr, false);
474 writer.appendFloat(point.x());
475 writer.appendFloat(point.y());
476 writer.appendFloat(point.z());
477 writer.endArray();
478}
479
480void DrawCommand::MakeJsonRect(SkJSONWriter& writer, const SkRect& rect) {
481 writer.beginArray(nullptr, false);
482 writer.appendFloat(rect.left());
483 writer.appendFloat(rect.top());
484 writer.appendFloat(rect.right());
485 writer.appendFloat(rect.bottom());
486 writer.endArray();
487}
488
489void DrawCommand::MakeJsonIRect(SkJSONWriter& writer, const SkIRect& rect) {
490 writer.beginArray(nullptr, false);
491 writer.appendS32(rect.left());
492 writer.appendS32(rect.top());
493 writer.appendS32(rect.right());
494 writer.appendS32(rect.bottom());
495 writer.endArray();
496}
497
498static void make_json_rrect(SkJSONWriter& writer, const SkRRect& rrect) {
499 writer.beginArray(nullptr, false);
500 DrawCommand::MakeJsonRect(writer, rrect.rect());
501 DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperLeft_Corner));
502 DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kUpperRight_Corner));
503 DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerRight_Corner));
504 DrawCommand::MakeJsonPoint(writer, rrect.radii(SkRRect::kLowerLeft_Corner));
505 writer.endArray();
506}
507
508void DrawCommand::MakeJsonMatrix(SkJSONWriter& writer, const SkMatrix& matrix) {
509 writer.beginArray();
510 for (int r = 0; r < 3; ++r) {
511 writer.beginArray(nullptr, false);
512 for (int c = 0; c < 3; ++c) {
513 writer.appendFloat(matrix[r * 3 + c]);
514 }
515 writer.endArray();
516 }
517 writer.endArray();
518}
519
520void DrawCommand::MakeJsonPath(SkJSONWriter& writer, const SkPath& path) {
521 writer.beginObject();
522 switch (path.getFillType()) {
523 case SkPath::kWinding_FillType:
Mike Klein17428132019-03-20 13:02:32 -0500524 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_WINDING);
Mike Klein8f4e2242019-03-20 11:59:00 -0500525 break;
526 case SkPath::kEvenOdd_FillType:
Mike Klein17428132019-03-20 13:02:32 -0500527 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_EVENODD);
Mike Klein8f4e2242019-03-20 11:59:00 -0500528 break;
529 case SkPath::kInverseWinding_FillType:
Mike Klein17428132019-03-20 13:02:32 -0500530 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
531 DEBUGCANVAS_FILLTYPE_INVERSEWINDING);
Mike Klein8f4e2242019-03-20 11:59:00 -0500532 break;
533 case SkPath::kInverseEvenOdd_FillType:
Mike Klein17428132019-03-20 13:02:32 -0500534 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
535 DEBUGCANVAS_FILLTYPE_INVERSEEVENODD);
Mike Klein8f4e2242019-03-20 11:59:00 -0500536 break;
537 }
Mike Klein17428132019-03-20 13:02:32 -0500538 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_VERBS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500539 SkPath::Iter iter(path, false);
540 SkPoint pts[4];
541 SkPath::Verb verb;
542 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
543 if (verb == SkPath::kClose_Verb) {
Mike Klein17428132019-03-20 13:02:32 -0500544 writer.appendString(DEBUGCANVAS_VERB_CLOSE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500545 continue;
546 }
547 writer.beginObject(); // verb
548 switch (verb) {
549 case SkPath::kLine_Verb: {
Mike Klein17428132019-03-20 13:02:32 -0500550 writer.appendName(DEBUGCANVAS_VERB_LINE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500551 MakeJsonPoint(writer, pts[1]);
552 break;
553 }
554 case SkPath::kQuad_Verb: {
Mike Klein17428132019-03-20 13:02:32 -0500555 writer.beginArray(DEBUGCANVAS_VERB_QUAD);
Mike Klein8f4e2242019-03-20 11:59:00 -0500556 MakeJsonPoint(writer, pts[1]);
557 MakeJsonPoint(writer, pts[2]);
558 writer.endArray(); // quad coords
559 break;
560 }
561 case SkPath::kCubic_Verb: {
Mike Klein17428132019-03-20 13:02:32 -0500562 writer.beginArray(DEBUGCANVAS_VERB_CUBIC);
Mike Klein8f4e2242019-03-20 11:59:00 -0500563 MakeJsonPoint(writer, pts[1]);
564 MakeJsonPoint(writer, pts[2]);
565 MakeJsonPoint(writer, pts[3]);
566 writer.endArray(); // cubic coords
567 break;
568 }
569 case SkPath::kConic_Verb: {
Mike Klein17428132019-03-20 13:02:32 -0500570 writer.beginArray(DEBUGCANVAS_VERB_CONIC);
Mike Klein8f4e2242019-03-20 11:59:00 -0500571 MakeJsonPoint(writer, pts[1]);
572 MakeJsonPoint(writer, pts[2]);
573 writer.appendFloat(iter.conicWeight());
574 writer.endArray(); // conic coords
575 break;
576 }
577 case SkPath::kMove_Verb: {
Mike Klein17428132019-03-20 13:02:32 -0500578 writer.appendName(DEBUGCANVAS_VERB_MOVE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500579 MakeJsonPoint(writer, pts[0]);
580 break;
581 }
582 case SkPath::kClose_Verb:
583 case SkPath::kDone_Verb:
584 // Unreachable
585 break;
586 }
587 writer.endObject(); // verb
588 }
589 writer.endArray(); // verbs
590 writer.endObject(); // path
591}
592
593void DrawCommand::MakeJsonRegion(SkJSONWriter& writer, const SkRegion& region) {
594 // TODO: Actually serialize the rectangles, rather than just devolving to path
595 SkPath path;
596 region.getBoundaryPath(&path);
597 MakeJsonPath(writer, path);
598}
599
600static const char* regionop_name(SkClipOp op) {
601 switch (op) {
Mike Klein17428132019-03-20 13:02:32 -0500602 case kDifference_SkClipOp: return DEBUGCANVAS_REGIONOP_DIFFERENCE;
603 case kIntersect_SkClipOp: return DEBUGCANVAS_REGIONOP_INTERSECT;
604 case kUnion_SkClipOp: return DEBUGCANVAS_REGIONOP_UNION;
605 case kXOR_SkClipOp: return DEBUGCANVAS_REGIONOP_XOR;
606 case kReverseDifference_SkClipOp: return DEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE;
607 case kReplace_SkClipOp: return DEBUGCANVAS_REGIONOP_REPLACE;
Mike Klein8f4e2242019-03-20 11:59:00 -0500608 default: SkASSERT(false); return "<invalid region op>";
609 }
610}
611
612static const char* pointmode_name(SkCanvas::PointMode mode) {
613 switch (mode) {
Mike Klein17428132019-03-20 13:02:32 -0500614 case SkCanvas::kPoints_PointMode: return DEBUGCANVAS_POINTMODE_POINTS;
615 case SkCanvas::kLines_PointMode: return DEBUGCANVAS_POINTMODE_LINES;
616 case SkCanvas::kPolygon_PointMode: return DEBUGCANVAS_POINTMODE_POLYGON;
Mike Klein8f4e2242019-03-20 11:59:00 -0500617 default: SkASSERT(false); return "<invalid point mode>";
618 }
619}
620
621static void store_scalar(SkJSONWriter& writer,
622 const char* key,
623 SkScalar value,
624 SkScalar defaultValue) {
625 if (value != defaultValue) {
626 writer.appendFloat(key, value);
627 }
628}
629
630static void store_bool(SkJSONWriter& writer, const char* key, bool value, bool defaultValue) {
631 if (value != defaultValue) {
632 writer.appendBool(key, value);
633 }
634}
635
636static SkString encode_data(const void* bytes,
637 size_t count,
638 const char* contentType,
639 UrlDataManager& urlDataManager) {
640 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
641 return urlDataManager.addData(data.get(), contentType);
642}
643
644void DrawCommand::flatten(const SkFlattenable* flattenable,
645 SkJSONWriter& writer,
646 UrlDataManager& urlDataManager) {
647 SkBinaryWriteBuffer buffer;
648 flattenable->flatten(buffer);
649 void* data = sk_malloc_throw(buffer.bytesWritten());
650 buffer.writeToMemory(data);
651 SkString url =
652 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -0500653 writer.appendString(DEBUGCANVAS_ATTRIBUTE_NAME, flattenable->getTypeName());
654 writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -0500655
Mike Klein17428132019-03-20 13:02:32 -0500656 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_VALUES);
Mike Klein8f4e2242019-03-20 11:59:00 -0500657 JsonWriteBuffer jsonBuffer(&writer, &urlDataManager);
658 flattenable->flatten(jsonBuffer);
659 writer.endObject(); // values
660
661 sk_free(data);
662}
663
664void DrawCommand::WritePNG(SkBitmap bitmap, SkWStream& out) {
665 SkPixmap pm;
666 SkAssertResult(bitmap.peekPixels(&pm));
667
668 SkPngEncoder::Options options;
669 options.fZLibLevel = 1;
670 options.fFilterFlags = SkPngEncoder::FilterFlag::kNone;
671 SkPngEncoder::Encode(&out, pm, options);
672}
673
674bool DrawCommand::flatten(const SkImage& image,
675 SkJSONWriter& writer,
676 UrlDataManager& urlDataManager) {
677 size_t rowBytes = 4 * image.width();
678 SkAutoMalloc buffer(rowBytes * image.height());
679 SkImageInfo dstInfo =
680 SkImageInfo::Make(image.width(), image.height(), kN32_SkColorType, kPremul_SkAlphaType);
681 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
682 SkDebugf("readPixels failed\n");
683 return false;
684 }
685
686 SkBitmap bm;
687 bm.installPixels(dstInfo, buffer.get(), rowBytes);
688
689 SkDynamicMemoryWStream out;
690 DrawCommand::WritePNG(bm, out);
691 sk_sp<SkData> encoded = out.detachAsData();
692 SkString url = encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -0500693 writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -0500694 return true;
695}
696
697static const char* color_type_name(SkColorType colorType) {
698 switch (colorType) {
Mike Klein17428132019-03-20 13:02:32 -0500699 case kARGB_4444_SkColorType: return DEBUGCANVAS_COLORTYPE_ARGB4444;
700 case kRGBA_8888_SkColorType: return DEBUGCANVAS_COLORTYPE_RGBA8888;
701 case kBGRA_8888_SkColorType: return DEBUGCANVAS_COLORTYPE_BGRA8888;
702 case kRGB_565_SkColorType: return DEBUGCANVAS_COLORTYPE_565;
703 case kGray_8_SkColorType: return DEBUGCANVAS_COLORTYPE_GRAY8;
704 case kAlpha_8_SkColorType: return DEBUGCANVAS_COLORTYPE_ALPHA8;
705 default: SkASSERT(false); return DEBUGCANVAS_COLORTYPE_RGBA8888;
Mike Klein8f4e2242019-03-20 11:59:00 -0500706 }
707}
708
709static const char* alpha_type_name(SkAlphaType alphaType) {
710 switch (alphaType) {
Mike Klein17428132019-03-20 13:02:32 -0500711 case kOpaque_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_OPAQUE;
712 case kPremul_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_PREMUL;
713 case kUnpremul_SkAlphaType: return DEBUGCANVAS_ALPHATYPE_UNPREMUL;
714 default: SkASSERT(false); return DEBUGCANVAS_ALPHATYPE_OPAQUE;
Mike Klein8f4e2242019-03-20 11:59:00 -0500715 }
716}
717
718bool DrawCommand::flatten(const SkBitmap& bitmap,
719 SkJSONWriter& writer,
720 UrlDataManager& urlDataManager) {
721 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
Mike Klein17428132019-03-20 13:02:32 -0500722 writer.appendString(DEBUGCANVAS_ATTRIBUTE_COLOR, color_type_name(bitmap.colorType()));
723 writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, alpha_type_name(bitmap.alphaType()));
Mike Klein8f4e2242019-03-20 11:59:00 -0500724 bool success = flatten(*image, writer, urlDataManager);
725 return success;
726}
727
728static void apply_font_hinting(const SkFont& font, SkJSONWriter& writer) {
729 SkFontHinting hinting = font.getHinting();
730 if (hinting != SkPaintDefaults_Hinting) {
731 switch (hinting) {
Ben Wagner5785e4a2019-05-07 16:50:29 -0400732 case SkFontHinting::kNone:
Mike Klein17428132019-03-20 13:02:32 -0500733 writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_NONE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500734 break;
Ben Wagner5785e4a2019-05-07 16:50:29 -0400735 case SkFontHinting::kSlight:
Mike Klein17428132019-03-20 13:02:32 -0500736 writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_SLIGHT);
Mike Klein8f4e2242019-03-20 11:59:00 -0500737 break;
Ben Wagner5785e4a2019-05-07 16:50:29 -0400738 case SkFontHinting::kNormal:
Mike Klein17428132019-03-20 13:02:32 -0500739 writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_NORMAL);
Mike Klein8f4e2242019-03-20 11:59:00 -0500740 break;
Ben Wagner5785e4a2019-05-07 16:50:29 -0400741 case SkFontHinting::kFull:
Mike Klein17428132019-03-20 13:02:32 -0500742 writer.appendString(DEBUGCANVAS_ATTRIBUTE_HINTING, DEBUGCANVAS_HINTING_FULL);
Mike Klein8f4e2242019-03-20 11:59:00 -0500743 break;
744 }
745 }
746}
747
748static void apply_font_edging(const SkFont& font, SkJSONWriter& writer) {
749 switch (font.getEdging()) {
750 case SkFont::Edging::kAlias:
Mike Klein17428132019-03-20 13:02:32 -0500751 writer.appendString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_ALIAS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500752 break;
753 case SkFont::Edging::kAntiAlias:
Mike Klein17428132019-03-20 13:02:32 -0500754 writer.appendString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_ANTIALIAS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500755 break;
756 case SkFont::Edging::kSubpixelAntiAlias:
Mike Klein17428132019-03-20 13:02:32 -0500757 writer.appendString(DEBUGCANVAS_ATTRIBUTE_EDGING, DEBUGCANVAS_EDGING_SUBPIXELANTIALIAS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500758 break;
759 }
760}
761
762static void apply_paint_color(const SkPaint& paint, SkJSONWriter& writer) {
763 SkColor color = paint.getColor();
764 if (color != SK_ColorBLACK) {
Mike Klein17428132019-03-20 13:02:32 -0500765 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COLOR);
Mike Klein8f4e2242019-03-20 11:59:00 -0500766 DrawCommand::MakeJsonColor(writer, color);
767 }
768}
769
770static void apply_paint_style(const SkPaint& paint, SkJSONWriter& writer) {
771 SkPaint::Style style = paint.getStyle();
772 if (style != SkPaint::kFill_Style) {
773 switch (style) {
774 case SkPaint::kStroke_Style: {
Mike Klein17428132019-03-20 13:02:32 -0500775 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_STYLE_STROKE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500776 break;
777 }
778 case SkPaint::kStrokeAndFill_Style: {
Mike Klein17428132019-03-20 13:02:32 -0500779 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_STYLE_STROKEANDFILL);
Mike Klein8f4e2242019-03-20 11:59:00 -0500780 break;
781 }
782 default: SkASSERT(false);
783 }
784 }
785}
786
787static void apply_paint_cap(const SkPaint& paint, SkJSONWriter& writer) {
788 SkPaint::Cap cap = paint.getStrokeCap();
789 if (cap != SkPaint::kDefault_Cap) {
790 switch (cap) {
791 case SkPaint::kButt_Cap:
Mike Klein17428132019-03-20 13:02:32 -0500792 writer.appendString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_BUTT);
Mike Klein8f4e2242019-03-20 11:59:00 -0500793 break;
794 case SkPaint::kRound_Cap:
Mike Klein17428132019-03-20 13:02:32 -0500795 writer.appendString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_ROUND);
Mike Klein8f4e2242019-03-20 11:59:00 -0500796 break;
797 case SkPaint::kSquare_Cap:
Mike Klein17428132019-03-20 13:02:32 -0500798 writer.appendString(DEBUGCANVAS_ATTRIBUTE_CAP, DEBUGCANVAS_CAP_SQUARE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500799 break;
800 default: SkASSERT(false);
801 }
802 }
803}
804
805static void apply_paint_join(const SkPaint& paint, SkJSONWriter& writer) {
806 SkPaint::Join join = paint.getStrokeJoin();
807 if (join != SkPaint::kDefault_Join) {
808 switch (join) {
809 case SkPaint::kMiter_Join:
Mike Klein17428132019-03-20 13:02:32 -0500810 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_MITER_JOIN);
Mike Klein8f4e2242019-03-20 11:59:00 -0500811 break;
812 case SkPaint::kRound_Join:
Mike Klein17428132019-03-20 13:02:32 -0500813 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_ROUND_JOIN);
Mike Klein8f4e2242019-03-20 11:59:00 -0500814 break;
815 case SkPaint::kBevel_Join:
Mike Klein17428132019-03-20 13:02:32 -0500816 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STROKEJOIN, DEBUGCANVAS_BEVEL_JOIN);
Mike Klein8f4e2242019-03-20 11:59:00 -0500817 break;
818 default: SkASSERT(false);
819 }
820 }
821}
822
823static void apply_paint_filterquality(const SkPaint& paint, SkJSONWriter& writer) {
824 SkFilterQuality quality = paint.getFilterQuality();
825 switch (quality) {
826 case kNone_SkFilterQuality: break;
827 case kLow_SkFilterQuality:
Mike Klein17428132019-03-20 13:02:32 -0500828 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY, DEBUGCANVAS_FILTERQUALITY_LOW);
Mike Klein8f4e2242019-03-20 11:59:00 -0500829 break;
830 case kMedium_SkFilterQuality:
Mike Klein17428132019-03-20 13:02:32 -0500831 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
832 DEBUGCANVAS_FILTERQUALITY_MEDIUM);
Mike Klein8f4e2242019-03-20 11:59:00 -0500833 break;
834 case kHigh_SkFilterQuality:
Mike Klein17428132019-03-20 13:02:32 -0500835 writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILTERQUALITY,
836 DEBUGCANVAS_FILTERQUALITY_HIGH);
Mike Klein8f4e2242019-03-20 11:59:00 -0500837 break;
838 }
839}
840
841static void apply_paint_maskfilter(const SkPaint& paint,
842 SkJSONWriter& writer,
843 UrlDataManager& urlDataManager) {
844 SkMaskFilter* maskFilter = paint.getMaskFilter();
845 if (maskFilter != nullptr) {
846 SkMaskFilterBase::BlurRec blurRec;
847 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
Mike Klein17428132019-03-20 13:02:32 -0500848 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BLUR);
849 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_SIGMA, blurRec.fSigma);
Mike Klein8f4e2242019-03-20 11:59:00 -0500850 switch (blurRec.fStyle) {
851 case SkBlurStyle::kNormal_SkBlurStyle:
Mike Klein17428132019-03-20 13:02:32 -0500852 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_NORMAL);
Mike Klein8f4e2242019-03-20 11:59:00 -0500853 break;
854 case SkBlurStyle::kSolid_SkBlurStyle:
Mike Klein17428132019-03-20 13:02:32 -0500855 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_SOLID);
Mike Klein8f4e2242019-03-20 11:59:00 -0500856 break;
857 case SkBlurStyle::kOuter_SkBlurStyle:
Mike Klein17428132019-03-20 13:02:32 -0500858 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_OUTER);
Mike Klein8f4e2242019-03-20 11:59:00 -0500859 break;
860 case SkBlurStyle::kInner_SkBlurStyle:
Mike Klein17428132019-03-20 13:02:32 -0500861 writer.appendString(DEBUGCANVAS_ATTRIBUTE_STYLE, DEBUGCANVAS_BLURSTYLE_INNER);
Mike Klein8f4e2242019-03-20 11:59:00 -0500862 break;
863 default: SkASSERT(false);
864 }
865 writer.endObject(); // blur
866 } else {
Mike Klein17428132019-03-20 13:02:32 -0500867 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_MASKFILTER);
Mike Klein8f4e2242019-03-20 11:59:00 -0500868 DrawCommand::flatten(maskFilter, writer, urlDataManager);
869 writer.endObject(); // maskFilter
870 }
871 }
872}
873
874static void apply_paint_patheffect(const SkPaint& paint,
875 SkJSONWriter& writer,
876 UrlDataManager& urlDataManager) {
877 SkPathEffect* pathEffect = paint.getPathEffect();
878 if (pathEffect != nullptr) {
879 SkPathEffect::DashInfo dashInfo;
880 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
881 if (dashType == SkPathEffect::kDash_DashType) {
882 dashInfo.fIntervals = (SkScalar*)sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
883 pathEffect->asADash(&dashInfo);
Mike Klein17428132019-03-20 13:02:32 -0500884 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_DASHING);
885 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_INTERVALS, false);
Mike Klein8f4e2242019-03-20 11:59:00 -0500886 for (int32_t i = 0; i < dashInfo.fCount; i++) {
887 writer.appendFloat(dashInfo.fIntervals[i]);
888 }
889 writer.endArray(); // intervals
890 sk_free(dashInfo.fIntervals);
Mike Klein17428132019-03-20 13:02:32 -0500891 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_PHASE, dashInfo.fPhase);
Mike Klein8f4e2242019-03-20 11:59:00 -0500892 writer.endObject(); // dashing
893 } else {
Mike Klein17428132019-03-20 13:02:32 -0500894 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_PATHEFFECT);
Mike Klein8f4e2242019-03-20 11:59:00 -0500895 DrawCommand::flatten(pathEffect, writer, urlDataManager);
896 writer.endObject(); // pathEffect
897 }
898 }
899}
900
901static void apply_font_typeface(const SkFont& font,
902 SkJSONWriter& writer,
903 UrlDataManager& urlDataManager) {
904 SkTypeface* typeface = font.getTypefaceOrDefault();
905 if (typeface != nullptr) {
Mike Klein17428132019-03-20 13:02:32 -0500906 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_TYPEFACE);
Mike Klein8f4e2242019-03-20 11:59:00 -0500907 SkDynamicMemoryWStream buffer;
908 typeface->serialize(&buffer);
909 void* data = sk_malloc_throw(buffer.bytesWritten());
910 buffer.copyTo(data);
911 SkString url = encode_data(
912 data, buffer.bytesWritten(), "application/octet-stream", urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -0500913 writer.appendString(DEBUGCANVAS_ATTRIBUTE_DATA, url.c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -0500914 sk_free(data);
915 writer.endObject();
916 }
917}
918
919static void apply_flattenable(const char* key,
920 SkFlattenable* flattenable,
921 SkJSONWriter& writer,
922 UrlDataManager& urlDataManager) {
923 if (flattenable != nullptr) {
924 writer.beginObject(key);
925 DrawCommand::flatten(flattenable, writer, urlDataManager);
926 writer.endObject();
927 }
928}
929
930void DrawCommand::MakeJsonPaint(SkJSONWriter& writer,
931 const SkPaint& paint,
932 UrlDataManager& urlDataManager) {
933 writer.beginObject();
Mike Klein17428132019-03-20 13:02:32 -0500934 store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
Mike Klein8f4e2242019-03-20 11:59:00 -0500935 store_scalar(writer,
Mike Klein17428132019-03-20 13:02:32 -0500936 DEBUGCANVAS_ATTRIBUTE_STROKEMITER,
Mike Klein8f4e2242019-03-20 11:59:00 -0500937 paint.getStrokeMiter(),
938 SkPaintDefaults_MiterLimit);
Mike Klein17428132019-03-20 13:02:32 -0500939 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
940 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Mike Klein8f4e2242019-03-20 11:59:00 -0500941
942 apply_paint_color(paint, writer);
943 apply_paint_style(paint, writer);
944 apply_paint_blend_mode(paint, writer);
945 apply_paint_cap(paint, writer);
946 apply_paint_join(paint, writer);
947 apply_paint_filterquality(paint, writer);
948 apply_paint_patheffect(paint, writer, urlDataManager);
949 apply_paint_maskfilter(paint, writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -0500950 apply_flattenable(DEBUGCANVAS_ATTRIBUTE_SHADER, paint.getShader(), writer, urlDataManager);
951 apply_flattenable(DEBUGCANVAS_ATTRIBUTE_LOOPER, paint.getLooper(), writer, urlDataManager);
Mike Klein8f4e2242019-03-20 11:59:00 -0500952 apply_flattenable(
Mike Klein17428132019-03-20 13:02:32 -0500953 DEBUGCANVAS_ATTRIBUTE_IMAGEFILTER, paint.getImageFilter(), writer, urlDataManager);
Mike Klein8f4e2242019-03-20 11:59:00 -0500954 apply_flattenable(
Mike Klein17428132019-03-20 13:02:32 -0500955 DEBUGCANVAS_ATTRIBUTE_COLORFILTER, paint.getColorFilter(), writer, urlDataManager);
Mike Klein8f4e2242019-03-20 11:59:00 -0500956 writer.endObject(); // paint
957}
958
959static void MakeJsonFont(const SkFont& font, SkJSONWriter& writer, UrlDataManager& urlDataManager) {
960 writer.beginObject();
Mike Klein17428132019-03-20 13:02:32 -0500961 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, font.isEmbolden(), false);
962 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_LINEARTEXT, font.isLinearMetrics(), false);
963 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, font.isSubpixel(), false);
964 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, font.isEmbeddedBitmaps(), false);
965 store_bool(writer, DEBUGCANVAS_ATTRIBUTE_AUTOHINTING, font.isForceAutoHinting(), false);
Mike Klein8f4e2242019-03-20 11:59:00 -0500966
Mike Klein17428132019-03-20 13:02:32 -0500967 store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSIZE, font.getSize(), SkPaintDefaults_TextSize);
968 store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getScaleX(), SK_Scalar1);
969 store_scalar(writer, DEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, font.getSkewX(), 0.0f);
Mike Klein8f4e2242019-03-20 11:59:00 -0500970 apply_font_edging(font, writer);
971 apply_font_hinting(font, writer);
972 apply_font_typeface(font, writer, urlDataManager);
973 writer.endObject(); // font
974}
975
976void DrawCommand::MakeJsonLattice(SkJSONWriter& writer, const SkCanvas::Lattice& lattice) {
977 writer.beginObject();
Mike Klein17428132019-03-20 13:02:32 -0500978 writer.appendS32(DEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT, lattice.fXCount);
979 writer.appendS32(DEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT, lattice.fYCount);
Mike Klein8f4e2242019-03-20 11:59:00 -0500980 if (nullptr != lattice.fBounds) {
Mike Klein17428132019-03-20 13:02:32 -0500981 writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500982 MakeJsonIRect(writer, *lattice.fBounds);
983 }
Mike Klein17428132019-03-20 13:02:32 -0500984 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500985 for (int i = 0; i < lattice.fXCount; i++) {
986 writer.appendS32(lattice.fXDivs[i]);
987 }
988 writer.endArray(); // xdivs
Mike Klein17428132019-03-20 13:02:32 -0500989 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500990 for (int i = 0; i < lattice.fYCount; i++) {
991 writer.appendS32(lattice.fYDivs[i]);
992 }
993 writer.endArray(); // ydivs
994 if (nullptr != lattice.fRectTypes) {
Mike Klein17428132019-03-20 13:02:32 -0500995 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS);
Mike Klein8f4e2242019-03-20 11:59:00 -0500996 int flagCount = 0;
997 for (int row = 0; row < lattice.fYCount + 1; row++) {
998 writer.beginArray();
999 for (int column = 0; column < lattice.fXCount + 1; column++) {
1000 writer.appendS32(lattice.fRectTypes[flagCount++]);
1001 }
1002 writer.endArray(); // row
1003 }
1004 writer.endArray();
1005 }
1006 writer.endObject();
1007}
1008
Mike Klein17428132019-03-20 13:02:32 -05001009ClearCommand::ClearCommand(SkColor color) : INHERITED(kClear_OpType) { fColor = color; }
Mike Klein8f4e2242019-03-20 11:59:00 -05001010
Mike Klein17428132019-03-20 13:02:32 -05001011void ClearCommand::execute(SkCanvas* canvas) const { canvas->clear(fColor); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001012
Mike Klein17428132019-03-20 13:02:32 -05001013void ClearCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001014 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001015 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COLOR);
Mike Klein8f4e2242019-03-20 11:59:00 -05001016 MakeJsonColor(writer, fColor);
1017}
1018
Mike Klein17428132019-03-20 13:02:32 -05001019ClipPathCommand::ClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
Mike Klein8f4e2242019-03-20 11:59:00 -05001020 : INHERITED(kClipPath_OpType) {
1021 fPath = path;
1022 fOp = op;
1023 fDoAA = doAA;
1024}
1025
Mike Klein17428132019-03-20 13:02:32 -05001026void ClipPathCommand::execute(SkCanvas* canvas) const { canvas->clipPath(fPath, fOp, fDoAA); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001027
Mike Klein17428132019-03-20 13:02:32 -05001028bool ClipPathCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001029 render_path(canvas, fPath);
1030 return true;
1031}
1032
Mike Klein17428132019-03-20 13:02:32 -05001033void ClipPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001034 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001035 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
Mike Klein8f4e2242019-03-20 11:59:00 -05001036 MakeJsonPath(writer, fPath);
Mike Klein17428132019-03-20 13:02:32 -05001037 writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1038 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
Mike Klein8f4e2242019-03-20 11:59:00 -05001039}
1040
Mike Klein17428132019-03-20 13:02:32 -05001041ClipRegionCommand::ClipRegionCommand(const SkRegion& region, SkClipOp op)
Mike Klein8f4e2242019-03-20 11:59:00 -05001042 : INHERITED(kClipRegion_OpType) {
1043 fRegion = region;
1044 fOp = op;
1045}
1046
Mike Klein17428132019-03-20 13:02:32 -05001047void ClipRegionCommand::execute(SkCanvas* canvas) const { canvas->clipRegion(fRegion, fOp); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001048
Mike Klein17428132019-03-20 13:02:32 -05001049void ClipRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001050 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001051 writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
Mike Klein8f4e2242019-03-20 11:59:00 -05001052 MakeJsonRegion(writer, fRegion);
Mike Klein17428132019-03-20 13:02:32 -05001053 writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
Mike Klein8f4e2242019-03-20 11:59:00 -05001054}
1055
Mike Klein17428132019-03-20 13:02:32 -05001056ClipRectCommand::ClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
Mike Klein8f4e2242019-03-20 11:59:00 -05001057 : INHERITED(kClipRect_OpType) {
1058 fRect = rect;
1059 fOp = op;
1060 fDoAA = doAA;
1061}
1062
Mike Klein17428132019-03-20 13:02:32 -05001063void ClipRectCommand::execute(SkCanvas* canvas) const { canvas->clipRect(fRect, fOp, fDoAA); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001064
Mike Klein17428132019-03-20 13:02:32 -05001065void ClipRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001066 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001067 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001068 MakeJsonRect(writer, fRect);
Mike Klein17428132019-03-20 13:02:32 -05001069 writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1070 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
Mike Klein8f4e2242019-03-20 11:59:00 -05001071
1072 SkString desc;
Mike Klein17428132019-03-20 13:02:32 -05001073 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fRect)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001074}
1075
Mike Klein17428132019-03-20 13:02:32 -05001076ClipRRectCommand::ClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
Mike Klein8f4e2242019-03-20 11:59:00 -05001077 : INHERITED(kClipRRect_OpType) {
1078 fRRect = rrect;
1079 fOp = op;
1080 fDoAA = doAA;
1081}
1082
Mike Klein17428132019-03-20 13:02:32 -05001083void ClipRRectCommand::execute(SkCanvas* canvas) const { canvas->clipRRect(fRRect, fOp, fDoAA); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001084
Mike Klein17428132019-03-20 13:02:32 -05001085bool ClipRRectCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001086 render_rrect(canvas, fRRect);
1087 return true;
1088}
1089
Mike Klein17428132019-03-20 13:02:32 -05001090void ClipRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001091 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001092 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001093 make_json_rrect(writer, fRRect);
Mike Klein17428132019-03-20 13:02:32 -05001094 writer.appendString(DEBUGCANVAS_ATTRIBUTE_REGIONOP, regionop_name(fOp));
1095 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_ANTIALIAS, fDoAA);
Mike Klein8f4e2242019-03-20 11:59:00 -05001096}
1097
Mike Klein17428132019-03-20 13:02:32 -05001098ConcatCommand::ConcatCommand(const SkMatrix& matrix) : INHERITED(kConcat_OpType) {
Mike Klein8f4e2242019-03-20 11:59:00 -05001099 fMatrix = matrix;
1100}
1101
Mike Klein17428132019-03-20 13:02:32 -05001102void ConcatCommand::execute(SkCanvas* canvas) const { canvas->concat(fMatrix); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001103
Mike Klein17428132019-03-20 13:02:32 -05001104void ConcatCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001105 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001106 writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
Mike Klein8f4e2242019-03-20 11:59:00 -05001107 MakeJsonMatrix(writer, fMatrix);
1108}
1109
1110////
1111
Mike Klein17428132019-03-20 13:02:32 -05001112DrawAnnotationCommand::DrawAnnotationCommand(const SkRect& rect,
1113 const char key[],
1114 sk_sp<SkData> value)
Mike Klein8f4e2242019-03-20 11:59:00 -05001115 : INHERITED(kDrawAnnotation_OpType), fRect(rect), fKey(key), fValue(std::move(value)) {}
1116
Mike Klein17428132019-03-20 13:02:32 -05001117void DrawAnnotationCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001118 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1119}
1120
Mike Klein17428132019-03-20 13:02:32 -05001121void DrawAnnotationCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001122 INHERITED::toJSON(writer, urlDataManager);
1123
Mike Klein17428132019-03-20 13:02:32 -05001124 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001125 MakeJsonRect(writer, fRect);
1126 writer.appendString("key", fKey.c_str());
1127 if (fValue.get()) {
1128 // TODO: dump out the "value"
1129 }
1130
1131 SkString desc;
1132 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
Mike Klein17428132019-03-20 13:02:32 -05001133 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, desc.c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001134}
1135
1136////
1137
Mike Klein17428132019-03-20 13:02:32 -05001138DrawBitmapCommand::DrawBitmapCommand(const SkBitmap& bitmap,
1139 SkScalar left,
1140 SkScalar top,
1141 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001142 : INHERITED(kDrawBitmap_OpType), fBitmap(bitmap), fLeft(left), fTop(top), fPaint(paint) {}
1143
Mike Klein17428132019-03-20 13:02:32 -05001144void DrawBitmapCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001145 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaint.getMaybeNull());
1146}
1147
Mike Klein17428132019-03-20 13:02:32 -05001148bool DrawBitmapCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001149 render_bitmap(canvas, fBitmap);
1150 return true;
1151}
1152
Mike Klein17428132019-03-20 13:02:32 -05001153void DrawBitmapCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001154 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001155 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
Mike Klein8f4e2242019-03-20 11:59:00 -05001156 flatten(fBitmap, writer, urlDataManager);
1157 writer.endObject();
Mike Klein17428132019-03-20 13:02:32 -05001158 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001159 MakeJsonPoint(writer, fLeft, fTop);
1160 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001161 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001162 MakeJsonPaint(writer, *fPaint, urlDataManager);
1163 }
1164}
1165
Mike Klein17428132019-03-20 13:02:32 -05001166DrawBitmapLatticeCommand::DrawBitmapLatticeCommand(const SkBitmap& bitmap,
1167 const SkCanvas::Lattice& lattice,
1168 const SkRect& dst,
1169 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001170 : INHERITED(kDrawBitmapLattice_OpType)
1171 , fBitmap(bitmap)
1172 , fLattice(lattice)
1173 , fDst(dst)
1174 , fPaint(paint) {}
1175
Mike Klein17428132019-03-20 13:02:32 -05001176void DrawBitmapLatticeCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001177 canvas->drawBitmapLattice(fBitmap, fLattice, fDst, fPaint.getMaybeNull());
1178}
1179
Mike Klein17428132019-03-20 13:02:32 -05001180bool DrawBitmapLatticeCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001181 SkAutoCanvasRestore acr(canvas, true);
1182 canvas->clear(0xFFFFFFFF);
1183
1184 xlate_and_scale_to_bounds(canvas, fDst);
1185
1186 this->execute(canvas);
1187 return true;
1188}
1189
Mike Klein17428132019-03-20 13:02:32 -05001190void DrawBitmapLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001191 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001192 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
Mike Klein8f4e2242019-03-20 11:59:00 -05001193 flatten(fBitmap, writer, urlDataManager);
1194 writer.endObject(); // bitmap
1195
Mike Klein17428132019-03-20 13:02:32 -05001196 writer.appendName(DEBUGCANVAS_ATTRIBUTE_LATTICE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001197 MakeJsonLattice(writer, fLattice);
Mike Klein17428132019-03-20 13:02:32 -05001198 writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
Mike Klein8f4e2242019-03-20 11:59:00 -05001199 MakeJsonRect(writer, fDst);
1200 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001201 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001202 MakeJsonPaint(writer, *fPaint, urlDataManager);
1203 }
1204
1205 SkString desc;
Mike Klein17428132019-03-20 13:02:32 -05001206 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001207}
1208
Mike Klein17428132019-03-20 13:02:32 -05001209DrawBitmapNineCommand::DrawBitmapNineCommand(const SkBitmap& bitmap,
1210 const SkIRect& center,
1211 const SkRect& dst,
1212 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001213 : INHERITED(kDrawBitmapNine_OpType)
1214 , fBitmap(bitmap)
1215 , fCenter(center)
1216 , fDst(dst)
1217 , fPaint(paint) {}
1218
Mike Klein17428132019-03-20 13:02:32 -05001219void DrawBitmapNineCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001220 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaint.getMaybeNull());
1221}
1222
Mike Klein17428132019-03-20 13:02:32 -05001223bool DrawBitmapNineCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001224 SkRect tmp = SkRect::Make(fCenter);
1225 render_bitmap(canvas, fBitmap, &tmp);
1226 return true;
1227}
1228
Mike Klein17428132019-03-20 13:02:32 -05001229void DrawBitmapNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001230 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001231 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
Mike Klein8f4e2242019-03-20 11:59:00 -05001232 flatten(fBitmap, writer, urlDataManager);
1233 writer.endObject(); // bitmap
1234
Mike Klein17428132019-03-20 13:02:32 -05001235 writer.appendName(DEBUGCANVAS_ATTRIBUTE_CENTER);
Mike Klein8f4e2242019-03-20 11:59:00 -05001236 MakeJsonIRect(writer, fCenter);
Mike Klein17428132019-03-20 13:02:32 -05001237 writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
Mike Klein8f4e2242019-03-20 11:59:00 -05001238 MakeJsonRect(writer, fDst);
1239 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001240 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001241 MakeJsonPaint(writer, *fPaint, urlDataManager);
1242 }
1243}
1244
Mike Klein17428132019-03-20 13:02:32 -05001245DrawBitmapRectCommand::DrawBitmapRectCommand(const SkBitmap& bitmap,
1246 const SkRect* src,
1247 const SkRect& dst,
1248 const SkPaint* paint,
1249 SkCanvas::SrcRectConstraint constraint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001250 : INHERITED(kDrawBitmapRect_OpType)
1251 , fBitmap(bitmap)
1252 , fSrc(src)
1253 , fDst(dst)
1254 , fPaint(paint)
1255 , fConstraint(constraint) {}
1256
Mike Klein17428132019-03-20 13:02:32 -05001257void DrawBitmapRectCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001258 canvas->legacy_drawBitmapRect(
1259 fBitmap, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), fConstraint);
1260}
1261
Mike Klein17428132019-03-20 13:02:32 -05001262bool DrawBitmapRectCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001263 render_bitmap(canvas, fBitmap, fSrc.getMaybeNull());
1264 return true;
1265}
1266
Mike Klein17428132019-03-20 13:02:32 -05001267void DrawBitmapRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001268 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001269 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BITMAP);
Mike Klein8f4e2242019-03-20 11:59:00 -05001270 flatten(fBitmap, writer, urlDataManager);
1271 writer.endObject(); // bitmap
1272
1273 if (fSrc.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001274 writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
Mike Klein8f4e2242019-03-20 11:59:00 -05001275 MakeJsonRect(writer, *fSrc);
1276 }
Mike Klein17428132019-03-20 13:02:32 -05001277 writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
Mike Klein8f4e2242019-03-20 11:59:00 -05001278 MakeJsonRect(writer, fDst);
1279 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001280 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001281 MakeJsonPaint(writer, *fPaint, urlDataManager);
1282 }
1283 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
Mike Klein17428132019-03-20 13:02:32 -05001284 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_STRICT, true);
Mike Klein8f4e2242019-03-20 11:59:00 -05001285 }
1286
1287 SkString desc;
Mike Klein17428132019-03-20 13:02:32 -05001288 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001289}
1290
Mike Klein17428132019-03-20 13:02:32 -05001291DrawImageCommand::DrawImageCommand(const SkImage* image,
1292 SkScalar left,
1293 SkScalar top,
1294 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001295 : INHERITED(kDrawImage_OpType)
1296 , fImage(SkRef(image))
1297 , fLeft(left)
1298 , fTop(top)
1299 , fPaint(paint) {}
1300
Mike Klein17428132019-03-20 13:02:32 -05001301void DrawImageCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001302 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
1303}
1304
Mike Klein17428132019-03-20 13:02:32 -05001305bool DrawImageCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001306 SkAutoCanvasRestore acr(canvas, true);
1307 canvas->clear(0xFFFFFFFF);
1308
1309 xlate_and_scale_to_bounds(
1310 canvas,
1311 SkRect::MakeXYWH(
1312 fLeft, fTop, SkIntToScalar(fImage->width()), SkIntToScalar(fImage->height())));
1313 this->execute(canvas);
1314 return true;
1315}
1316
Mike Klein17428132019-03-20 13:02:32 -05001317void DrawImageCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001318 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001319 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001320 flatten(*fImage, writer, urlDataManager);
1321 writer.endObject(); // image
1322
Mike Klein17428132019-03-20 13:02:32 -05001323 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001324 MakeJsonPoint(writer, fLeft, fTop);
1325 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001326 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001327 MakeJsonPaint(writer, *fPaint, urlDataManager);
1328 }
1329
Mike Klein17428132019-03-20 13:02:32 -05001330 writer.appendU32(DEBUGCANVAS_ATTRIBUTE_UNIQUE_ID, fImage->uniqueID());
1331 writer.appendS32(DEBUGCANVAS_ATTRIBUTE_WIDTH, fImage->width());
1332 writer.appendS32(DEBUGCANVAS_ATTRIBUTE_HEIGHT, fImage->height());
Mike Klein8f4e2242019-03-20 11:59:00 -05001333 switch (fImage->alphaType()) {
1334 case kOpaque_SkAlphaType:
Mike Klein17428132019-03-20 13:02:32 -05001335 writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_OPAQUE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001336 break;
1337 case kPremul_SkAlphaType:
Mike Klein17428132019-03-20 13:02:32 -05001338 writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_PREMUL);
Mike Klein8f4e2242019-03-20 11:59:00 -05001339 break;
1340 case kUnpremul_SkAlphaType:
Mike Klein17428132019-03-20 13:02:32 -05001341 writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_UNPREMUL);
Mike Klein8f4e2242019-03-20 11:59:00 -05001342 break;
1343 default:
Mike Klein17428132019-03-20 13:02:32 -05001344 writer.appendString(DEBUGCANVAS_ATTRIBUTE_ALPHA, DEBUGCANVAS_ALPHATYPE_UNKNOWN);
Mike Klein8f4e2242019-03-20 11:59:00 -05001345 break;
1346 }
1347}
1348
Mike Klein17428132019-03-20 13:02:32 -05001349DrawImageLatticeCommand::DrawImageLatticeCommand(const SkImage* image,
1350 const SkCanvas::Lattice& lattice,
1351 const SkRect& dst,
1352 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001353 : INHERITED(kDrawImageLattice_OpType)
1354 , fImage(SkRef(image))
1355 , fLattice(lattice)
1356 , fDst(dst)
1357 , fPaint(paint) {}
1358
Mike Klein17428132019-03-20 13:02:32 -05001359void DrawImageLatticeCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001360 canvas->drawImageLattice(fImage.get(), fLattice, fDst, fPaint.getMaybeNull());
1361}
1362
Mike Klein17428132019-03-20 13:02:32 -05001363bool DrawImageLatticeCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001364 SkAutoCanvasRestore acr(canvas, true);
1365 canvas->clear(0xFFFFFFFF);
1366
1367 xlate_and_scale_to_bounds(canvas, fDst);
1368
1369 this->execute(canvas);
1370 return true;
1371}
1372
Mike Klein17428132019-03-20 13:02:32 -05001373void DrawImageLatticeCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001374 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001375 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001376 flatten(*fImage, writer, urlDataManager);
1377 writer.endObject(); // image
1378
Mike Klein17428132019-03-20 13:02:32 -05001379 writer.appendName(DEBUGCANVAS_ATTRIBUTE_LATTICE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001380 MakeJsonLattice(writer, fLattice);
Mike Klein17428132019-03-20 13:02:32 -05001381 writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
Mike Klein8f4e2242019-03-20 11:59:00 -05001382 MakeJsonRect(writer, fDst);
1383 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001384 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001385 MakeJsonPaint(writer, *fPaint, urlDataManager);
1386 }
1387
1388 SkString desc;
Mike Klein17428132019-03-20 13:02:32 -05001389 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001390}
1391
Mike Klein17428132019-03-20 13:02:32 -05001392DrawImageRectCommand::DrawImageRectCommand(const SkImage* image,
1393 const SkRect* src,
1394 const SkRect& dst,
1395 const SkPaint* paint,
1396 SkCanvas::SrcRectConstraint constraint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001397 : INHERITED(kDrawImageRect_OpType)
1398 , fImage(SkRef(image))
1399 , fSrc(src)
1400 , fDst(dst)
1401 , fPaint(paint)
1402 , fConstraint(constraint) {}
1403
Mike Klein17428132019-03-20 13:02:32 -05001404void DrawImageRectCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001405 canvas->legacy_drawImageRect(
1406 fImage.get(), fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), fConstraint);
1407}
1408
Mike Klein17428132019-03-20 13:02:32 -05001409bool DrawImageRectCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001410 SkAutoCanvasRestore acr(canvas, true);
1411 canvas->clear(0xFFFFFFFF);
1412
1413 xlate_and_scale_to_bounds(canvas, fDst);
1414
1415 this->execute(canvas);
1416 return true;
1417}
1418
Mike Klein17428132019-03-20 13:02:32 -05001419void DrawImageRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001420 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001421 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001422 flatten(*fImage, writer, urlDataManager);
1423 writer.endObject(); // image
1424
1425 if (fSrc.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001426 writer.appendName(DEBUGCANVAS_ATTRIBUTE_SRC);
Mike Klein8f4e2242019-03-20 11:59:00 -05001427 MakeJsonRect(writer, *fSrc);
1428 }
Mike Klein17428132019-03-20 13:02:32 -05001429 writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
Mike Klein8f4e2242019-03-20 11:59:00 -05001430 MakeJsonRect(writer, fDst);
1431 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001432 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001433 MakeJsonPaint(writer, *fPaint, urlDataManager);
1434 }
1435 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
Mike Klein17428132019-03-20 13:02:32 -05001436 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_STRICT, true);
Mike Klein8f4e2242019-03-20 11:59:00 -05001437 }
1438
1439 SkString desc;
Mike Klein17428132019-03-20 13:02:32 -05001440 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fDst)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001441}
1442
Mike Klein17428132019-03-20 13:02:32 -05001443DrawImageNineCommand::DrawImageNineCommand(const SkImage* image,
1444 const SkIRect& center,
1445 const SkRect& dst,
1446 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001447 : INHERITED(kDrawImageNine_OpType)
1448 , fImage(SkRef(image))
1449 , fCenter(center)
1450 , fDst(dst)
1451 , fPaint(paint) {}
1452
Mike Klein17428132019-03-20 13:02:32 -05001453void DrawImageNineCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001454 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaint.getMaybeNull());
1455}
1456
Mike Klein17428132019-03-20 13:02:32 -05001457bool DrawImageNineCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001458 SkAutoCanvasRestore acr(canvas, true);
1459 canvas->clear(0xFFFFFFFF);
1460
1461 xlate_and_scale_to_bounds(canvas, fDst);
1462
1463 this->execute(canvas);
1464 return true;
1465}
1466
Mike Klein17428132019-03-20 13:02:32 -05001467void DrawImageNineCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001468 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001469 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_IMAGE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001470 flatten(*fImage, writer, urlDataManager);
1471 writer.endObject(); // image
1472
Mike Klein17428132019-03-20 13:02:32 -05001473 writer.appendName(DEBUGCANVAS_ATTRIBUTE_CENTER);
Mike Klein8f4e2242019-03-20 11:59:00 -05001474 MakeJsonIRect(writer, fCenter);
Mike Klein17428132019-03-20 13:02:32 -05001475 writer.appendName(DEBUGCANVAS_ATTRIBUTE_DST);
Mike Klein8f4e2242019-03-20 11:59:00 -05001476 MakeJsonRect(writer, fDst);
1477 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05001478 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001479 MakeJsonPaint(writer, *fPaint, urlDataManager);
1480 }
1481}
1482
Mike Klein17428132019-03-20 13:02:32 -05001483DrawOvalCommand::DrawOvalCommand(const SkRect& oval, const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001484 : INHERITED(kDrawOval_OpType) {
1485 fOval = oval;
1486 fPaint = paint;
1487}
1488
Mike Klein17428132019-03-20 13:02:32 -05001489void DrawOvalCommand::execute(SkCanvas* canvas) const { canvas->drawOval(fOval, fPaint); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001490
Mike Klein17428132019-03-20 13:02:32 -05001491bool DrawOvalCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001492 canvas->clear(0xFFFFFFFF);
1493 canvas->save();
1494
1495 xlate_and_scale_to_bounds(canvas, fOval);
1496
1497 SkPaint p;
1498 p.setColor(SK_ColorBLACK);
1499 p.setStyle(SkPaint::kStroke_Style);
1500
1501 canvas->drawOval(fOval, p);
1502 canvas->restore();
1503
1504 return true;
1505}
1506
Mike Klein17428132019-03-20 13:02:32 -05001507void DrawOvalCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001508 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001509 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001510 MakeJsonRect(writer, fOval);
Mike Klein17428132019-03-20 13:02:32 -05001511 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001512 MakeJsonPaint(writer, fPaint, urlDataManager);
1513}
1514
Mike Klein17428132019-03-20 13:02:32 -05001515DrawArcCommand::DrawArcCommand(const SkRect& oval,
1516 SkScalar startAngle,
1517 SkScalar sweepAngle,
1518 bool useCenter,
1519 const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001520 : INHERITED(kDrawArc_OpType) {
1521 fOval = oval;
1522 fStartAngle = startAngle;
1523 fSweepAngle = sweepAngle;
1524 fUseCenter = useCenter;
1525 fPaint = paint;
1526}
1527
Mike Klein17428132019-03-20 13:02:32 -05001528void DrawArcCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001529 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
1530}
1531
Mike Klein17428132019-03-20 13:02:32 -05001532bool DrawArcCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001533 canvas->clear(0xFFFFFFFF);
1534 canvas->save();
1535
1536 xlate_and_scale_to_bounds(canvas, fOval);
1537
1538 SkPaint p;
1539 p.setColor(SK_ColorBLACK);
1540 p.setStyle(SkPaint::kStroke_Style);
1541
1542 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
1543 canvas->restore();
1544
1545 return true;
1546}
1547
Mike Klein17428132019-03-20 13:02:32 -05001548void DrawArcCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001549 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001550 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001551 MakeJsonRect(writer, fOval);
Mike Klein17428132019-03-20 13:02:32 -05001552 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_STARTANGLE, fStartAngle);
1553 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_SWEEPANGLE, fSweepAngle);
1554 writer.appendBool(DEBUGCANVAS_ATTRIBUTE_USECENTER, fUseCenter);
1555 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001556 MakeJsonPaint(writer, fPaint, urlDataManager);
1557}
1558
Mike Klein17428132019-03-20 13:02:32 -05001559DrawPaintCommand::DrawPaintCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
Mike Klein8f4e2242019-03-20 11:59:00 -05001560 fPaint = paint;
1561}
1562
Mike Klein17428132019-03-20 13:02:32 -05001563void DrawPaintCommand::execute(SkCanvas* canvas) const { canvas->drawPaint(fPaint); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001564
Mike Klein17428132019-03-20 13:02:32 -05001565bool DrawPaintCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001566 canvas->clear(0xFFFFFFFF);
1567 canvas->drawPaint(fPaint);
1568 return true;
1569}
1570
Mike Klein17428132019-03-20 13:02:32 -05001571void DrawPaintCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001572 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001573 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001574 MakeJsonPaint(writer, fPaint, urlDataManager);
1575}
1576
Mike Reedd5674082019-04-19 15:00:47 -04001577DrawBehindCommand::DrawBehindCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
1578 fPaint = paint;
1579}
1580
1581void DrawBehindCommand::execute(SkCanvas* canvas) const {
1582 SkCanvasPriv::DrawBehind(canvas, fPaint);
1583}
1584
1585bool DrawBehindCommand::render(SkCanvas* canvas) const {
1586 canvas->clear(0xFFFFFFFF);
1587 SkCanvasPriv::DrawBehind(canvas, fPaint);
1588 return true;
1589}
1590
1591void DrawBehindCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
1592 INHERITED::toJSON(writer, urlDataManager);
1593 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
1594 MakeJsonPaint(writer, fPaint, urlDataManager);
1595}
1596
Mike Klein17428132019-03-20 13:02:32 -05001597DrawPathCommand::DrawPathCommand(const SkPath& path, const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001598 : INHERITED(kDrawPath_OpType) {
1599 fPath = path;
1600 fPaint = paint;
1601}
1602
Mike Klein17428132019-03-20 13:02:32 -05001603void DrawPathCommand::execute(SkCanvas* canvas) const { canvas->drawPath(fPath, fPaint); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001604
Mike Klein17428132019-03-20 13:02:32 -05001605bool DrawPathCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001606 render_path(canvas, fPath);
1607 return true;
1608}
1609
Mike Klein17428132019-03-20 13:02:32 -05001610void DrawPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001611 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001612 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
Mike Klein8f4e2242019-03-20 11:59:00 -05001613 MakeJsonPath(writer, fPath);
Mike Klein17428132019-03-20 13:02:32 -05001614 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001615 MakeJsonPaint(writer, fPaint, urlDataManager);
1616}
1617
Mike Klein17428132019-03-20 13:02:32 -05001618DrawRegionCommand::DrawRegionCommand(const SkRegion& region, const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001619 : INHERITED(kDrawRegion_OpType) {
1620 fRegion = region;
1621 fPaint = paint;
1622}
1623
Mike Klein17428132019-03-20 13:02:32 -05001624void DrawRegionCommand::execute(SkCanvas* canvas) const { canvas->drawRegion(fRegion, fPaint); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001625
Mike Klein17428132019-03-20 13:02:32 -05001626bool DrawRegionCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001627 render_region(canvas, fRegion);
1628 return true;
1629}
1630
Mike Klein17428132019-03-20 13:02:32 -05001631void DrawRegionCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001632 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001633 writer.appendName(DEBUGCANVAS_ATTRIBUTE_REGION);
Mike Klein8f4e2242019-03-20 11:59:00 -05001634 MakeJsonRegion(writer, fRegion);
Mike Klein17428132019-03-20 13:02:32 -05001635 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001636 MakeJsonPaint(writer, fPaint, urlDataManager);
1637}
1638
Mike Klein17428132019-03-20 13:02:32 -05001639BeginDrawPictureCommand::BeginDrawPictureCommand(const SkPicture* picture,
1640 const SkMatrix* matrix,
1641 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001642 : INHERITED(kBeginDrawPicture_OpType)
1643 , fPicture(SkRef(picture))
1644 , fMatrix(matrix)
1645 , fPaint(paint) {}
1646
Mike Klein17428132019-03-20 13:02:32 -05001647void BeginDrawPictureCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001648 if (fPaint.isValid()) {
1649 SkRect bounds = fPicture->cullRect();
1650 if (fMatrix.isValid()) {
1651 fMatrix->mapRect(&bounds);
1652 }
1653 canvas->saveLayer(&bounds, fPaint.get());
1654 }
1655
1656 if (fMatrix.isValid()) {
1657 if (!fPaint.isValid()) {
1658 canvas->save();
1659 }
1660 canvas->concat(*fMatrix);
1661 }
1662}
1663
Mike Klein17428132019-03-20 13:02:32 -05001664bool BeginDrawPictureCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001665 canvas->clear(0xFFFFFFFF);
1666 canvas->save();
1667
1668 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
1669
1670 canvas->drawPicture(fPicture.get());
1671
1672 canvas->restore();
1673
1674 return true;
1675}
1676
Mike Klein17428132019-03-20 13:02:32 -05001677EndDrawPictureCommand::EndDrawPictureCommand(bool restore)
Mike Klein8f4e2242019-03-20 11:59:00 -05001678 : INHERITED(kEndDrawPicture_OpType), fRestore(restore) {}
1679
Mike Klein17428132019-03-20 13:02:32 -05001680void EndDrawPictureCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001681 if (fRestore) {
1682 canvas->restore();
1683 }
1684}
1685
Mike Klein17428132019-03-20 13:02:32 -05001686DrawPointsCommand::DrawPointsCommand(SkCanvas::PointMode mode,
1687 size_t count,
1688 const SkPoint pts[],
1689 const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001690 : INHERITED(kDrawPoints_OpType), fMode(mode), fPts(pts, count), fPaint(paint) {}
1691
Mike Klein17428132019-03-20 13:02:32 -05001692void DrawPointsCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001693 canvas->drawPoints(fMode, fPts.count(), fPts.begin(), fPaint);
1694}
1695
Mike Klein17428132019-03-20 13:02:32 -05001696bool DrawPointsCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001697 canvas->clear(0xFFFFFFFF);
1698 canvas->save();
1699
1700 SkRect bounds;
1701
1702 bounds.setEmpty();
1703 for (int i = 0; i < fPts.count(); ++i) {
1704 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
1705 }
1706
1707 xlate_and_scale_to_bounds(canvas, bounds);
1708
1709 SkPaint p;
1710 p.setColor(SK_ColorBLACK);
1711 p.setStyle(SkPaint::kStroke_Style);
1712
1713 canvas->drawPoints(fMode, fPts.count(), fPts.begin(), p);
1714 canvas->restore();
1715
1716 return true;
1717}
1718
Mike Klein17428132019-03-20 13:02:32 -05001719void DrawPointsCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001720 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001721 writer.appendString(DEBUGCANVAS_ATTRIBUTE_MODE, pointmode_name(fMode));
1722 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_POINTS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001723 for (int i = 0; i < fPts.count(); i++) {
1724 MakeJsonPoint(writer, fPts[i]);
1725 }
1726 writer.endArray(); // points
Mike Klein17428132019-03-20 13:02:32 -05001727 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001728 MakeJsonPaint(writer, fPaint, urlDataManager);
1729}
1730
Mike Klein17428132019-03-20 13:02:32 -05001731DrawTextBlobCommand::DrawTextBlobCommand(sk_sp<SkTextBlob> blob,
1732 SkScalar x,
1733 SkScalar y,
1734 const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001735 : INHERITED(kDrawTextBlob_OpType)
1736 , fBlob(std::move(blob))
1737 , fXPos(x)
1738 , fYPos(y)
1739 , fPaint(paint) {}
1740
Mike Klein17428132019-03-20 13:02:32 -05001741void DrawTextBlobCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001742 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
1743}
1744
Mike Klein17428132019-03-20 13:02:32 -05001745bool DrawTextBlobCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001746 canvas->clear(SK_ColorWHITE);
1747 canvas->save();
1748
1749 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
1750 xlate_and_scale_to_bounds(canvas, bounds);
1751
1752 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
1753
1754 canvas->restore();
1755
1756 return true;
1757}
1758
Mike Klein17428132019-03-20 13:02:32 -05001759void DrawTextBlobCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001760 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001761 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_RUNS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001762 SkTextBlobRunIterator iter(fBlob.get());
1763 while (!iter.done()) {
1764 writer.beginObject(); // run
Mike Klein17428132019-03-20 13:02:32 -05001765 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_GLYPHS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001766 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
1767 writer.appendU32(iter.glyphs()[i]);
1768 }
1769 writer.endArray(); // glyphs
1770 if (iter.positioning() != SkTextBlobRunIterator::kDefault_Positioning) {
Mike Klein17428132019-03-20 13:02:32 -05001771 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_POSITIONS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001772 const SkScalar* iterPositions = iter.pos();
1773 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
1774 switch (iter.positioning()) {
1775 case SkTextBlobRunIterator::kFull_Positioning:
1776 MakeJsonPoint(writer, iterPositions[i * 2], iterPositions[i * 2 + 1]);
1777 break;
1778 case SkTextBlobRunIterator::kHorizontal_Positioning:
1779 writer.appendFloat(iterPositions[i]);
1780 break;
1781 case SkTextBlobRunIterator::kDefault_Positioning: break;
1782 case SkTextBlobRunIterator::kRSXform_Positioning:
1783 // TODO_RSXFORM_BLOB
1784 break;
1785 }
1786 }
1787 writer.endArray(); // positions
1788 }
Mike Klein17428132019-03-20 13:02:32 -05001789 writer.appendName(DEBUGCANVAS_ATTRIBUTE_FONT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001790 MakeJsonFont(iter.font(), writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001791 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001792 MakeJsonPoint(writer, iter.offset());
1793
1794 writer.endObject(); // run
1795 iter.next();
1796 }
1797 writer.endArray(); // runs
Mike Klein17428132019-03-20 13:02:32 -05001798 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_X, fXPos);
1799 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_Y, fYPos);
Mike Klein8f4e2242019-03-20 11:59:00 -05001800 SkRect bounds = fBlob->bounds();
Mike Klein17428132019-03-20 13:02:32 -05001801 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001802 MakeJsonRect(writer, bounds);
Mike Klein17428132019-03-20 13:02:32 -05001803 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001804 MakeJsonPaint(writer, fPaint, urlDataManager);
1805
1806 SkString desc;
1807 // make the bounds local by applying the x,y
1808 bounds.offset(fXPos, fYPos);
Mike Klein17428132019-03-20 13:02:32 -05001809 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, bounds)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001810}
1811
Mike Klein17428132019-03-20 13:02:32 -05001812DrawPatchCommand::DrawPatchCommand(const SkPoint cubics[12],
1813 const SkColor colors[4],
1814 const SkPoint texCoords[4],
1815 SkBlendMode bmode,
1816 const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001817 : INHERITED(kDrawPatch_OpType), fBlendMode(bmode) {
1818 memcpy(fCubics, cubics, sizeof(fCubics));
1819 if (colors != nullptr) {
1820 memcpy(fColors, colors, sizeof(fColors));
1821 fColorsPtr = fColors;
1822 } else {
1823 fColorsPtr = nullptr;
1824 }
1825 if (texCoords != nullptr) {
1826 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
1827 fTexCoordsPtr = fTexCoords;
1828 } else {
1829 fTexCoordsPtr = nullptr;
1830 }
1831 fPaint = paint;
1832}
1833
Mike Klein17428132019-03-20 13:02:32 -05001834void DrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001835 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
1836}
1837
Mike Klein17428132019-03-20 13:02:32 -05001838void DrawPatchCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001839 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001840 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_CUBICS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001841 for (int i = 0; i < 12; i++) {
1842 MakeJsonPoint(writer, fCubics[i]);
1843 }
1844 writer.endArray(); // cubics
1845 if (fColorsPtr != nullptr) {
Mike Klein17428132019-03-20 13:02:32 -05001846 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_COLORS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001847 for (int i = 0; i < 4; i++) {
1848 MakeJsonColor(writer, fColorsPtr[i]);
1849 }
1850 writer.endArray(); // colors
1851 }
1852 if (fTexCoordsPtr != nullptr) {
Mike Klein17428132019-03-20 13:02:32 -05001853 writer.beginArray(DEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001854 for (int i = 0; i < 4; i++) {
1855 MakeJsonPoint(writer, fTexCoords[i]);
1856 }
1857 writer.endArray(); // texCoords
1858 }
1859 // fBlendMode
1860}
1861
Mike Klein17428132019-03-20 13:02:32 -05001862DrawRectCommand::DrawRectCommand(const SkRect& rect, const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001863 : INHERITED(kDrawRect_OpType) {
1864 fRect = rect;
1865 fPaint = paint;
1866}
1867
Mike Klein17428132019-03-20 13:02:32 -05001868void DrawRectCommand::execute(SkCanvas* canvas) const { canvas->drawRect(fRect, fPaint); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001869
Mike Klein17428132019-03-20 13:02:32 -05001870void DrawRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001871 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001872 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001873 MakeJsonRect(writer, fRect);
Mike Klein17428132019-03-20 13:02:32 -05001874 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001875 MakeJsonPaint(writer, fPaint, urlDataManager);
1876
1877 SkString desc;
Mike Klein17428132019-03-20 13:02:32 -05001878 writer.appendString(DEBUGCANVAS_ATTRIBUTE_SHORTDESC, str_append(&desc, fRect)->c_str());
Mike Klein8f4e2242019-03-20 11:59:00 -05001879}
1880
Mike Klein17428132019-03-20 13:02:32 -05001881DrawRRectCommand::DrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001882 : INHERITED(kDrawRRect_OpType) {
1883 fRRect = rrect;
1884 fPaint = paint;
1885}
1886
Mike Klein17428132019-03-20 13:02:32 -05001887void DrawRRectCommand::execute(SkCanvas* canvas) const { canvas->drawRRect(fRRect, fPaint); }
Mike Klein8f4e2242019-03-20 11:59:00 -05001888
Mike Klein17428132019-03-20 13:02:32 -05001889bool DrawRRectCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001890 render_rrect(canvas, fRRect);
1891 return true;
1892}
1893
Mike Klein17428132019-03-20 13:02:32 -05001894void DrawRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001895 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001896 writer.appendName(DEBUGCANVAS_ATTRIBUTE_COORDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05001897 make_json_rrect(writer, fRRect);
Mike Klein17428132019-03-20 13:02:32 -05001898 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001899 MakeJsonPaint(writer, fPaint, urlDataManager);
1900}
1901
Mike Klein17428132019-03-20 13:02:32 -05001902DrawDRRectCommand::DrawDRRectCommand(const SkRRect& outer,
1903 const SkRRect& inner,
1904 const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001905 : INHERITED(kDrawDRRect_OpType) {
1906 fOuter = outer;
1907 fInner = inner;
1908 fPaint = paint;
1909}
1910
Mike Klein17428132019-03-20 13:02:32 -05001911void DrawDRRectCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001912 canvas->drawDRRect(fOuter, fInner, fPaint);
1913}
1914
Mike Klein17428132019-03-20 13:02:32 -05001915bool DrawDRRectCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001916 render_drrect(canvas, fOuter, fInner);
1917 return true;
1918}
1919
Mike Klein17428132019-03-20 13:02:32 -05001920void DrawDRRectCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001921 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05001922 writer.appendName(DEBUGCANVAS_ATTRIBUTE_OUTER);
Mike Klein8f4e2242019-03-20 11:59:00 -05001923 make_json_rrect(writer, fOuter);
Mike Klein17428132019-03-20 13:02:32 -05001924 writer.appendName(DEBUGCANVAS_ATTRIBUTE_INNER);
Mike Klein8f4e2242019-03-20 11:59:00 -05001925 make_json_rrect(writer, fInner);
Mike Klein17428132019-03-20 13:02:32 -05001926 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05001927 MakeJsonPaint(writer, fPaint, urlDataManager);
1928}
1929
Mike Klein17428132019-03-20 13:02:32 -05001930DrawShadowCommand::DrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
Mike Klein8f4e2242019-03-20 11:59:00 -05001931 : INHERITED(kDrawShadow_OpType) {
1932 fPath = path;
1933 fShadowRec = rec;
1934}
1935
Mike Klein17428132019-03-20 13:02:32 -05001936void DrawShadowCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001937 canvas->private_draw_shadow_rec(fPath, fShadowRec);
1938}
1939
Mike Klein17428132019-03-20 13:02:32 -05001940bool DrawShadowCommand::render(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001941 render_shadow(canvas, fPath, fShadowRec);
1942 return true;
1943}
1944
Mike Klein17428132019-03-20 13:02:32 -05001945void DrawShadowCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001946 INHERITED::toJSON(writer, urlDataManager);
1947
1948 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
1949 bool transparentOccluder =
1950 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
1951
Mike Klein17428132019-03-20 13:02:32 -05001952 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PATH);
Mike Klein8f4e2242019-03-20 11:59:00 -05001953 MakeJsonPath(writer, fPath);
Mike Klein17428132019-03-20 13:02:32 -05001954 writer.appendName(DEBUGCANVAS_ATTRIBUTE_ZPLANE);
Mike Klein8f4e2242019-03-20 11:59:00 -05001955 MakeJsonPoint3(writer, fShadowRec.fZPlaneParams);
Mike Klein17428132019-03-20 13:02:32 -05001956 writer.appendName(DEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION);
Mike Klein8f4e2242019-03-20 11:59:00 -05001957 MakeJsonPoint3(writer, fShadowRec.fLightPos);
Mike Klein17428132019-03-20 13:02:32 -05001958 writer.appendFloat(DEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS, fShadowRec.fLightRadius);
1959 writer.appendName(DEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR);
Mike Klein8f4e2242019-03-20 11:59:00 -05001960 MakeJsonColor(writer, fShadowRec.fAmbientColor);
Mike Klein17428132019-03-20 13:02:32 -05001961 writer.appendName(DEBUGCANVAS_ATTRIBUTE_SPOTCOLOR);
Mike Klein8f4e2242019-03-20 11:59:00 -05001962 MakeJsonColor(writer, fShadowRec.fSpotColor);
Mike Klein17428132019-03-20 13:02:32 -05001963 store_bool(writer, DEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
1964 store_bool(writer, DEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
Mike Klein8f4e2242019-03-20 11:59:00 -05001965}
1966
1967///////////////////////////////////////////////////////////////////////////////////////////////////
1968
Mike Klein17428132019-03-20 13:02:32 -05001969DrawEdgeAAQuadCommand::DrawEdgeAAQuadCommand(const SkRect& rect,
1970 const SkPoint clip[],
1971 SkCanvas::QuadAAFlags aa,
1972 SkColor color,
1973 SkBlendMode mode)
Mike Klein8f4e2242019-03-20 11:59:00 -05001974 : INHERITED(kDrawEdgeAAQuad_OpType)
1975 , fRect(rect)
1976 , fHasClip(clip != nullptr)
1977 , fAA(aa)
1978 , fColor(color)
1979 , fMode(mode) {
1980 if (clip) {
1981 for (int i = 0; i < 4; ++i) {
1982 fClip[i] = clip[i];
1983 }
1984 }
1985}
1986
Mike Klein17428132019-03-20 13:02:32 -05001987void DrawEdgeAAQuadCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05001988 canvas->experimental_DrawEdgeAAQuad(fRect, fHasClip ? fClip : nullptr, fAA, fColor, fMode);
1989}
1990
Mike Klein17428132019-03-20 13:02:32 -05001991DrawEdgeAAImageSetCommand::DrawEdgeAAImageSetCommand(const SkCanvas::ImageSetEntry set[],
1992 int count,
1993 const SkPoint dstClips[],
1994 const SkMatrix preViewMatrices[],
1995 const SkPaint* paint,
1996 SkCanvas::SrcRectConstraint constraint)
Mike Klein8f4e2242019-03-20 11:59:00 -05001997 : INHERITED(kDrawEdgeAAImageSet_OpType)
1998 , fSet(count)
1999 , fCount(count)
2000 , fPaint(paint)
2001 , fConstraint(constraint) {
2002 int totalDstClipCount, totalMatrixCount;
2003 SkCanvasPriv::GetDstClipAndMatrixCounts(set, count, &totalDstClipCount, &totalMatrixCount);
2004
2005 std::copy_n(set, count, fSet.get());
2006 fDstClips.reset(totalDstClipCount);
2007 std::copy_n(dstClips, totalDstClipCount, fDstClips.get());
2008 fPreViewMatrices.reset(totalMatrixCount);
2009 std::copy_n(preViewMatrices, totalMatrixCount, fPreViewMatrices.get());
2010}
2011
Mike Klein17428132019-03-20 13:02:32 -05002012void DrawEdgeAAImageSetCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002013 canvas->experimental_DrawEdgeAAImageSet(fSet.get(),
2014 fCount,
2015 fDstClips.get(),
2016 fPreViewMatrices.get(),
2017 fPaint.getMaybeNull(),
2018 fConstraint);
2019}
2020
2021///////////////////////////////////////////////////////////////////////////////////////////////////
2022
Mike Klein17428132019-03-20 13:02:32 -05002023DrawDrawableCommand::DrawDrawableCommand(SkDrawable* drawable, const SkMatrix* matrix)
Mike Klein8f4e2242019-03-20 11:59:00 -05002024 : INHERITED(kDrawDrawable_OpType), fDrawable(SkRef(drawable)), fMatrix(matrix) {}
2025
Mike Klein17428132019-03-20 13:02:32 -05002026void DrawDrawableCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002027 canvas->drawDrawable(fDrawable.get(), fMatrix.getMaybeNull());
2028}
2029
2030///////////////////////////////////////////////////////////////////////////////////////////////////
2031
Mike Klein17428132019-03-20 13:02:32 -05002032DrawVerticesCommand::DrawVerticesCommand(sk_sp<SkVertices> vertices,
2033 SkBlendMode bmode,
2034 const SkPaint& paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05002035 : INHERITED(kDrawVertices_OpType)
2036 , fVertices(std::move(vertices))
2037 , fBlendMode(bmode)
2038 , fPaint(paint) {}
2039
Mike Klein17428132019-03-20 13:02:32 -05002040void DrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002041 canvas->drawVertices(fVertices, fBlendMode, fPaint);
2042}
2043
2044///////////////////////////////////////////////////////////////////////////////////////////////////
2045
Mike Klein17428132019-03-20 13:02:32 -05002046DrawAtlasCommand::DrawAtlasCommand(const SkImage* image,
2047 const SkRSXform xform[],
2048 const SkRect tex[],
2049 const SkColor colors[],
2050 int count,
2051 SkBlendMode bmode,
2052 const SkRect* cull,
2053 const SkPaint* paint)
Mike Klein8f4e2242019-03-20 11:59:00 -05002054 : INHERITED(kDrawAtlas_OpType)
2055 , fImage(SkRef(image))
2056 , fXform(xform, count)
2057 , fTex(tex, count)
2058 , fColors(colors, colors ? count : 0)
2059 , fBlendMode(bmode)
2060 , fCull(cull)
2061 , fPaint(paint) {}
2062
Mike Klein17428132019-03-20 13:02:32 -05002063void DrawAtlasCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002064 canvas->drawAtlas(fImage.get(),
2065 fXform.begin(),
2066 fTex.begin(),
2067 fColors.isEmpty() ? nullptr : fColors.begin(),
2068 fXform.count(),
2069 fBlendMode,
2070 fCull.getMaybeNull(),
2071 fPaint.getMaybeNull());
2072}
2073
2074///////////////////////////////////////////////////////////////////////////////////////////////////
2075
Mike Klein17428132019-03-20 13:02:32 -05002076RestoreCommand::RestoreCommand() : INHERITED(kRestore_OpType) {}
Mike Klein8f4e2242019-03-20 11:59:00 -05002077
Mike Klein17428132019-03-20 13:02:32 -05002078void RestoreCommand::execute(SkCanvas* canvas) const { canvas->restore(); }
Mike Klein8f4e2242019-03-20 11:59:00 -05002079
Mike Klein17428132019-03-20 13:02:32 -05002080SaveCommand::SaveCommand() : INHERITED(kSave_OpType) {}
Mike Klein8f4e2242019-03-20 11:59:00 -05002081
Mike Klein17428132019-03-20 13:02:32 -05002082void SaveCommand::execute(SkCanvas* canvas) const { canvas->save(); }
Mike Klein8f4e2242019-03-20 11:59:00 -05002083
Mike Klein17428132019-03-20 13:02:32 -05002084SaveLayerCommand::SaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
Mike Klein8f4e2242019-03-20 11:59:00 -05002085 : INHERITED(kSaveLayer_OpType)
2086 , fBounds(rec.fBounds)
2087 , fPaint(rec.fPaint)
2088 , fBackdrop(SkSafeRef(rec.fBackdrop))
2089 , fSaveLayerFlags(rec.fSaveLayerFlags) {}
2090
Mike Klein17428132019-03-20 13:02:32 -05002091void SaveLayerCommand::execute(SkCanvas* canvas) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002092 canvas->saveLayer(
2093 SkCanvas::SaveLayerRec(fBounds.getMaybeNull(), fPaint.getMaybeNull(), fSaveLayerFlags));
2094}
2095
Mike Klein17428132019-03-20 13:02:32 -05002096void SaveLayerCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002097 INHERITED::toJSON(writer, urlDataManager);
2098 if (fBounds.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05002099 writer.appendName(DEBUGCANVAS_ATTRIBUTE_BOUNDS);
Mike Klein8f4e2242019-03-20 11:59:00 -05002100 MakeJsonRect(writer, *fBounds);
2101 }
2102 if (fPaint.isValid()) {
Mike Klein17428132019-03-20 13:02:32 -05002103 writer.appendName(DEBUGCANVAS_ATTRIBUTE_PAINT);
Mike Klein8f4e2242019-03-20 11:59:00 -05002104 MakeJsonPaint(writer, *fPaint, urlDataManager);
2105 }
2106 if (fBackdrop != nullptr) {
Mike Klein17428132019-03-20 13:02:32 -05002107 writer.beginObject(DEBUGCANVAS_ATTRIBUTE_BACKDROP);
Mike Klein8f4e2242019-03-20 11:59:00 -05002108 flatten(fBackdrop.get(), writer, urlDataManager);
2109 writer.endObject(); // backdrop
2110 }
2111 if (fSaveLayerFlags != 0) {
2112 SkDebugf("unsupported: saveLayer flags\n");
2113 SkASSERT(false);
2114 }
2115}
2116
Mike Klein17428132019-03-20 13:02:32 -05002117SetMatrixCommand::SetMatrixCommand(const SkMatrix& matrix) : INHERITED(kSetMatrix_OpType) {
Mike Klein8f4e2242019-03-20 11:59:00 -05002118 fMatrix = matrix;
2119}
2120
Mike Klein17428132019-03-20 13:02:32 -05002121void SetMatrixCommand::execute(SkCanvas* canvas) const { canvas->setMatrix(fMatrix); }
Mike Klein8f4e2242019-03-20 11:59:00 -05002122
Mike Klein17428132019-03-20 13:02:32 -05002123void SetMatrixCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
Mike Klein8f4e2242019-03-20 11:59:00 -05002124 INHERITED::toJSON(writer, urlDataManager);
Mike Klein17428132019-03-20 13:02:32 -05002125 writer.appendName(DEBUGCANVAS_ATTRIBUTE_MATRIX);
Mike Klein8f4e2242019-03-20 11:59:00 -05002126 MakeJsonMatrix(writer, fMatrix);
2127}