blob: bca5186d8af4e37748dfac1af4660d6b0bdd1096 [file] [log] [blame]
chudy@google.com902ebe52012-06-29 14:21:22 +00001
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
chudy@google.com902ebe52012-06-29 14:21:22 +000010#include "SkDrawCommand.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080011#include "SkBlurMaskFilter.h"
12#include "SkColorFilter.h"
13#include "SkDashPathEffect.h"
14#include "SkImageFilter.h"
15#include "SkMaskFilter.h"
chudy@google.com902ebe52012-06-29 14:21:22 +000016#include "SkObjectParser.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080017#include "SkPaintDefaults.h"
18#include "SkPathEffect.h"
robertphillips9bafc302015-02-13 11:13:00 -080019#include "SkPicture.h"
fmalitab7425172014-08-26 07:56:44 -070020#include "SkTextBlob.h"
fmalitae77f2da2015-12-08 18:59:18 -080021#include "SkTextBlobRunIterator.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080022#include "SkTHash.h"
23#include "SkTypeface.h"
24#include "SkValidatingReadBuffer.h"
25#include "SkWriteBuffer.h"
26
27#define SKDEBUGCANVAS_SEND_BINARIES false
28
29#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
30#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
31#define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
32#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
33#define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
34#define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
35#define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
36#define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
37#define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
38#define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
39#define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
40#define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
41#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
42#define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
43#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
44#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
45#define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
46#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
47#define SKDEBUGCANVAS_ATTRIBUTE_REGION "region"
48#define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
49#define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
50#define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
51#define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur"
52#define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
53#define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
54#define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign"
55#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
56#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
57#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
58#define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
59#define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
60#define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
61#define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
62#define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
63#define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
64#define SKDEBUGCANVAS_ATTRIBUTE_BYTES "bytes"
65#define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
66#define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
67#define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
68#define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
69#define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
70#define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
71#define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
72#define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
73#define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
74#define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
75#define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
76#define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
77#define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
78#define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
79#define SKDEBUGCANVAS_ATTRIBUTE_X "x"
80#define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
81#define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
82#define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
83#define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
84#define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
85#define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
86
87#define SKDEBUGCANVAS_VERB_MOVE "move"
88#define SKDEBUGCANVAS_VERB_LINE "line"
89#define SKDEBUGCANVAS_VERB_QUAD "quad"
90#define SKDEBUGCANVAS_VERB_CUBIC "cubic"
91#define SKDEBUGCANVAS_VERB_CONIC "conic"
92#define SKDEBUGCANVAS_VERB_CLOSE "close"
93
94#define SKDEBUGCANVAS_STYLE_FILL "fill"
95#define SKDEBUGCANVAS_STYLE_STROKE "stroke"
96#define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
97
98#define SKDEBUGCANVAS_POINTMODE_POINTS "points"
99#define SKDEBUGCANVAS_POINTMODE_LINES "lines"
100#define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
101
102#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
103#define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
104#define SKDEBUGCANVAS_REGIONOP_UNION "union"
105#define SKDEBUGCANVAS_REGIONOP_XOR "xor"
106#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
107#define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
108
109#define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
110#define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
111#define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
112#define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
113
114#define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
115#define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
116
117#define SKDEBUGCANVAS_ALIGN_LEFT "left"
118#define SKDEBUGCANVAS_ALIGN_CENTER "center"
119#define SKDEBUGCANVAS_ALIGN_RIGHT "right"
120
121#define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
122#define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
123#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
124#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
125
126#define SKDEBUGCANVAS_CAP_BUTT "butt"
127#define SKDEBUGCANVAS_CAP_ROUND "round"
128#define SKDEBUGCANVAS_CAP_SQUARE "square"
129
130#define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
131#define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
132#define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
133#define SKDEBUGCANVAS_COLORTYPE_565 "565"
134#define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
135#define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
136#define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
137
138#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
139#define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
140#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
141
142typedef SkDrawCommand* (*FROM_JSON)(Json::Value);
fmalitab7425172014-08-26 07:56:44 -0700143
chudy@google.com902ebe52012-06-29 14:21:22 +0000144// TODO(chudy): Refactor into non subclass model.
145
robertphillips9bafc302015-02-13 11:13:00 -0800146SkDrawCommand::SkDrawCommand(OpType type)
147 : fOpType(type)
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000148 , fVisible(true) {
149}
150
chudy@google.com902ebe52012-06-29 14:21:22 +0000151SkDrawCommand::~SkDrawCommand() {
chudy@google.com97cee972012-08-07 20:41:37 +0000152 fInfo.deleteAll();
chudy@google.com902ebe52012-06-29 14:21:22 +0000153}
154
robertphillips9bafc302015-02-13 11:13:00 -0800155const char* SkDrawCommand::GetCommandString(OpType type) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000156 switch (type) {
fmalita160ebb22015-04-01 20:58:37 -0700157 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800158 case kClipPath_OpType: return "ClipPath";
159 case kClipRegion_OpType: return "ClipRegion";
160 case kClipRect_OpType: return "ClipRect";
161 case kClipRRect_OpType: return "ClipRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800162 case kConcat_OpType: return "Concat";
163 case kDrawBitmap_OpType: return "DrawBitmap";
164 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
165 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
166 case kDrawClear_OpType: return "DrawClear";
167 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700168 case kDrawImage_OpType: return "DrawImage";
169 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800170 case kDrawOval_OpType: return "DrawOval";
171 case kDrawPaint_OpType: return "DrawPaint";
172 case kDrawPatch_OpType: return "DrawPatch";
173 case kDrawPath_OpType: return "DrawPath";
robertphillips9bafc302015-02-13 11:13:00 -0800174 case kDrawPoints_OpType: return "DrawPoints";
175 case kDrawPosText_OpType: return "DrawPosText";
176 case kDrawPosTextH_OpType: return "DrawPosTextH";
177 case kDrawRect_OpType: return "DrawRect";
178 case kDrawRRect_OpType: return "DrawRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800179 case kDrawText_OpType: return "DrawText";
180 case kDrawTextBlob_OpType: return "DrawTextBlob";
181 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
182 case kDrawVertices_OpType: return "DrawVertices";
fmalita160ebb22015-04-01 20:58:37 -0700183 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800184 case kRestore_OpType: return "Restore";
185 case kSave_OpType: return "Save";
186 case kSaveLayer_OpType: return "SaveLayer";
187 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000188 default:
robertphillips9bafc302015-02-13 11:13:00 -0800189 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000190 SkASSERT(0);
191 break;
192 }
193 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700194 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000195}
196
fmalita8c89c522014-11-08 16:18:56 -0800197SkString SkDrawCommand::toString() const {
robertphillips9bafc302015-02-13 11:13:00 -0800198 return SkString(GetCommandString(fOpType));
chudy@google.com902ebe52012-06-29 14:21:22 +0000199}
200
ethannicholas50a8dd02016-02-10 05:40:46 -0800201Json::Value SkDrawCommand::toJSON() const {
202 Json::Value result;
203 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
204 return result;
205}
206
207#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
208 (FROM_JSON) Sk ## name ## Command::fromJSON)
209SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command) {
210 static SkTHashMap<SkString, FROM_JSON> factories;
211 static bool initialized = false;
212 if (!initialized) {
213 initialized = true;
214 INSTALL_FACTORY(Restore);
215 INSTALL_FACTORY(ClipPath);
216 INSTALL_FACTORY(ClipRegion);
217 INSTALL_FACTORY(ClipRect);
218 INSTALL_FACTORY(ClipRRect);
219 INSTALL_FACTORY(Concat);
220 INSTALL_FACTORY(DrawBitmap);
221 INSTALL_FACTORY(DrawBitmapRect);
222 INSTALL_FACTORY(DrawBitmapNine);
223 INSTALL_FACTORY(DrawImage);
224 INSTALL_FACTORY(DrawImageRect);
225 INSTALL_FACTORY(DrawOval);
226 INSTALL_FACTORY(DrawPaint);
227 INSTALL_FACTORY(DrawPath);
228 INSTALL_FACTORY(DrawPoints);
229 INSTALL_FACTORY(DrawText);
230 INSTALL_FACTORY(DrawPosText);
231 INSTALL_FACTORY(DrawTextOnPath);
232 INSTALL_FACTORY(DrawTextBlob);
233
234 INSTALL_FACTORY(DrawRect);
235 INSTALL_FACTORY(DrawRRect);
236 INSTALL_FACTORY(DrawDRRect);
237 INSTALL_FACTORY(Save);
238 INSTALL_FACTORY(SaveLayer);
239 INSTALL_FACTORY(SetMatrix);
240 }
241 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
242 FROM_JSON* factory = factories.find(name);
243 if (factory == nullptr) {
244 SkDebugf("no JSON factory for '%s'\n", name.c_str());
245 return nullptr;
246 }
247 return (*factory)(command);
248}
249
robertphillips9bafc302015-02-13 11:13:00 -0800250SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kDrawClear_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +0000251 fColor = color;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +0000252 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
chudy@google.com902ebe52012-06-29 14:21:22 +0000253}
254
fmalita8c89c522014-11-08 16:18:56 -0800255void SkClearCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +0000256 canvas->clear(fColor);
chudy@google.com902ebe52012-06-29 14:21:22 +0000257}
258
ethannicholas50a8dd02016-02-10 05:40:46 -0800259Json::Value SkClearCommand::toJSON() const {
260 Json::Value result = INHERITED::toJSON();
261 Json::Value colorValue(Json::arrayValue);
262 colorValue.append(Json::Value(SkColorGetA(fColor)));
263 colorValue.append(Json::Value(SkColorGetR(fColor)));
264 colorValue.append(Json::Value(SkColorGetG(fColor)));
265 colorValue.append(Json::Value(SkColorGetB(fColor)));
266 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
267 return result;
268}
269
270 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command) {
271 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
272 return new SkClearCommand(SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(),
273 color[3].asInt()));
274}
275
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000276namespace {
277
278void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
279 const SkISize& size = canvas->getDeviceSize();
280
281 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
282
283 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
284 if (bounds.width() > bounds.height()) {
285 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
286 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
287 } else {
288 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
289 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
290 }
291 canvas->translate(-bounds.centerX(), -bounds.centerY());
292}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000293
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000294
295void render_path(SkCanvas* canvas, const SkPath& path) {
296 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000297
298 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700299 if (bounds.isEmpty()) {
300 return;
301 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000302
fmalitab0cd8b72015-10-06 07:24:03 -0700303 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000304 xlate_and_scale_to_bounds(canvas, bounds);
305
306 SkPaint p;
307 p.setColor(SK_ColorBLACK);
308 p.setStyle(SkPaint::kStroke_Style);
309
310 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000311}
312
halcanary96fcdcc2015-08-27 07:41:13 -0700313void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000314 const SkISize& size = canvas->getDeviceSize();
315
316 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
317 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
318
319 if (input.width() > input.height()) {
320 yScale *= input.height() / (float) input.width();
321 } else {
322 xScale *= input.width() / (float) input.height();
323 }
324
325 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
326 xScale * input.width(),
327 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000328
robertphillips96a5cff2015-09-24 06:56:27 -0700329 static const int kNumBlocks = 8;
330
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000331 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700332 SkISize block = {
333 canvas->imageInfo().width()/kNumBlocks,
334 canvas->imageInfo().height()/kNumBlocks
335 };
336 for (int y = 0; y < kNumBlocks; ++y) {
337 for (int x = 0; x < kNumBlocks; ++x) {
338 SkPaint paint;
339 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
340 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
341 SkIntToScalar(y*block.height()),
342 SkIntToScalar(block.width()),
343 SkIntToScalar(block.height()));
344 canvas->drawRect(r, paint);
345 }
346 }
347
reede47829b2015-08-06 10:02:53 -0700348 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000349
bsalomon49f085d2014-09-05 13:34:00 -0700350 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000351 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
352 srcRect->fTop * yScale + SK_Scalar1,
353 srcRect->fRight * xScale + SK_Scalar1,
354 srcRect->fBottom * yScale + SK_Scalar1);
355 SkPaint p;
356 p.setColor(SK_ColorRED);
357 p.setStyle(SkPaint::kStroke_Style);
358
359 canvas->drawRect(r, p);
360 }
361}
362
363void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
364 canvas->clear(0xFFFFFFFF);
365 canvas->save();
366
367 const SkRect& bounds = rrect.getBounds();
368
369 xlate_and_scale_to_bounds(canvas, bounds);
370
371 SkPaint p;
372 p.setColor(SK_ColorBLACK);
373 p.setStyle(SkPaint::kStroke_Style);
374
375 canvas->drawRRect(rrect, p);
376 canvas->restore();
377}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000378
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000379void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
380 canvas->clear(0xFFFFFFFF);
381 canvas->save();
382
383 const SkRect& bounds = outer.getBounds();
384
385 xlate_and_scale_to_bounds(canvas, bounds);
386
387 SkPaint p;
388 p.setColor(SK_ColorBLACK);
389 p.setStyle(SkPaint::kStroke_Style);
390
391 canvas->drawDRRect(outer, inner, p);
392 canvas->restore();
393}
394
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000395};
396
ethannicholas50a8dd02016-02-10 05:40:46 -0800397static Json::Value make_json_point(const SkPoint& point) {
398 Json::Value result(Json::arrayValue);
399 result.append(Json::Value(point.x()));
400 result.append(Json::Value(point.y()));
401 return result;
402}
403
404static Json::Value make_json_point(SkScalar x, SkScalar y) {
405 Json::Value result(Json::arrayValue);
406 result.append(Json::Value(x));
407 result.append(Json::Value(y));
408 return result;
409}
410
411static Json::Value make_json_rect(const SkRect& rect) {
412 Json::Value result(Json::arrayValue);
413 result.append(Json::Value(rect.left()));
414 result.append(Json::Value(rect.top()));
415 result.append(Json::Value(rect.right()));
416 result.append(Json::Value(rect.bottom()));
417 return result;
418}
419
420static Json::Value make_json_irect(const SkIRect& rect) {
421 Json::Value result(Json::arrayValue);
422 result.append(Json::Value(rect.left()));
423 result.append(Json::Value(rect.top()));
424 result.append(Json::Value(rect.right()));
425 result.append(Json::Value(rect.bottom()));
426 return result;
427}
428
429static Json::Value make_json_rrect(const SkRRect& rrect) {
430 Json::Value result(Json::arrayValue);
431 result.append(make_json_rect(rrect.rect()));
432 result.append(make_json_point(rrect.radii(SkRRect::kUpperLeft_Corner)));
433 result.append(make_json_point(rrect.radii(SkRRect::kUpperRight_Corner)));
434 result.append(make_json_point(rrect.radii(SkRRect::kLowerRight_Corner)));
435 result.append(make_json_point(rrect.radii(SkRRect::kLowerLeft_Corner)));
436 return result;
437}
438
439static Json::Value make_json_matrix(const SkMatrix& matrix) {
440 Json::Value result(Json::arrayValue);
441 Json::Value row1(Json::arrayValue);
442 row1.append(Json::Value(matrix[0]));
443 row1.append(Json::Value(matrix[1]));
444 row1.append(Json::Value(matrix[2]));
445 result.append(row1);
446 Json::Value row2(Json::arrayValue);
447 row2.append(Json::Value(matrix[3]));
448 row2.append(Json::Value(matrix[4]));
449 row2.append(Json::Value(matrix[5]));
450 result.append(row2);
451 Json::Value row3(Json::arrayValue);
452 row3.append(Json::Value(matrix[6]));
453 row3.append(Json::Value(matrix[7]));
454 row3.append(Json::Value(matrix[8]));
455 result.append(row3);
456 return result;
457}
458static Json::Value make_json_path(const SkPath& path) {
459 Json::Value result(Json::objectValue);
460 switch (path.getFillType()) {
461 case SkPath::kWinding_FillType:
462 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
463 break;
464 case SkPath::kEvenOdd_FillType:
465 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
466 break;
467 case SkPath::kInverseWinding_FillType:
468 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
469 break;
470 case SkPath::kInverseEvenOdd_FillType:
471 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
472 break;
473 }
474 Json::Value verbs(Json::arrayValue);
475 SkPath::Iter iter(path, false);
476 SkPoint pts[4];
477 SkPath::Verb verb;
478 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
479 switch (verb) {
480 case SkPath::kLine_Verb: {
481 Json::Value line(Json::objectValue);
482 line[SKDEBUGCANVAS_VERB_LINE] = make_json_point(pts[1]);
483 verbs.append(line);
484 break;
485 }
486 case SkPath::kQuad_Verb: {
487 Json::Value quad(Json::objectValue);
488 Json::Value coords(Json::arrayValue);
489 coords.append(make_json_point(pts[1]));
490 coords.append(make_json_point(pts[2]));
491 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
492 verbs.append(quad);
493 break;
494 }
495 case SkPath::kCubic_Verb: {
496 Json::Value cubic(Json::objectValue);
497 Json::Value coords(Json::arrayValue);
498 coords.append(make_json_point(pts[1]));
499 coords.append(make_json_point(pts[2]));
500 coords.append(make_json_point(pts[3]));
501 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
502 verbs.append(cubic);
503 break;
504 }
505 case SkPath::kConic_Verb: {
506 Json::Value conic(Json::objectValue);
507 Json::Value coords(Json::arrayValue);
508 coords.append(make_json_point(pts[1]));
509 coords.append(make_json_point(pts[2]));
510 coords.append(Json::Value(iter.conicWeight()));
511 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
512 verbs.append(conic);
513 break;
514 }
515 case SkPath::kMove_Verb: {
516 Json::Value move(Json::objectValue);
517 move[SKDEBUGCANVAS_VERB_MOVE] = make_json_point(pts[0]);
518 verbs.append(move);
519 break;
520 }
521 case SkPath::kClose_Verb:
522 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
523 break;
524 case SkPath::kDone_Verb:
525 break;
526 }
527 }
528 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
529 return result;
530}
531
532static Json::Value make_json_region(const SkRegion& region) {
533 return Json::Value("<unimplemented>");
534}
535
536static Json::Value make_json_regionop(SkRegion::Op op) {
537 switch (op) {
538 case SkRegion::kDifference_Op:
539 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
540 case SkRegion::kIntersect_Op:
541 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
542 case SkRegion::kUnion_Op:
543 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
544 case SkRegion::kXOR_Op:
545 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
546 case SkRegion::kReverseDifference_Op:
547 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
548 case SkRegion::kReplace_Op:
549 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
550 default:
551 SkASSERT(false);
552 return Json::Value("<invalid region op>");
553 };
554}
555
556static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
557 switch (mode) {
558 case SkCanvas::kPoints_PointMode:
559 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
560 case SkCanvas::kLines_PointMode:
561 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
562 case SkCanvas::kPolygon_PointMode:
563 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
564 default:
565 SkASSERT(false);
566 return Json::Value("<invalid point mode>");
567 };
568}
569
ethannicholasbd3dae82016-02-10 12:10:00 -0800570static void store_scalar(Json::Value* target, const char* key, SkScalar value,
571 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800572 if (value != defaultValue) {
573 (*target)[key] = Json::Value(value);
574 }
575}
576
ethannicholasbd3dae82016-02-10 12:10:00 -0800577static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800578 if (value != defaultValue) {
579 (*target)[key] = Json::Value(value);
580 }
581}
582
583static void encode_data(const void* data, size_t count, Json::Value* target) {
584 // just use a brain-dead JSON array for now, switch to base64 or something else smarter down the
585 // road
586 for (size_t i = 0; i < count; i++) {
587 target->append(((const uint8_t*)data)[i]);
588 }
589}
590
591static void flatten(const SkFlattenable* flattenable, Json::Value* target, bool sendBinaries) {
592 if (sendBinaries) {
593 SkWriteBuffer buffer;
594 flattenable->flatten(buffer);
595 void* data = sk_malloc_throw(buffer.bytesWritten());
596 buffer.writeToMemory(data);
597 Json::Value bytes;
598 encode_data(data, buffer.bytesWritten(), &bytes);
599 Json::Value jsonFlattenable;
600 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
601 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_BYTES] = bytes;
602 (*target) = jsonFlattenable;
603 sk_free(data);
604 } else {
605 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(flattenable->getTypeName());
606 }
607}
608
609static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target,
610 bool sendBinaries) {
611 if (sendBinaries) {
612 SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100);
613 if (encoded == nullptr) {
614 // PNG encode doesn't necessarily support all color formats, convert to a different
615 // format
616 size_t rowBytes = 4 * image.width();
617 void* buffer = sk_malloc_throw(rowBytes * image.height());
618 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
619 kN32_SkColorType, kPremul_SkAlphaType);
620 if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) {
621 SkDebugf("readPixels failed\n");
622 return false;
623 }
624 SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes);
625 encoded = converted->encode(SkImageEncoder::kPNG_Type, 100);
626 if (encoded == nullptr) {
627 SkDebugf("image encode failed\n");
628 return false;
629 }
630 sk_free(converted);
631 sk_free(buffer);
632 }
633 Json::Value bytes;
634 encode_data(encoded->data(), encoded->size(), &bytes);
635 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BYTES] = bytes;
636 encoded->unref();
637 } else {
638 SkString description = SkStringPrintf("%dx%d pixel image", image.width(), image.height());
639 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(description.c_str());
640 }
641 return true;
642}
643
644static const char* color_type_name(SkColorType colorType) {
645 switch (colorType) {
646 case kARGB_4444_SkColorType:
647 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
648 case kRGBA_8888_SkColorType:
649 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
650 case kBGRA_8888_SkColorType:
651 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
652 case kRGB_565_SkColorType:
653 return SKDEBUGCANVAS_COLORTYPE_565;
654 case kGray_8_SkColorType:
655 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
656 case kIndex_8_SkColorType:
657 return SKDEBUGCANVAS_COLORTYPE_INDEX8;
658 case kAlpha_8_SkColorType:
659 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
660 default:
661 SkASSERT(false);
662 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
663 }
664}
665
666static const char* alpha_type_name(SkAlphaType alphaType) {
667 switch (alphaType) {
668 case kOpaque_SkAlphaType:
669 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
670 case kPremul_SkAlphaType:
671 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
672 case kUnpremul_SkAlphaType:
673 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
674 default:
675 SkASSERT(false);
676 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
677 }
678}
679
680// note that the caller is responsible for freeing the pointer
681static Json::ArrayIndex decode_data(Json::Value bytes, void** target) {
682 Json::ArrayIndex size = bytes.size();
683 *target = sk_malloc_throw(size);
684 for (Json::ArrayIndex i = 0; i < size; i++) {
685 ((uint8_t*) *target)[i] = bytes[i].asInt();
686 }
687 return size;
688}
689
690static SkFlattenable* load_flattenable(Json::Value jsonFlattenable) {
691 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
692 return nullptr;
693 }
694 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
695 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
696 if (factory == nullptr) {
697 SkDebugf("no factory for loading '%s'\n", name);
698 return nullptr;
699 }
700 void* data;
701 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_BYTES], &data);
702 SkValidatingReadBuffer buffer(data, size);
703 SkFlattenable* result = factory(buffer);
704 sk_free(data);
705 if (!buffer.isValid()) {
706 SkDebugf("invalid buffer loading flattenable\n");
707 return nullptr;
708 }
709 return result;
710}
711
712static SkColorType colortype_from_name(const char* name) {
713 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
714 return kARGB_4444_SkColorType;
715 }
716 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
717 return kRGBA_8888_SkColorType;
718 }
719 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
720 return kBGRA_8888_SkColorType;
721 }
722 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
723 return kRGB_565_SkColorType;
724 }
725 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
726 return kGray_8_SkColorType;
727 }
728 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_INDEX8)) {
729 return kIndex_8_SkColorType;
730 }
731 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
732 return kAlpha_8_SkColorType;
733 }
734 SkASSERT(false);
735 return kN32_SkColorType;
736}
737
738static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
739 if (bitmap->colorType() == colorType ) {
740 return bitmap;
741 }
742 SkBitmap* dst = new SkBitmap();
743 if (bitmap->copyTo(dst, colorType)) {
744 delete bitmap;
745 return dst;
746 }
747 SkASSERT(false);
748 delete dst;
749 return bitmap;
750}
751
752// caller is responsible for freeing return value
753static SkBitmap* load_bitmap(const Json::Value& jsonBitmap) {
754 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_BYTES)) {
755 SkDebugf("invalid bitmap\n");
756 return nullptr;
757 }
758 void* data;
759 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_BYTES], &data);
760 SkMemoryStream stream(data, size);
761 SkImageDecoder* decoder = SkImageDecoder::Factory(&stream);
762 SkBitmap* bitmap = new SkBitmap();
763 SkImageDecoder::Result result = decoder->decode(&stream, bitmap,
764 SkImageDecoder::kDecodePixels_Mode);
765 sk_free(decoder);
766 if (result != SkImageDecoder::kFailure) {
767 sk_free(data);
768 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
769 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
770 SkColorType ct = colortype_from_name(ctName);
771 if (ct != kIndex_8_SkColorType) {
772 bitmap = convert_colortype(bitmap, ct);
773 }
774 }
775 return bitmap;
776 }
777 SkDebugf("image decode failed\n");
778 sk_free(data);
779 return nullptr;
780}
781
782static SkImage* load_image(const Json::Value& jsonImage) {
783 SkBitmap* bitmap = load_bitmap(jsonImage);
784 if (bitmap == nullptr) {
785 return nullptr;
786 }
787 SkImage* result = SkImage::NewFromBitmap(*bitmap);
788 delete bitmap;
789 return result;
790}
791
792static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target,
793 bool sendBinaries) {
794 bitmap.lockPixels();
795 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
796 bitmap.unlockPixels();
797 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
798 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
799 bool success = flatten(*image, target, sendBinaries);
800 return success;
801}
802
803static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
804 SkColor color = paint.getColor();
805 if (color != SK_ColorBLACK) {
806 Json::Value colorValue(Json::arrayValue);
807 colorValue.append(Json::Value(SkColorGetA(color)));
808 colorValue.append(Json::Value(SkColorGetR(color)));
809 colorValue.append(Json::Value(SkColorGetG(color)));
810 colorValue.append(Json::Value(SkColorGetB(color)));
811 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
812 }
813}
814
815static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
816 SkPaint::Style style = paint.getStyle();
817 if (style != SkPaint::kFill_Style) {
818 switch (style) {
819 case SkPaint::kStroke_Style: {
820 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
821 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
822 break;
823 }
824 case SkPaint::kStrokeAndFill_Style: {
825 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
826 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
827 break;
828 }
829 default: SkASSERT(false);
830 }
831 }
832}
833
834static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
835 SkPaint::Cap cap = paint.getStrokeCap();
836 if (cap != SkPaint::kDefault_Cap) {
837 switch (cap) {
838 case SkPaint::kButt_Cap: {
839 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
840 break;
841 }
842 case SkPaint::kRound_Cap: {
843 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
844 break;
845 }
846 case SkPaint::kSquare_Cap: {
847 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
848 break;
849 }
850 default: SkASSERT(false);
851 }
852 }
853}
854static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
855 SkMaskFilter* maskFilter = paint.getMaskFilter();
856 if (maskFilter != nullptr) {
857 SkMaskFilter::BlurRec blurRec;
858 if (maskFilter->asABlur(&blurRec)) {
859 Json::Value blur(Json::objectValue);
860 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
861 switch (blurRec.fStyle) {
862 case SkBlurStyle::kNormal_SkBlurStyle:
863 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_NORMAL);
864 break;
865 case SkBlurStyle::kSolid_SkBlurStyle:
866 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_SOLID);
867 break;
868 case SkBlurStyle::kOuter_SkBlurStyle:
869 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_OUTER);
870 break;
871 case SkBlurStyle::kInner_SkBlurStyle:
872 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_INNER);
873 break;
874 default:
875 SkASSERT(false);
876 }
877 switch (blurRec.fQuality) {
878 case SkBlurQuality::kLow_SkBlurQuality:
879 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKDEBUGCANVAS_BLURQUALITY_LOW);
880 break;
881 case SkBlurQuality::kHigh_SkBlurQuality:
882 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKDEBUGCANVAS_BLURQUALITY_HIGH);
883 break;
884 default:
885 SkASSERT(false);
886 }
887 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
888 } else {
889 Json::Value jsonMaskFilter;
890 flatten(maskFilter, &jsonMaskFilter, sendBinaries);
891 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
892 }
893 }
894}
895
896static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
897 SkPathEffect* pathEffect = paint.getPathEffect();
898 if (pathEffect != nullptr) {
899 SkPathEffect::DashInfo dashInfo;
900 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
901 if (dashType == SkPathEffect::kDash_DashType) {
902 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
903 pathEffect->asADash(&dashInfo);
904 Json::Value dashing(Json::objectValue);
905 Json::Value intervals(Json::arrayValue);
906 for (int32_t i = 0; i < dashInfo.fCount; i++) {
907 intervals.append(Json::Value(dashInfo.fIntervals[i]));
908 }
909 sk_free(dashInfo.fIntervals);
910 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
911 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
912 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
913 } else {
914 Json::Value jsonPathEffect;
915 flatten(pathEffect, &jsonPathEffect, sendBinaries);
916 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
917 }
918 }
919}
920
921static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
922 SkPaint::Align textAlign = paint.getTextAlign();
923 if (textAlign != SkPaint::kLeft_Align) {
924 switch (textAlign) {
925 case SkPaint::kCenter_Align: {
926 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
927 break;
928 }
929 case SkPaint::kRight_Align: {
930 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
931 break;
932 }
933 default: SkASSERT(false);
934 }
935 }
936}
937
938static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
939 bool sendBinaries) {
940 SkTypeface* typeface = paint.getTypeface();
941 if (typeface != nullptr) {
942 if (sendBinaries) {
943 Json::Value jsonTypeface;
944 SkDynamicMemoryWStream buffer;
945 typeface->serialize(&buffer);
946 void* data = sk_malloc_throw(buffer.bytesWritten());
947 buffer.copyTo(data);
948 Json::Value bytes;
949 encode_data(data, buffer.bytesWritten(), &bytes);
950 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_BYTES] = bytes;
951 sk_free(data);
952 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
953 }
954 }
955}
956
957static void apply_paint_shader(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
958 SkFlattenable* shader = paint.getShader();
959 if (shader != nullptr) {
960 Json::Value jsonShader;
961 flatten(shader, &jsonShader, sendBinaries);
962 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
963 }
964}
965
966static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
967 SkFlattenable* xfermode = paint.getXfermode();
968 if (xfermode != nullptr) {
969 Json::Value jsonXfermode;
970 flatten(xfermode, &jsonXfermode, sendBinaries);
971 (*target)[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
972 }
973}
974
975static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
976 SkFlattenable* imageFilter = paint.getImageFilter();
977 if (imageFilter != nullptr) {
978 Json::Value jsonImageFilter;
979 flatten(imageFilter, &jsonImageFilter, sendBinaries);
980 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
981 }
982}
983
984static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
985 SkFlattenable* colorFilter = paint.getColorFilter();
986 if (colorFilter != nullptr) {
987 Json::Value jsonColorFilter;
988 flatten(colorFilter, &jsonColorFilter, sendBinaries);
989 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
990 }
991}
992
993Json::Value make_json_paint(const SkPaint& paint, bool sendBinaries) {
994 Json::Value result(Json::objectValue);
995 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
996 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
997 SkPaintDefaults_MiterLimit);
998 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
999 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
1000 SkPaintDefaults_TextSize);
1001 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1002 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
1003 apply_paint_color(paint, &result);
1004 apply_paint_style(paint, &result);
1005 apply_paint_cap(paint, &result);
1006 apply_paint_textalign(paint, &result);
1007 apply_paint_patheffect(paint, &result, sendBinaries);
1008 apply_paint_maskfilter(paint, &result, sendBinaries);
1009 apply_paint_shader(paint, &result, sendBinaries);
1010 apply_paint_xfermode(paint, &result, sendBinaries);
1011 apply_paint_imagefilter(paint, &result, sendBinaries);
1012 apply_paint_colorfilter(paint, &result, sendBinaries);
1013 apply_paint_typeface(paint, &result, sendBinaries);
1014 return result;
1015}
1016
1017static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1018 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
1019 Json::Value color = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1020 target->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(),
1021 color[3].asInt()));
1022 }
1023}
1024
1025static void extract_json_paint_shader(Json::Value& jsonPaint, SkPaint* target) {
1026 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1027 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
1028 SkShader* shader = (SkShader*) load_flattenable(jsonShader);
1029 if (shader != nullptr) {
1030 target->setShader(shader);
1031 shader->unref();
1032 }
1033 }
1034}
1035
1036static void extract_json_paint_patheffect(Json::Value& jsonPaint, SkPaint* target) {
1037 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1038 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
1039 SkPathEffect* pathEffect = (SkPathEffect*) load_flattenable(jsonPathEffect);
1040 if (pathEffect != nullptr) {
1041 target->setPathEffect(pathEffect);
1042 pathEffect->unref();
1043 }
1044 }
1045}
1046
1047static void extract_json_paint_maskfilter(Json::Value& jsonPaint, SkPaint* target) {
1048 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1049 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
1050 SkMaskFilter* maskFilter = (SkMaskFilter*) load_flattenable(jsonMaskFilter);
1051 if (maskFilter != nullptr) {
1052 target->setMaskFilter(maskFilter);
1053 maskFilter->unref();
1054 }
1055 }
1056}
1057
1058static void extract_json_paint_colorfilter(Json::Value& jsonPaint, SkPaint* target) {
1059 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1060 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
1061 SkColorFilter* colorFilter = (SkColorFilter*) load_flattenable(jsonColorFilter);
1062 if (colorFilter != nullptr) {
1063 target->setColorFilter(colorFilter);
1064 colorFilter->unref();
1065 }
1066 }
1067}
1068
1069static void extract_json_paint_xfermode(Json::Value& jsonPaint, SkPaint* target) {
1070 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) {
1071 Json::Value jsonXfermode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE];
1072 SkXfermode* xfermode = (SkXfermode*) load_flattenable(jsonXfermode);
1073 if (xfermode != nullptr) {
1074 target->setXfermode(xfermode);
1075 xfermode->unref();
1076 }
1077 }
1078}
1079
1080static void extract_json_paint_imagefilter(Json::Value& jsonPaint, SkPaint* target) {
1081 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1082 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
1083 SkImageFilter* imageFilter = (SkImageFilter*) load_flattenable(jsonImageFilter);
1084 if (imageFilter != nullptr) {
1085 target->setImageFilter(imageFilter);
1086 imageFilter->unref();
1087 }
1088 }
1089}
1090
1091static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1092 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1093 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1094 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1095 target->setStyle(SkPaint::kFill_Style);
1096 }
1097 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1098 target->setStyle(SkPaint::kStroke_Style);
1099 }
1100 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1101 target->setStyle(SkPaint::kStrokeAndFill_Style);
1102 }
1103 }
1104}
1105
1106static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1107 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1108 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1109 target->setStrokeWidth(strokeWidth);
1110 }
1111}
1112
1113static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1114 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1115 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1116 target->setStrokeMiter(strokeMiter);
1117 }
1118}
1119
1120static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1121 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1122 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1123 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1124 target->setStrokeCap(SkPaint::kButt_Cap);
1125 }
1126 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1127 target->setStrokeCap(SkPaint::kRound_Cap);
1128 }
1129 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1130 target->setStrokeCap(SkPaint::kSquare_Cap);
1131 }
1132 }
1133}
1134
1135static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1136 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1137 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1138 }
1139}
1140
1141static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1142 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1143 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1144 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1145 SkBlurStyle style;
1146 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1147 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1148 style = SkBlurStyle::kNormal_SkBlurStyle;
1149 }
1150 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1151 style = SkBlurStyle::kSolid_SkBlurStyle;
1152 }
1153 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1154 style = SkBlurStyle::kOuter_SkBlurStyle;
1155 }
1156 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1157 style = SkBlurStyle::kInner_SkBlurStyle;
1158 }
1159 else {
1160 SkASSERT(false);
1161 style = SkBlurStyle::kNormal_SkBlurStyle;
1162 }
1163 SkBlurMaskFilter::BlurFlags flags;
1164 const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString();
1165 if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) {
1166 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1167 }
1168 else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) {
1169 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag;
1170 }
1171 else {
1172 SkASSERT(false);
1173 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1174 }
1175 target->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags));
1176 }
1177}
1178
1179static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1180 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1181 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1182 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1183 Json::ArrayIndex count = jsonIntervals.size();
1184 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1185 for (Json::ArrayIndex i = 0; i < count; i++) {
1186 intervals[i] = jsonIntervals[i].asFloat();
1187 }
1188 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
1189 target->setPathEffect(SkDashPathEffect::Create(intervals, count, phase));
1190 sk_free(intervals);
1191 }
1192}
1193
1194static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1195 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1196 SkPaint::Align textAlign;
1197 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1198 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1199 textAlign = SkPaint::kLeft_Align;
1200 }
1201 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1202 textAlign = SkPaint::kCenter_Align;
1203 }
1204 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1205 textAlign = SkPaint::kRight_Align;
1206 }
1207 else {
1208 SkASSERT(false);
1209 textAlign = SkPaint::kLeft_Align;
1210 }
1211 target->setTextAlign(textAlign);
1212 }
1213}
1214
1215static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1216 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1217 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1218 target->setTextSize(textSize);
1219 }
1220}
1221
1222static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1223 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1224 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1225 target->setTextScaleX(textScaleX);
1226 }
1227}
1228
1229static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1230 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1231 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1232 target->setTextSkewX(textSkewX);
1233 }
1234}
1235
1236static void extract_json_paint_typeface(Json::Value& jsonPaint, SkPaint* target) {
1237 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1238 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1239 Json::Value bytes = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_BYTES];
1240 void* data;
1241 Json::ArrayIndex length = decode_data(bytes, &data);
1242 SkMemoryStream buffer(data, length);
1243 SkTypeface* typeface = SkTypeface::Deserialize(&buffer);
1244 sk_free(data);
1245 target->setTypeface(typeface);
1246 }
1247}
1248
1249static void extract_json_paint(Json::Value& paint, SkPaint* result) {
1250 extract_json_paint_color(paint, result);
1251 extract_json_paint_shader(paint, result);
1252 extract_json_paint_patheffect(paint, result);
1253 extract_json_paint_maskfilter(paint, result);
1254 extract_json_paint_colorfilter(paint, result);
1255 extract_json_paint_xfermode(paint, result);
1256 extract_json_paint_imagefilter(paint, result);
1257 extract_json_paint_style(paint, result);
1258 extract_json_paint_strokewidth(paint, result);
1259 extract_json_paint_strokemiter(paint, result);
1260 extract_json_paint_cap(paint, result);
1261 extract_json_paint_antialias(paint, result);
1262 extract_json_paint_blur(paint, result);
1263 extract_json_paint_dashing(paint, result);
1264 extract_json_paint_textalign(paint, result);
1265 extract_json_paint_textsize(paint, result);
1266 extract_json_paint_textscalex(paint, result);
1267 extract_json_paint_textskewx(paint, result);
1268 extract_json_paint_typeface(paint, result);
1269}
1270
1271static void extract_json_rect(Json::Value& rect, SkRect* result) {
1272 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1273}
1274
1275static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1276 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1277}
1278
1279static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1280 SkVector radii[4] = {
1281 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1282 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1283 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
1284 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1285 };
1286 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1287 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
1288 radii);
1289}
1290
1291static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
1292 SkScalar values[] = {
1293 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1294 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
1295 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
1296 };
1297 result->set9(values);
1298}
1299
1300static void extract_json_path(Json::Value& path, SkPath* result) {
1301 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1302 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1303 result->setFillType(SkPath::kWinding_FillType);
1304 }
1305 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1306 result->setFillType(SkPath::kEvenOdd_FillType);
1307 }
1308 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1309 result->setFillType(SkPath::kInverseWinding_FillType);
1310 }
1311 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1312 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1313 }
1314 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1315 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1316 Json::Value verb = verbs[i];
1317 if (verb.isString()) {
1318 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1319 result->close();
1320 }
1321 else {
1322 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1323 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1324 result->moveTo(move[0].asFloat(), move[1].asFloat());
1325 }
1326 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1327 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1328 result->lineTo(line[0].asFloat(), line[1].asFloat());
1329 }
1330 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1331 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1332 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1333 quad[1][0].asFloat(), quad[1][1].asFloat());
1334 }
1335 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1336 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1337 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1338 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1339 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1340 }
1341 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1342 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1343 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1344 conic[1][0].asFloat(), conic[1][1].asFloat(),
1345 conic[2].asFloat());
1346 }
1347 else {
1348 SkASSERT(false);
1349 }
1350 }
1351 }
1352}
1353
1354SkRegion::Op get_json_regionop(Json::Value& jsonOp) {
1355 const char* op = jsonOp.asCString();
1356 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
1357 return SkRegion::kDifference_Op;
1358 }
1359 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
1360 return SkRegion::kIntersect_Op;
1361 }
1362 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
1363 return SkRegion::kUnion_Op;
1364 }
1365 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
1366 return SkRegion::kXOR_Op;
1367 }
1368 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
1369 return SkRegion::kReverseDifference_Op;
1370 }
1371 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
1372 return SkRegion::kReplace_Op;
1373 }
1374 SkASSERT(false);
1375 return SkRegion::kIntersect_Op;
1376}
1377
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001378
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001379SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001380 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001381 fPath = path;
1382 fOp = op;
1383 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001384
robertphillips@google.com91217d02013-03-17 18:33:46 +00001385 fInfo.push(SkObjectParser::PathToString(path));
1386 fInfo.push(SkObjectParser::RegionOpToString(op));
1387 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001388}
1389
fmalita8c89c522014-11-08 16:18:56 -08001390void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001391 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001392}
1393
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001394bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001395 render_path(canvas, fPath);
1396 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001397}
1398
ethannicholas50a8dd02016-02-10 05:40:46 -08001399Json::Value SkClipPathCommand::toJSON() const {
1400 Json::Value result = INHERITED::toJSON();
1401 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
1402 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1403 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1404 return result;
1405}
1406
1407SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command) {
1408 SkPath path;
1409 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
1410 return new SkClipPathCommand(path, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1411 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1412}
1413
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001414SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op)
robertphillips9bafc302015-02-13 11:13:00 -08001415 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001416 fRegion = region;
1417 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001418
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001419 fInfo.push(SkObjectParser::RegionToString(region));
1420 fInfo.push(SkObjectParser::RegionOpToString(op));
chudy@google.com902ebe52012-06-29 14:21:22 +00001421}
1422
fmalita8c89c522014-11-08 16:18:56 -08001423void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001424 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001425}
1426
ethannicholas50a8dd02016-02-10 05:40:46 -08001427Json::Value SkClipRegionCommand::toJSON() const {
1428 Json::Value result = INHERITED::toJSON();
1429 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = make_json_region(fRegion);
1430 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1431 return result;
1432}
1433
1434SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command) {
1435 SkASSERT(false);
1436 return nullptr;
1437}
1438
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001439SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001440 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001441 fRect = rect;
1442 fOp = op;
1443 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001444
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001445 fInfo.push(SkObjectParser::RectToString(rect));
1446 fInfo.push(SkObjectParser::RegionOpToString(op));
1447 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001448}
1449
fmalita8c89c522014-11-08 16:18:56 -08001450void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001451 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001452}
1453
ethannicholas50a8dd02016-02-10 05:40:46 -08001454Json::Value SkClipRectCommand::toJSON() const {
1455 Json::Value result = INHERITED::toJSON();
1456 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect);
1457 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1458 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1459 return result;
1460}
1461
1462SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command) {
1463 SkRect rect;
1464 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
1465 return new SkClipRectCommand(rect, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1466 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1467}
1468
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001469SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001470 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001471 fRRect = rrect;
1472 fOp = op;
1473 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001474
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001475 fInfo.push(SkObjectParser::RRectToString(rrect));
1476 fInfo.push(SkObjectParser::RegionOpToString(op));
1477 fInfo.push(SkObjectParser::BoolToString(doAA));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001478}
1479
fmalita8c89c522014-11-08 16:18:56 -08001480void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001481 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001482}
1483
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001484bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001485 render_rrect(canvas, fRRect);
1486 return true;
1487}
1488
ethannicholas50a8dd02016-02-10 05:40:46 -08001489Json::Value SkClipRRectCommand::toJSON() const {
1490 Json::Value result = INHERITED::toJSON();
1491 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1492 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1493 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1494 return result;
1495}
1496
1497SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command) {
1498 SkRRect rrect;
1499 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
1500 return new SkClipRRectCommand(rrect,
1501 get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1502 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1503}
1504
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001505SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001506 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001507 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001508
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001509 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00001510}
1511
fmalita8c89c522014-11-08 16:18:56 -08001512void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001513 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001514}
1515
ethannicholas50a8dd02016-02-10 05:40:46 -08001516Json::Value SkConcatCommand::toJSON() const {
1517 Json::Value result = INHERITED::toJSON();
1518 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix);
1519 return result;
1520}
1521
1522SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command) {
1523 SkMatrix matrix;
1524 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1525 return new SkConcatCommand(matrix);
1526}
1527
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001528SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07001529 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08001530 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001531 fBitmap = bitmap;
1532 fLeft = left;
1533 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07001534 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001535 fPaint = *paint;
1536 fPaintPtr = &fPaint;
1537 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001538 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001539 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001540
1541 fInfo.push(SkObjectParser::BitmapToString(bitmap));
1542 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
1543 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
bsalomon49f085d2014-09-05 13:34:00 -07001544 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001545 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001546 }
chudy@google.com902ebe52012-06-29 14:21:22 +00001547}
1548
fmalita8c89c522014-11-08 16:18:56 -08001549void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001550 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00001551}
1552
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001553bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001554 render_bitmap(canvas, fBitmap);
1555 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001556}
1557
ethannicholas50a8dd02016-02-10 05:40:46 -08001558Json::Value SkDrawBitmapCommand::toJSON() const {
1559 Json::Value result = INHERITED::toJSON();
1560 Json::Value encoded;
1561 if (flatten(fBitmap, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1562 Json::Value command(Json::objectValue);
1563 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1564 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop);
1565 if (fPaintPtr != nullptr) {
1566 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, SKDEBUGCANVAS_SEND_BINARIES);
1567 }
1568 }
1569 return result;
1570}
1571
1572SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command) {
1573 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP]);
1574 if (bitmap == nullptr) {
1575 return nullptr;
1576 }
1577 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
1578 SkPaint* paintPtr;
1579 SkPaint paint;
1580 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1581 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1582 paintPtr = &paint;
1583 }
1584 else {
1585 paintPtr = nullptr;
1586 }
1587 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
1588 point[1].asFloat(), paintPtr);
1589 delete bitmap;
1590 return result;
1591}
1592
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001593SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001594 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08001595 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001596 fBitmap = bitmap;
1597 fCenter = center;
1598 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07001599 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001600 fPaint = *paint;
1601 fPaintPtr = &fPaint;
1602 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001603 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001604 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001605
1606 fInfo.push(SkObjectParser::BitmapToString(bitmap));
1607 fInfo.push(SkObjectParser::IRectToString(center));
1608 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07001609 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001610 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001611 }
chudy@google.com902ebe52012-06-29 14:21:22 +00001612}
1613
fmalita8c89c522014-11-08 16:18:56 -08001614void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001615 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00001616}
1617
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001618bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08001619 SkRect tmp = SkRect::Make(fCenter);
1620 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001621 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001622}
1623
ethannicholas50a8dd02016-02-10 05:40:46 -08001624Json::Value SkDrawBitmapNineCommand::toJSON() const {
1625 Json::Value result = INHERITED::toJSON();
1626 Json::Value encoded;
1627 if (flatten(fBitmap, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1628 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1629 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = make_json_irect(fCenter);
1630 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
1631 if (fPaintPtr != nullptr) {
1632 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
1633 SKDEBUGCANVAS_SEND_BINARIES);
1634 }
1635 }
1636 return result;
1637}
1638
1639SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command) {
1640 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP]);
1641 if (bitmap == nullptr) {
1642 return nullptr;
1643 }
1644 SkIRect center;
1645 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
1646 SkRect dst;
1647 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
1648 SkPaint* paintPtr;
1649 SkPaint paint;
1650 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1651 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1652 paintPtr = &paint;
1653 }
1654 else {
1655 paintPtr = nullptr;
1656 }
1657 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
1658 delete bitmap;
1659 return result;
1660}
1661
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001662SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00001663 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07001664 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08001665 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001666 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07001667 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001668 fSrc = *src;
1669 } else {
1670 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001671 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00001672 fDst = dst;
1673
bsalomon49f085d2014-09-05 13:34:00 -07001674 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001675 fPaint = *paint;
1676 fPaintPtr = &fPaint;
1677 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001678 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00001679 }
reeda5517e22015-07-14 10:54:12 -07001680 fConstraint = constraint;
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00001681
robertphillips@google.com91217d02013-03-17 18:33:46 +00001682 fInfo.push(SkObjectParser::BitmapToString(bitmap));
bsalomon49f085d2014-09-05 13:34:00 -07001683 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001684 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
1685 }
1686 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07001687 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001688 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001689 }
reeda5517e22015-07-14 10:54:12 -07001690 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
chudy@google.com902ebe52012-06-29 14:21:22 +00001691}
1692
fmalita8c89c522014-11-08 16:18:56 -08001693void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07001694 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001695}
1696
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001697bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001698 render_bitmap(canvas, fBitmap, this->srcRect());
1699 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001700}
1701
ethannicholas50a8dd02016-02-10 05:40:46 -08001702Json::Value SkDrawBitmapRectCommand::toJSON() const {
1703 Json::Value result = INHERITED::toJSON();
1704 Json::Value encoded;
1705 if (flatten(fBitmap, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1706 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1707 if (!fSrc.isEmpty()) {
1708 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(fSrc);
1709 }
1710 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
1711 if (fPaintPtr != nullptr) {
1712 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
1713 SKDEBUGCANVAS_SEND_BINARIES);
1714 }
1715 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1716 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
1717 }
1718 }
1719 return result;
1720}
1721
1722SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command) {
1723 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP]);
1724 if (bitmap == nullptr) {
1725 return nullptr;
1726 }
1727 SkRect dst;
1728 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
1729 SkPaint* paintPtr;
1730 SkPaint paint;
1731 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1732 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1733 paintPtr = &paint;
1734 }
1735 else {
1736 paintPtr = nullptr;
1737 }
1738 SkCanvas::SrcRectConstraint constraint;
1739 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
1740 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
1741 constraint = SkCanvas::kStrict_SrcRectConstraint;
1742 }
1743 else {
1744 constraint = SkCanvas::kFast_SrcRectConstraint;
1745 }
1746 SkRect* srcPtr;
1747 SkRect src;
1748 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
1749 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
1750 srcPtr = &src;
1751 }
1752 else {
1753 srcPtr = nullptr;
1754 }
1755 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
1756 constraint);
1757 delete bitmap;
1758 return result;
1759}
1760
fmalita651c9202015-07-22 10:23:01 -07001761SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
1762 const SkPaint* paint)
1763 : INHERITED(kDrawImage_OpType)
1764 , fImage(SkRef(image))
1765 , fLeft(left)
1766 , fTop(top) {
1767
fmalita7361bf02015-10-29 12:13:48 -07001768 fInfo.push(SkObjectParser::ImageToString(image));
1769 fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
1770 fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));
1771
fmalita651c9202015-07-22 10:23:01 -07001772 if (paint) {
1773 fPaint.set(*paint);
fmalita7361bf02015-10-29 12:13:48 -07001774 fInfo.push(SkObjectParser::PaintToString(*paint));
fmalita651c9202015-07-22 10:23:01 -07001775 }
1776}
1777
1778void SkDrawImageCommand::execute(SkCanvas* canvas) const {
1779 canvas->drawImage(fImage, fLeft, fTop, fPaint.getMaybeNull());
1780}
1781
1782bool SkDrawImageCommand::render(SkCanvas* canvas) const {
1783 SkAutoCanvasRestore acr(canvas, true);
1784 canvas->clear(0xFFFFFFFF);
1785
1786 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
1787 SkIntToScalar(fImage->width()),
1788 SkIntToScalar(fImage->height())));
1789 this->execute(canvas);
1790 return true;
1791}
1792
ethannicholas50a8dd02016-02-10 05:40:46 -08001793Json::Value SkDrawImageCommand::toJSON() const {
1794 Json::Value result = INHERITED::toJSON();
1795 Json::Value encoded;
1796 if (flatten(*fImage, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1797 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
1798 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop);
1799 if (fPaint.isValid()) {
1800 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(),
1801 SKDEBUGCANVAS_SEND_BINARIES);
1802 }
1803 }
1804 return result;
1805}
1806
1807SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command) {
1808 SkImage* image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE]);
1809 if (image == nullptr) {
1810 return nullptr;
1811 }
1812 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
1813 SkPaint* paintPtr;
1814 SkPaint paint;
1815 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1816 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1817 paintPtr = &paint;
1818 }
1819 else {
1820 paintPtr = nullptr;
1821 }
1822 SkDrawImageCommand* result = new SkDrawImageCommand(image, point[0].asFloat(),
1823 point[1].asFloat(), paintPtr);
1824 image->unref();
1825 return result;
1826}
1827
fmalita651c9202015-07-22 10:23:01 -07001828SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
1829 const SkRect& dst, const SkPaint* paint,
1830 SkCanvas::SrcRectConstraint constraint)
1831 : INHERITED(kDrawImageRect_OpType)
1832 , fImage(SkRef(image))
1833 , fDst(dst)
1834 , fConstraint(constraint) {
1835
1836 if (src) {
1837 fSrc.set(*src);
1838 }
1839
1840 if (paint) {
1841 fPaint.set(*paint);
1842 }
robertphillips80af6452015-08-24 08:27:38 -07001843
1844 fInfo.push(SkObjectParser::ImageToString(image));
1845 if (src) {
1846 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
1847 }
1848 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
1849 if (paint) {
1850 fInfo.push(SkObjectParser::PaintToString(*paint));
1851 }
1852 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
fmalita651c9202015-07-22 10:23:01 -07001853}
1854
1855void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07001856 canvas->legacy_drawImageRect(fImage, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07001857}
1858
1859bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
1860 SkAutoCanvasRestore acr(canvas, true);
1861 canvas->clear(0xFFFFFFFF);
1862
1863 xlate_and_scale_to_bounds(canvas, fDst);
1864
1865 this->execute(canvas);
1866 return true;
1867}
1868
ethannicholas50a8dd02016-02-10 05:40:46 -08001869Json::Value SkDrawImageRectCommand::toJSON() const {
1870 Json::Value result = INHERITED::toJSON();
1871 Json::Value encoded;
1872 if (flatten(*fImage.get(), &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1873 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1874 if (fSrc.isValid()) {
1875 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(*fSrc.get());
1876 }
1877 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
1878 if (fPaint.isValid()) {
1879 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(),
1880 SKDEBUGCANVAS_SEND_BINARIES);
1881 }
1882 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1883 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
1884 }
1885 }
1886 return result;
1887}
1888
1889SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command) {
1890 SkImage* image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE]);
1891 if (image == nullptr) {
1892 return nullptr;
1893 }
1894 SkRect dst;
1895 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
1896 SkPaint* paintPtr;
1897 SkPaint paint;
1898 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1899 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1900 paintPtr = &paint;
1901 }
1902 else {
1903 paintPtr = nullptr;
1904 }
1905 SkCanvas::SrcRectConstraint constraint;
1906 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
1907 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
1908 constraint = SkCanvas::kStrict_SrcRectConstraint;
1909 }
1910 else {
1911 constraint = SkCanvas::kFast_SrcRectConstraint;
1912 }
1913 SkRect* srcPtr;
1914 SkRect src;
1915 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
1916 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
1917 srcPtr = &src;
1918 }
1919 else {
1920 srcPtr = nullptr;
1921 }
1922 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image, srcPtr, dst, paintPtr,
1923 constraint);
1924 image->unref();
1925 return result;
1926}
1927
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001928SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001929 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001930 fOval = oval;
1931 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001932
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001933 fInfo.push(SkObjectParser::RectToString(oval));
1934 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001935}
1936
fmalita8c89c522014-11-08 16:18:56 -08001937void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001938 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001939}
1940
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001941bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001942 canvas->clear(0xFFFFFFFF);
1943 canvas->save();
1944
1945 xlate_and_scale_to_bounds(canvas, fOval);
1946
1947 SkPaint p;
1948 p.setColor(SK_ColorBLACK);
1949 p.setStyle(SkPaint::kStroke_Style);
1950
1951 canvas->drawOval(fOval, p);
1952 canvas->restore();
1953
1954 return true;
1955}
1956
ethannicholas50a8dd02016-02-10 05:40:46 -08001957Json::Value SkDrawOvalCommand::toJSON() const {
1958 Json::Value result = INHERITED::toJSON();
1959 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fOval);
1960 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
1961 return result;
1962}
1963
1964SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command) {
1965 SkRect coords;
1966 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
1967 SkPaint paint;
1968 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1969 return new SkDrawOvalCommand(coords, paint);
1970}
1971
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001972SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001973 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001974 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00001975
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001976 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00001977}
1978
fmalita8c89c522014-11-08 16:18:56 -08001979void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001980 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001981}
1982
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001983bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001984 canvas->clear(0xFFFFFFFF);
1985 canvas->drawPaint(fPaint);
1986 return true;
1987}
1988
ethannicholas50a8dd02016-02-10 05:40:46 -08001989Json::Value SkDrawPaintCommand::toJSON() const {
1990 Json::Value result = INHERITED::toJSON();
1991 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
1992 return result;
1993}
1994
1995SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command) {
1996 SkPaint paint;
1997 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1998 return new SkDrawPaintCommand(paint);
1999}
2000
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002001SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002002 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002003 fPath = path;
2004 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002005
robertphillips@google.com91217d02013-03-17 18:33:46 +00002006 fInfo.push(SkObjectParser::PathToString(path));
2007 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002008}
2009
fmalita8c89c522014-11-08 16:18:56 -08002010void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002011 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002012}
2013
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002014bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002015 render_path(canvas, fPath);
2016 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002017}
2018
ethannicholas50a8dd02016-02-10 05:40:46 -08002019Json::Value SkDrawPathCommand::toJSON() const {
2020 Json::Value result = INHERITED::toJSON();
2021 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
2022 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2023 return result;
2024}
2025
2026SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command) {
2027 SkPath path;
2028 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2029 SkPaint paint;
2030 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2031 return new SkDrawPathCommand(path, paint);
2032}
2033
fmalita160ebb22015-04-01 20:58:37 -07002034SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2035 const SkMatrix* matrix,
2036 const SkPaint* paint)
2037 : INHERITED(kBeginDrawPicture_OpType)
2038 , fPicture(SkRef(picture)) {
2039
2040 SkString* str = new SkString;
2041 str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
2042 picture->cullRect().fLeft, picture->cullRect().fTop,
2043 picture->cullRect().fRight, picture->cullRect().fBottom);
2044 fInfo.push(str);
robertphillipsb3f319f2014-08-13 10:46:23 -07002045
bsalomon49f085d2014-09-05 13:34:00 -07002046 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002047 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002048 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2049 }
fmalita160ebb22015-04-01 20:58:37 -07002050
bsalomon49f085d2014-09-05 13:34:00 -07002051 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002052 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002053 fInfo.push(SkObjectParser::PaintToString(*paint));
2054 }
fmalita160ebb22015-04-01 20:58:37 -07002055
2056}
2057
2058void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2059 if (fPaint.isValid()) {
2060 SkRect bounds = fPicture->cullRect();
2061 if (fMatrix.isValid()) {
2062 fMatrix.get()->mapRect(&bounds);
2063 }
2064 canvas->saveLayer(&bounds, fPaint.get());
2065 }
2066
2067 if (fMatrix.isValid()) {
2068 if (!fPaint.isValid()) {
2069 canvas->save();
2070 }
2071 canvas->concat(*fMatrix.get());
2072 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002073}
2074
fmalita160ebb22015-04-01 20:58:37 -07002075bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002076 canvas->clear(0xFFFFFFFF);
2077 canvas->save();
2078
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002079 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002080
robertphillips9b14f262014-06-04 05:40:44 -07002081 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002082
2083 canvas->restore();
2084
2085 return true;
2086}
2087
fmalita160ebb22015-04-01 20:58:37 -07002088SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2089 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2090
2091void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2092 if (fRestore) {
2093 canvas->restore();
2094 }
2095}
2096
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002097SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002098 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002099 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002100 fMode = mode;
2101 fCount = count;
2102 fPts = new SkPoint[count];
2103 memcpy(fPts, pts, count * sizeof(SkPoint));
2104 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002105
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002106 fInfo.push(SkObjectParser::PointsToString(pts, count));
2107 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
2108 "Points: "));
2109 fInfo.push(SkObjectParser::PointModeToString(mode));
2110 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002111}
2112
fmalita8c89c522014-11-08 16:18:56 -08002113void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002114 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002115}
2116
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002117bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002118 canvas->clear(0xFFFFFFFF);
2119 canvas->save();
2120
2121 SkRect bounds;
2122
2123 bounds.setEmpty();
2124 for (unsigned int i = 0; i < fCount; ++i) {
2125 bounds.growToInclude(fPts[i].fX, fPts[i].fY);
2126 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002127
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002128 xlate_and_scale_to_bounds(canvas, bounds);
2129
2130 SkPaint p;
2131 p.setColor(SK_ColorBLACK);
2132 p.setStyle(SkPaint::kStroke_Style);
2133
2134 canvas->drawPoints(fMode, fCount, fPts, p);
2135 canvas->restore();
2136
2137 return true;
2138}
2139
ethannicholas50a8dd02016-02-10 05:40:46 -08002140Json::Value SkDrawPointsCommand::toJSON() const {
2141 Json::Value result = INHERITED::toJSON();
2142 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2143 Json::Value points(Json::arrayValue);
2144 for (size_t i = 0; i < fCount; i++) {
2145 points.append(make_json_point(fPts[i]));
2146 }
2147 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
2148 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2149 return result;
2150}
2151
2152SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command) {
2153 SkCanvas::PointMode mode;
2154 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2155 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2156 mode = SkCanvas::kPoints_PointMode;
2157 }
2158 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2159 mode = SkCanvas::kLines_PointMode;
2160 }
2161 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2162 mode = SkCanvas::kPolygon_PointMode;
2163 }
2164 else {
2165 SkASSERT(false);
2166 return nullptr;
2167 }
2168 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2169 int count = (int) jsonPoints.size();
2170 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2171 for (int i = 0; i < count; i++) {
2172 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2173 }
2174 SkPaint paint;
2175 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2176 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2177 sk_free(points);
2178 return result;
2179}
2180
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002181SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002182 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002183 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002184 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002185
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002186 fText = new char[byteLength];
2187 memcpy(fText, text, byteLength);
2188 fByteLength = byteLength;
2189
2190 fPos = new SkPoint[numPts];
2191 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2192
2193 fPaint = paint;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002194
2195 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
chudy@google.com902ebe52012-06-29 14:21:22 +00002196 // TODO(chudy): Test that this works.
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002197 fInfo.push(SkObjectParser::PointsToString(pos, 1));
2198 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002199}
2200
fmalita8c89c522014-11-08 16:18:56 -08002201void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002202 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002203}
2204
ethannicholas50a8dd02016-02-10 05:40:46 -08002205Json::Value SkDrawPosTextCommand::toJSON() const {
2206 Json::Value result = INHERITED::toJSON();
2207 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2208 ((const char*) fText) + fByteLength);
2209 Json::Value coords(Json::arrayValue);
2210 for (size_t i = 0; i < fByteLength; i++) {
2211 coords.append(make_json_point(fPos[i]));
2212 }
2213 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
2214 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2215 return result;
2216}
2217
2218SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command) {
2219 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2220 SkPaint paint;
2221 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2222 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2223 int count = (int) coords.size();
2224 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2225 for (int i = 0; i < count; i++) {
2226 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2227 }
2228 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2229}
chudy@google.com902ebe52012-06-29 14:21:22 +00002230
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002231SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2232 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002233 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002234 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002235 size_t numPts = paint.countText(text, byteLength);
2236
2237 fText = new char[byteLength];
2238 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002239 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002240
2241 fXpos = new SkScalar[numPts];
2242 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2243
robertphillips@google.com91217d02013-03-17 18:33:46 +00002244 fConstY = constY;
2245 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002246
robertphillips@google.com91217d02013-03-17 18:33:46 +00002247 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2248 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
2249 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
2250 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002251}
2252
fmalita8c89c522014-11-08 16:18:56 -08002253void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002254 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002255}
2256
fmalita0d48e412016-01-04 08:08:04 -08002257static const char* gPositioningLabels[] = {
2258 "kDefault_Positioning",
2259 "kHorizontal_Positioning",
2260 "kFull_Positioning",
2261};
2262
fmalitab7425172014-08-26 07:56:44 -07002263SkDrawTextBlobCommand::SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y,
2264 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002265 : INHERITED(kDrawTextBlob_OpType)
fmalitae77f2da2015-12-08 18:59:18 -08002266 , fBlob(SkRef(blob))
fmalitab7425172014-08-26 07:56:44 -07002267 , fXPos(x)
2268 , fYPos(y)
2269 , fPaint(paint) {
2270
fmalitae77f2da2015-12-08 18:59:18 -08002271 SkAutoTDelete<SkString> runsStr(new SkString);
fmalitab7425172014-08-26 07:56:44 -07002272 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
fmalitaff3106c2014-12-09 05:28:20 -08002273 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
2274 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
fmalitae77f2da2015-12-08 18:59:18 -08002275 fInfo.push(runsStr);
fmalitab7425172014-08-26 07:56:44 -07002276 fInfo.push(SkObjectParser::PaintToString(paint));
fmalitae77f2da2015-12-08 18:59:18 -08002277
2278 unsigned runs = 0;
2279 SkPaint runPaint(paint);
2280 SkTextBlobRunIterator iter(blob);
2281 while (!iter.done()) {
fmalita0d48e412016-01-04 08:08:04 -08002282 SkAutoTDelete<SkString> tmpStr(new SkString);
2283 tmpStr->printf("==== Run [%d] ====", runs++);
2284 fInfo.push(tmpStr.release());
fmalitae77f2da2015-12-08 18:59:18 -08002285
2286 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
fmalita0d48e412016-01-04 08:08:04 -08002287 tmpStr.reset(new SkString("GlyphPositioning: "));
2288 tmpStr->append(gPositioningLabels[iter.positioning()]);
2289 fInfo.push(tmpStr.release());
2290
fmalitae77f2da2015-12-08 18:59:18 -08002291 iter.applyFontToPaint(&runPaint);
2292 fInfo.push(SkObjectParser::PaintToString(runPaint));
2293
2294 iter.next();
2295 }
2296
2297 runsStr->printf("Runs: %d", runs);
2298 // runStr is owned by fInfo at this point.
2299 runsStr.release();
fmalitab7425172014-08-26 07:56:44 -07002300}
2301
fmalita8c89c522014-11-08 16:18:56 -08002302void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07002303 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2304}
2305
fmalita55773872014-08-29 15:08:20 -07002306bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
2307 canvas->clear(SK_ColorWHITE);
2308 canvas->save();
2309
2310 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
2311 xlate_and_scale_to_bounds(canvas, bounds);
2312
2313 canvas->drawTextBlob(fBlob.get(), fXPos, fYPos, fPaint);
2314
2315 canvas->restore();
2316
2317 return true;
2318}
2319
ethannicholas50a8dd02016-02-10 05:40:46 -08002320Json::Value SkDrawTextBlobCommand::toJSON() const {
2321 Json::Value result = INHERITED::toJSON();
2322 Json::Value runs(Json::arrayValue);
2323 SkTextBlobRunIterator iter(fBlob.get());
2324 while (!iter.done()) {
2325 Json::Value run(Json::objectValue);
2326 Json::Value jsonPositions(Json::arrayValue);
2327 Json::Value jsonGlyphs(Json::arrayValue);
2328 const SkScalar* iterPositions = iter.pos();
2329 const uint16_t* iterGlyphs = iter.glyphs();
2330 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
2331 switch (iter.positioning()) {
2332 case SkTextBlob::kFull_Positioning:
2333 jsonPositions.append(make_json_point(iterPositions[i * 2],
2334 iterPositions[i * 2 + 1]));
2335 break;
2336 case SkTextBlob::kHorizontal_Positioning:
2337 jsonPositions.append(Json::Value(iterPositions[i]));
2338 break;
2339 case SkTextBlob::kDefault_Positioning:
2340 break;
2341 }
2342 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
2343 }
2344 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
2345 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
2346 }
2347 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
2348 SkPaint fontPaint;
2349 iter.applyFontToPaint(&fontPaint);
2350 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = make_json_paint(fontPaint, SKDEBUGCANVAS_SEND_BINARIES);
2351 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(iter.offset());
2352 runs.append(run);
2353 iter.next();
2354 }
2355 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
2356 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
2357 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
2358 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2359 return result;
2360}
2361
2362SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command) {
2363 SkTextBlobBuilder builder;
2364 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
2365 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
2366 Json::Value run = runs[i];
2367 SkPaint font;
2368 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
2369 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], &font);
2370 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
2371 int count = glyphs.size();
2372 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2373 SkScalar x = coords[0].asFloat();
2374 SkScalar y = coords[1].asFloat();
2375 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
2376 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2377 if (positions.size() > 0 && positions[0].isNumeric()) {
2378 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y);
2379 for (int j = 0; j < count; j++) {
2380 buffer.glyphs[j] = glyphs[j].asUInt();
2381 buffer.pos[j] = positions[j].asFloat();
2382 }
2383 }
2384 else {
2385 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count);
2386 for (int j = 0; j < count; j++) {
2387 buffer.glyphs[j] = glyphs[j].asUInt();
2388 buffer.pos[j * 2] = positions[j][0].asFloat();
2389 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
2390 }
2391 }
2392 }
2393 else {
2394 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y);
2395 for (int j = 0; j < count; j++) {
2396 buffer.glyphs[j] = glyphs[j].asUInt();
2397 }
2398 }
2399 }
2400 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
2401 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2402 SkPaint paint;
2403 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2404 return new SkDrawTextBlobCommand(builder.build(), x, y, paint);
2405}
2406
robertphillips9bafc302015-02-13 11:13:00 -08002407SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
2408 const SkPoint texCoords[4], SkXfermode* xfermode,
2409 const SkPaint& paint)
2410 : INHERITED(kDrawPatch_OpType) {
2411 memcpy(fCubics, cubics, sizeof(fCubics));
2412 memcpy(fColors, colors, sizeof(fColors));
2413 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
2414 fXfermode.reset(xfermode);
2415 fPaint = paint;
2416
2417 fInfo.push(SkObjectParser::PaintToString(paint));
2418}
2419
2420void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
2421 canvas->drawPatch(fCubics, fColors, fTexCoords, fXfermode, fPaint);
2422}
2423
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002424SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002425 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002426 fRect = rect;
2427 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002428
robertphillips@google.com91217d02013-03-17 18:33:46 +00002429 fInfo.push(SkObjectParser::RectToString(rect));
2430 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002431}
2432
fmalita8c89c522014-11-08 16:18:56 -08002433void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002434 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002435}
2436
ethannicholas50a8dd02016-02-10 05:40:46 -08002437Json::Value SkDrawRectCommand::toJSON() const {
2438 Json::Value result = INHERITED::toJSON();
2439 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect);
2440 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2441 return result;
2442}
2443
2444SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command) {
2445 SkRect coords;
2446 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2447 SkPaint paint;
2448 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2449 return new SkDrawRectCommand(coords, paint);
2450}
2451
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002452SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002453 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002454 fRRect = rrect;
2455 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002456
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002457 fInfo.push(SkObjectParser::RRectToString(rrect));
2458 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00002459}
2460
fmalita8c89c522014-11-08 16:18:56 -08002461void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00002462 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002463}
2464
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002465bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002466 render_rrect(canvas, fRRect);
2467 return true;
2468}
2469
ethannicholas50a8dd02016-02-10 05:40:46 -08002470Json::Value SkDrawRRectCommand::toJSON() const {
2471 Json::Value result = INHERITED::toJSON();
2472 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
2473 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2474 return result;
2475}
2476
2477SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command) {
2478 SkRRect coords;
2479 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2480 SkPaint paint;
2481 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2482 return new SkDrawRRectCommand(coords, paint);
2483}
2484
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00002485SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002486 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002487 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002488 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002489 fOuter = outer;
2490 fInner = inner;
2491 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002492
2493 fInfo.push(SkObjectParser::RRectToString(outer));
2494 fInfo.push(SkObjectParser::RRectToString(inner));
2495 fInfo.push(SkObjectParser::PaintToString(paint));
2496}
2497
fmalita8c89c522014-11-08 16:18:56 -08002498void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002499 canvas->drawDRRect(fOuter, fInner, fPaint);
2500}
2501
2502bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
2503 render_drrect(canvas, fOuter, fInner);
2504 return true;
2505}
2506
ethannicholas50a8dd02016-02-10 05:40:46 -08002507Json::Value SkDrawDRRectCommand::toJSON() const {
2508 Json::Value result = INHERITED::toJSON();
2509 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
2510 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
2511 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2512 return result;
2513}
2514
2515SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command) {
2516 SkRRect outer;
2517 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
2518 SkRRect inner;
2519 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
2520 SkPaint paint;
2521 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2522 return new SkDrawDRRectCommand(outer, inner, paint);
2523}
2524
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002525SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002526 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002527 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002528 fText = new char[byteLength];
2529 memcpy(fText, text, byteLength);
2530 fByteLength = byteLength;
2531 fX = x;
2532 fY = y;
2533 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002534
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002535 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2536 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
2537 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
2538 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002539}
2540
fmalita8c89c522014-11-08 16:18:56 -08002541void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002542 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002543}
2544
ethannicholas50a8dd02016-02-10 05:40:46 -08002545Json::Value SkDrawTextCommand::toJSON() const {
2546 Json::Value result = INHERITED::toJSON();
2547 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2548 ((const char*) fText) + fByteLength);
2549 Json::Value coords(Json::arrayValue);
2550 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fX, fY);
2551 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2552 return result;
2553}
2554
2555SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command) {
2556 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2557 SkPaint paint;
2558 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2559 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2560 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
2561 paint);
2562}
2563
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002564SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
2565 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002566 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002567 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002568 fText = new char[byteLength];
2569 memcpy(fText, text, byteLength);
2570 fByteLength = byteLength;
2571 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07002572 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002573 fMatrix = *matrix;
2574 } else {
2575 fMatrix.setIdentity();
2576 }
2577 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002578
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002579 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2580 fInfo.push(SkObjectParser::PathToString(path));
bsalomon49f085d2014-09-05 13:34:00 -07002581 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002582 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2583 }
2584 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002585}
2586
fmalita8c89c522014-11-08 16:18:56 -08002587void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002588 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07002589 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002590 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002591}
2592
ethannicholas50a8dd02016-02-10 05:40:46 -08002593Json::Value SkDrawTextOnPathCommand::toJSON() const {
2594 Json::Value result = INHERITED::toJSON();
2595 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2596 ((const char*) fText) + fByteLength);
2597 Json::Value coords(Json::arrayValue);
2598 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
2599 if (!fMatrix.isIdentity()) {
2600 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix);
2601 }
2602 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2603 return result;
2604}
2605
2606SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command) {
2607 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2608 SkPaint paint;
2609 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2610 SkPath path;
2611 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2612 SkMatrix* matrixPtr;
2613 SkMatrix matrix;
2614 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
2615 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
2616 matrixPtr = &matrix;
2617 }
2618 else {
2619 matrixPtr = nullptr;
2620 }
2621 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
2622}
2623
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002624SkDrawVerticesCommand::SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount,
2625 const SkPoint vertices[], const SkPoint texs[],
2626 const SkColor colors[], SkXfermode* xfermode,
2627 const uint16_t indices[], int indexCount,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002628 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002629 : INHERITED(kDrawVertices_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002630 fVmode = vmode;
2631
2632 fVertexCount = vertexCount;
2633
2634 fVertices = new SkPoint[vertexCount];
2635 memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint));
2636
bsalomon49f085d2014-09-05 13:34:00 -07002637 if (texs) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002638 fTexs = new SkPoint[vertexCount];
2639 memcpy(fTexs, texs, vertexCount * sizeof(SkPoint));
2640 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002641 fTexs = nullptr;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002642 }
2643
bsalomon49f085d2014-09-05 13:34:00 -07002644 if (colors) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002645 fColors = new SkColor[vertexCount];
2646 memcpy(fColors, colors, vertexCount * sizeof(SkColor));
2647 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002648 fColors = nullptr;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002649 }
2650
2651 fXfermode = xfermode;
bsalomon49f085d2014-09-05 13:34:00 -07002652 if (fXfermode) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002653 fXfermode->ref();
2654 }
2655
2656 if (indexCount > 0) {
2657 fIndices = new uint16_t[indexCount];
2658 memcpy(fIndices, indices, indexCount * sizeof(uint16_t));
2659 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002660 fIndices = nullptr;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002661 }
2662
2663 fIndexCount = indexCount;
2664 fPaint = paint;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002665
chudy@google.com902ebe52012-06-29 14:21:22 +00002666 // TODO(chudy)
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002667 fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
2668 fInfo.push(SkObjectParser::PaintToString(paint));
2669}
2670
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002671SkDrawVerticesCommand::~SkDrawVerticesCommand() {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002672 delete [] fVertices;
2673 delete [] fTexs;
2674 delete [] fColors;
2675 SkSafeUnref(fXfermode);
2676 delete [] fIndices;
chudy@google.com902ebe52012-06-29 14:21:22 +00002677}
2678
fmalita8c89c522014-11-08 16:18:56 -08002679void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002680 canvas->drawVertices(fVmode, fVertexCount, fVertices,
2681 fTexs, fColors, fXfermode, fIndices,
2682 fIndexCount, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002683}
2684
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002685SkRestoreCommand::SkRestoreCommand()
robertphillips9bafc302015-02-13 11:13:00 -08002686 : INHERITED(kRestore_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002687 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
chudy@google.com902ebe52012-06-29 14:21:22 +00002688}
2689
fmalita8c89c522014-11-08 16:18:56 -08002690void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00002691 canvas->restore();
2692}
2693
ethannicholas50a8dd02016-02-10 05:40:46 -08002694SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command) {
2695 return new SkRestoreCommand();
2696}
2697
Florin Malita5f6102d2014-06-30 10:13:28 -04002698SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08002699 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00002700}
2701
fmalita8c89c522014-11-08 16:18:56 -08002702void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04002703 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00002704}
2705
ethannicholas50a8dd02016-02-10 05:40:46 -08002706SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command) {
2707 return new SkSaveCommand();
2708}
2709
reed4960eee2015-12-18 07:09:18 -08002710SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08002711 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08002712 if (rec.fBounds) {
2713 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002714 } else {
2715 fBounds.setEmpty();
2716 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002717
reed4960eee2015-12-18 07:09:18 -08002718 if (rec.fPaint) {
2719 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002720 fPaintPtr = &fPaint;
2721 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002722 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002723 }
reed4960eee2015-12-18 07:09:18 -08002724 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002725
ethannicholas50a8dd02016-02-10 05:40:46 -08002726 if (rec.fBackdrop) {
2727 fBackdrop = rec.fBackdrop;
2728 fBackdrop->ref();
2729 } else {
2730 fBackdrop = nullptr;
2731 }
2732
reed4960eee2015-12-18 07:09:18 -08002733 if (rec.fBounds) {
2734 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002735 }
reed4960eee2015-12-18 07:09:18 -08002736 if (rec.fPaint) {
2737 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002738 }
reed4960eee2015-12-18 07:09:18 -08002739 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00002740}
2741
ethannicholas50a8dd02016-02-10 05:40:46 -08002742SkSaveLayerCommand::~SkSaveLayerCommand() {
2743 if (fBackdrop != nullptr) {
2744 fBackdrop->unref();
2745 }
2746}
2747
fmalita8c89c522014-11-08 16:18:56 -08002748void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08002749 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
2750 fPaintPtr,
2751 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00002752}
2753
fmalita8c89c522014-11-08 16:18:56 -08002754void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
commit-bot@chromium.org1643b2c2014-03-03 23:25:41 +00002755 canvas->save();
2756}
2757
ethannicholas50a8dd02016-02-10 05:40:46 -08002758Json::Value SkSaveLayerCommand::toJSON() const {
2759 Json::Value result = INHERITED::toJSON();
2760 if (!fBounds.isEmpty()) {
2761 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = make_json_rect(fBounds);
2762 }
2763 if (fPaintPtr != nullptr) {
2764 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
2765 SKDEBUGCANVAS_SEND_BINARIES);
2766 }
2767 if (fBackdrop != nullptr) {
2768 Json::Value jsonBackdrop;
2769 flatten(fBackdrop, &jsonBackdrop, SKDEBUGCANVAS_SEND_BINARIES);
2770 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
2771 }
2772 if (fSaveLayerFlags != 0) {
2773 SkDebugf("unsupported: saveLayer flags\n");
2774 SkASSERT(false);
2775 }
2776 return result;
2777}
2778
2779SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command) {
2780 SkCanvas::SaveLayerRec rec;
2781 SkRect bounds;
2782 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
2783 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
2784 rec.fBounds = &bounds;
2785 }
2786 SkPaint paint;
2787 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2788 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2789 rec.fPaint = &paint;
2790 }
2791 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
2792 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
2793 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop);
2794 }
2795 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
2796 if (rec.fBackdrop != nullptr) {
2797 rec.fBackdrop->unref();
2798 }
2799 return result;
2800}
2801
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002802SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08002803 : INHERITED(kSetMatrix_OpType) {
robertphillips70171682014-10-16 14:28:28 -07002804 fUserMatrix.reset();
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002805 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00002806
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002807 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00002808}
2809
robertphillips70171682014-10-16 14:28:28 -07002810void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
2811 fUserMatrix = userMatrix;
2812}
2813
fmalita8c89c522014-11-08 16:18:56 -08002814void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
robertphillips70171682014-10-16 14:28:28 -07002815 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
2816 canvas->setMatrix(temp);
chudy@google.com902ebe52012-06-29 14:21:22 +00002817}
2818
ethannicholas50a8dd02016-02-10 05:40:46 -08002819Json::Value SkSetMatrixCommand::toJSON() const {
2820 Json::Value result = INHERITED::toJSON();
2821 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix);
2822 return result;
2823}
2824
2825SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command) {
2826 SkMatrix matrix;
2827 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
2828 return new SkSetMatrixCommand(matrix);
2829}