blob: e9cdd32e085df74068808eb367b746203697ac2c [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
570void store_scalar(Json::Value* target, const char* key, SkScalar value, SkScalar defaultValue) {
571 if (value != defaultValue) {
572 (*target)[key] = Json::Value(value);
573 }
574}
575
576void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
577 if (value != defaultValue) {
578 (*target)[key] = Json::Value(value);
579 }
580}
581
582static void encode_data(const void* data, size_t count, Json::Value* target) {
583 // just use a brain-dead JSON array for now, switch to base64 or something else smarter down the
584 // road
585 for (size_t i = 0; i < count; i++) {
586 target->append(((const uint8_t*)data)[i]);
587 }
588}
589
590static void flatten(const SkFlattenable* flattenable, Json::Value* target, bool sendBinaries) {
591 if (sendBinaries) {
592 SkWriteBuffer buffer;
593 flattenable->flatten(buffer);
594 void* data = sk_malloc_throw(buffer.bytesWritten());
595 buffer.writeToMemory(data);
596 Json::Value bytes;
597 encode_data(data, buffer.bytesWritten(), &bytes);
598 Json::Value jsonFlattenable;
599 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
600 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_BYTES] = bytes;
601 (*target) = jsonFlattenable;
602 sk_free(data);
603 } else {
604 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(flattenable->getTypeName());
605 }
606}
607
608static bool SK_WARN_UNUSED_RESULT flatten(const SkImage& image, Json::Value* target,
609 bool sendBinaries) {
610 if (sendBinaries) {
611 SkData* encoded = image.encode(SkImageEncoder::kPNG_Type, 100);
612 if (encoded == nullptr) {
613 // PNG encode doesn't necessarily support all color formats, convert to a different
614 // format
615 size_t rowBytes = 4 * image.width();
616 void* buffer = sk_malloc_throw(rowBytes * image.height());
617 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
618 kN32_SkColorType, kPremul_SkAlphaType);
619 if (!image.readPixels(dstInfo, buffer, rowBytes, 0, 0)) {
620 SkDebugf("readPixels failed\n");
621 return false;
622 }
623 SkImage* converted = SkImage::NewRasterCopy(dstInfo, buffer, rowBytes);
624 encoded = converted->encode(SkImageEncoder::kPNG_Type, 100);
625 if (encoded == nullptr) {
626 SkDebugf("image encode failed\n");
627 return false;
628 }
629 sk_free(converted);
630 sk_free(buffer);
631 }
632 Json::Value bytes;
633 encode_data(encoded->data(), encoded->size(), &bytes);
634 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BYTES] = bytes;
635 encoded->unref();
636 } else {
637 SkString description = SkStringPrintf("%dx%d pixel image", image.width(), image.height());
638 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION] = Json::Value(description.c_str());
639 }
640 return true;
641}
642
643static const char* color_type_name(SkColorType colorType) {
644 switch (colorType) {
645 case kARGB_4444_SkColorType:
646 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
647 case kRGBA_8888_SkColorType:
648 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
649 case kBGRA_8888_SkColorType:
650 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
651 case kRGB_565_SkColorType:
652 return SKDEBUGCANVAS_COLORTYPE_565;
653 case kGray_8_SkColorType:
654 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
655 case kIndex_8_SkColorType:
656 return SKDEBUGCANVAS_COLORTYPE_INDEX8;
657 case kAlpha_8_SkColorType:
658 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
659 default:
660 SkASSERT(false);
661 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
662 }
663}
664
665static const char* alpha_type_name(SkAlphaType alphaType) {
666 switch (alphaType) {
667 case kOpaque_SkAlphaType:
668 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
669 case kPremul_SkAlphaType:
670 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
671 case kUnpremul_SkAlphaType:
672 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
673 default:
674 SkASSERT(false);
675 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
676 }
677}
678
679// note that the caller is responsible for freeing the pointer
680static Json::ArrayIndex decode_data(Json::Value bytes, void** target) {
681 Json::ArrayIndex size = bytes.size();
682 *target = sk_malloc_throw(size);
683 for (Json::ArrayIndex i = 0; i < size; i++) {
684 ((uint8_t*) *target)[i] = bytes[i].asInt();
685 }
686 return size;
687}
688
689static SkFlattenable* load_flattenable(Json::Value jsonFlattenable) {
690 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
691 return nullptr;
692 }
693 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
694 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
695 if (factory == nullptr) {
696 SkDebugf("no factory for loading '%s'\n", name);
697 return nullptr;
698 }
699 void* data;
700 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_BYTES], &data);
701 SkValidatingReadBuffer buffer(data, size);
702 SkFlattenable* result = factory(buffer);
703 sk_free(data);
704 if (!buffer.isValid()) {
705 SkDebugf("invalid buffer loading flattenable\n");
706 return nullptr;
707 }
708 return result;
709}
710
711static SkColorType colortype_from_name(const char* name) {
712 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
713 return kARGB_4444_SkColorType;
714 }
715 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
716 return kRGBA_8888_SkColorType;
717 }
718 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
719 return kBGRA_8888_SkColorType;
720 }
721 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
722 return kRGB_565_SkColorType;
723 }
724 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
725 return kGray_8_SkColorType;
726 }
727 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_INDEX8)) {
728 return kIndex_8_SkColorType;
729 }
730 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
731 return kAlpha_8_SkColorType;
732 }
733 SkASSERT(false);
734 return kN32_SkColorType;
735}
736
737static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
738 if (bitmap->colorType() == colorType ) {
739 return bitmap;
740 }
741 SkBitmap* dst = new SkBitmap();
742 if (bitmap->copyTo(dst, colorType)) {
743 delete bitmap;
744 return dst;
745 }
746 SkASSERT(false);
747 delete dst;
748 return bitmap;
749}
750
751// caller is responsible for freeing return value
752static SkBitmap* load_bitmap(const Json::Value& jsonBitmap) {
753 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_BYTES)) {
754 SkDebugf("invalid bitmap\n");
755 return nullptr;
756 }
757 void* data;
758 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_BYTES], &data);
759 SkMemoryStream stream(data, size);
760 SkImageDecoder* decoder = SkImageDecoder::Factory(&stream);
761 SkBitmap* bitmap = new SkBitmap();
762 SkImageDecoder::Result result = decoder->decode(&stream, bitmap,
763 SkImageDecoder::kDecodePixels_Mode);
764 sk_free(decoder);
765 if (result != SkImageDecoder::kFailure) {
766 sk_free(data);
767 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
768 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
769 SkColorType ct = colortype_from_name(ctName);
770 if (ct != kIndex_8_SkColorType) {
771 bitmap = convert_colortype(bitmap, ct);
772 }
773 }
774 return bitmap;
775 }
776 SkDebugf("image decode failed\n");
777 sk_free(data);
778 return nullptr;
779}
780
781static SkImage* load_image(const Json::Value& jsonImage) {
782 SkBitmap* bitmap = load_bitmap(jsonImage);
783 if (bitmap == nullptr) {
784 return nullptr;
785 }
786 SkImage* result = SkImage::NewFromBitmap(*bitmap);
787 delete bitmap;
788 return result;
789}
790
791static bool SK_WARN_UNUSED_RESULT flatten(const SkBitmap& bitmap, Json::Value* target,
792 bool sendBinaries) {
793 bitmap.lockPixels();
794 SkAutoTUnref<SkImage> image(SkImage::NewFromBitmap(bitmap));
795 bitmap.unlockPixels();
796 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
797 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
798 bool success = flatten(*image, target, sendBinaries);
799 return success;
800}
801
802static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
803 SkColor color = paint.getColor();
804 if (color != SK_ColorBLACK) {
805 Json::Value colorValue(Json::arrayValue);
806 colorValue.append(Json::Value(SkColorGetA(color)));
807 colorValue.append(Json::Value(SkColorGetR(color)));
808 colorValue.append(Json::Value(SkColorGetG(color)));
809 colorValue.append(Json::Value(SkColorGetB(color)));
810 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
811 }
812}
813
814static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
815 SkPaint::Style style = paint.getStyle();
816 if (style != SkPaint::kFill_Style) {
817 switch (style) {
818 case SkPaint::kStroke_Style: {
819 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
820 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
821 break;
822 }
823 case SkPaint::kStrokeAndFill_Style: {
824 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
825 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
826 break;
827 }
828 default: SkASSERT(false);
829 }
830 }
831}
832
833static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
834 SkPaint::Cap cap = paint.getStrokeCap();
835 if (cap != SkPaint::kDefault_Cap) {
836 switch (cap) {
837 case SkPaint::kButt_Cap: {
838 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
839 break;
840 }
841 case SkPaint::kRound_Cap: {
842 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
843 break;
844 }
845 case SkPaint::kSquare_Cap: {
846 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
847 break;
848 }
849 default: SkASSERT(false);
850 }
851 }
852}
853static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
854 SkMaskFilter* maskFilter = paint.getMaskFilter();
855 if (maskFilter != nullptr) {
856 SkMaskFilter::BlurRec blurRec;
857 if (maskFilter->asABlur(&blurRec)) {
858 Json::Value blur(Json::objectValue);
859 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
860 switch (blurRec.fStyle) {
861 case SkBlurStyle::kNormal_SkBlurStyle:
862 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_NORMAL);
863 break;
864 case SkBlurStyle::kSolid_SkBlurStyle:
865 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_SOLID);
866 break;
867 case SkBlurStyle::kOuter_SkBlurStyle:
868 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_OUTER);
869 break;
870 case SkBlurStyle::kInner_SkBlurStyle:
871 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(SKDEBUGCANVAS_BLURSTYLE_INNER);
872 break;
873 default:
874 SkASSERT(false);
875 }
876 switch (blurRec.fQuality) {
877 case SkBlurQuality::kLow_SkBlurQuality:
878 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKDEBUGCANVAS_BLURQUALITY_LOW);
879 break;
880 case SkBlurQuality::kHigh_SkBlurQuality:
881 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(SKDEBUGCANVAS_BLURQUALITY_HIGH);
882 break;
883 default:
884 SkASSERT(false);
885 }
886 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
887 } else {
888 Json::Value jsonMaskFilter;
889 flatten(maskFilter, &jsonMaskFilter, sendBinaries);
890 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
891 }
892 }
893}
894
895static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
896 SkPathEffect* pathEffect = paint.getPathEffect();
897 if (pathEffect != nullptr) {
898 SkPathEffect::DashInfo dashInfo;
899 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
900 if (dashType == SkPathEffect::kDash_DashType) {
901 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
902 pathEffect->asADash(&dashInfo);
903 Json::Value dashing(Json::objectValue);
904 Json::Value intervals(Json::arrayValue);
905 for (int32_t i = 0; i < dashInfo.fCount; i++) {
906 intervals.append(Json::Value(dashInfo.fIntervals[i]));
907 }
908 sk_free(dashInfo.fIntervals);
909 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
910 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
911 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
912 } else {
913 Json::Value jsonPathEffect;
914 flatten(pathEffect, &jsonPathEffect, sendBinaries);
915 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
916 }
917 }
918}
919
920static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
921 SkPaint::Align textAlign = paint.getTextAlign();
922 if (textAlign != SkPaint::kLeft_Align) {
923 switch (textAlign) {
924 case SkPaint::kCenter_Align: {
925 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
926 break;
927 }
928 case SkPaint::kRight_Align: {
929 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
930 break;
931 }
932 default: SkASSERT(false);
933 }
934 }
935}
936
937static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
938 bool sendBinaries) {
939 SkTypeface* typeface = paint.getTypeface();
940 if (typeface != nullptr) {
941 if (sendBinaries) {
942 Json::Value jsonTypeface;
943 SkDynamicMemoryWStream buffer;
944 typeface->serialize(&buffer);
945 void* data = sk_malloc_throw(buffer.bytesWritten());
946 buffer.copyTo(data);
947 Json::Value bytes;
948 encode_data(data, buffer.bytesWritten(), &bytes);
949 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_BYTES] = bytes;
950 sk_free(data);
951 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
952 }
953 }
954}
955
956static void apply_paint_shader(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
957 SkFlattenable* shader = paint.getShader();
958 if (shader != nullptr) {
959 Json::Value jsonShader;
960 flatten(shader, &jsonShader, sendBinaries);
961 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
962 }
963}
964
965static void apply_paint_xfermode(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
966 SkFlattenable* xfermode = paint.getXfermode();
967 if (xfermode != nullptr) {
968 Json::Value jsonXfermode;
969 flatten(xfermode, &jsonXfermode, sendBinaries);
970 (*target)[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE] = jsonXfermode;
971 }
972}
973
974static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
975 SkFlattenable* imageFilter = paint.getImageFilter();
976 if (imageFilter != nullptr) {
977 Json::Value jsonImageFilter;
978 flatten(imageFilter, &jsonImageFilter, sendBinaries);
979 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
980 }
981}
982
983static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target, bool sendBinaries) {
984 SkFlattenable* colorFilter = paint.getColorFilter();
985 if (colorFilter != nullptr) {
986 Json::Value jsonColorFilter;
987 flatten(colorFilter, &jsonColorFilter, sendBinaries);
988 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
989 }
990}
991
992Json::Value make_json_paint(const SkPaint& paint, bool sendBinaries) {
993 Json::Value result(Json::objectValue);
994 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
995 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
996 SkPaintDefaults_MiterLimit);
997 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
998 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
999 SkPaintDefaults_TextSize);
1000 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1001 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
1002 apply_paint_color(paint, &result);
1003 apply_paint_style(paint, &result);
1004 apply_paint_cap(paint, &result);
1005 apply_paint_textalign(paint, &result);
1006 apply_paint_patheffect(paint, &result, sendBinaries);
1007 apply_paint_maskfilter(paint, &result, sendBinaries);
1008 apply_paint_shader(paint, &result, sendBinaries);
1009 apply_paint_xfermode(paint, &result, sendBinaries);
1010 apply_paint_imagefilter(paint, &result, sendBinaries);
1011 apply_paint_colorfilter(paint, &result, sendBinaries);
1012 apply_paint_typeface(paint, &result, sendBinaries);
1013 return result;
1014}
1015
1016static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1017 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
1018 Json::Value color = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1019 target->setColor(SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(),
1020 color[3].asInt()));
1021 }
1022}
1023
1024static void extract_json_paint_shader(Json::Value& jsonPaint, SkPaint* target) {
1025 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1026 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
1027 SkShader* shader = (SkShader*) load_flattenable(jsonShader);
1028 if (shader != nullptr) {
1029 target->setShader(shader);
1030 shader->unref();
1031 }
1032 }
1033}
1034
1035static void extract_json_paint_patheffect(Json::Value& jsonPaint, SkPaint* target) {
1036 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1037 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
1038 SkPathEffect* pathEffect = (SkPathEffect*) load_flattenable(jsonPathEffect);
1039 if (pathEffect != nullptr) {
1040 target->setPathEffect(pathEffect);
1041 pathEffect->unref();
1042 }
1043 }
1044}
1045
1046static void extract_json_paint_maskfilter(Json::Value& jsonPaint, SkPaint* target) {
1047 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1048 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
1049 SkMaskFilter* maskFilter = (SkMaskFilter*) load_flattenable(jsonMaskFilter);
1050 if (maskFilter != nullptr) {
1051 target->setMaskFilter(maskFilter);
1052 maskFilter->unref();
1053 }
1054 }
1055}
1056
1057static void extract_json_paint_colorfilter(Json::Value& jsonPaint, SkPaint* target) {
1058 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1059 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
1060 SkColorFilter* colorFilter = (SkColorFilter*) load_flattenable(jsonColorFilter);
1061 if (colorFilter != nullptr) {
1062 target->setColorFilter(colorFilter);
1063 colorFilter->unref();
1064 }
1065 }
1066}
1067
1068static void extract_json_paint_xfermode(Json::Value& jsonPaint, SkPaint* target) {
1069 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_XFERMODE)) {
1070 Json::Value jsonXfermode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_XFERMODE];
1071 SkXfermode* xfermode = (SkXfermode*) load_flattenable(jsonXfermode);
1072 if (xfermode != nullptr) {
1073 target->setXfermode(xfermode);
1074 xfermode->unref();
1075 }
1076 }
1077}
1078
1079static void extract_json_paint_imagefilter(Json::Value& jsonPaint, SkPaint* target) {
1080 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1081 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
1082 SkImageFilter* imageFilter = (SkImageFilter*) load_flattenable(jsonImageFilter);
1083 if (imageFilter != nullptr) {
1084 target->setImageFilter(imageFilter);
1085 imageFilter->unref();
1086 }
1087 }
1088}
1089
1090static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1091 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1092 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1093 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1094 target->setStyle(SkPaint::kFill_Style);
1095 }
1096 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1097 target->setStyle(SkPaint::kStroke_Style);
1098 }
1099 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1100 target->setStyle(SkPaint::kStrokeAndFill_Style);
1101 }
1102 }
1103}
1104
1105static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1106 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1107 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1108 target->setStrokeWidth(strokeWidth);
1109 }
1110}
1111
1112static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1113 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1114 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1115 target->setStrokeMiter(strokeMiter);
1116 }
1117}
1118
1119static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1120 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1121 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1122 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1123 target->setStrokeCap(SkPaint::kButt_Cap);
1124 }
1125 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1126 target->setStrokeCap(SkPaint::kRound_Cap);
1127 }
1128 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1129 target->setStrokeCap(SkPaint::kSquare_Cap);
1130 }
1131 }
1132}
1133
1134static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1135 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1136 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1137 }
1138}
1139
1140static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1141 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1142 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1143 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1144 SkBlurStyle style;
1145 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1146 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1147 style = SkBlurStyle::kNormal_SkBlurStyle;
1148 }
1149 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1150 style = SkBlurStyle::kSolid_SkBlurStyle;
1151 }
1152 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1153 style = SkBlurStyle::kOuter_SkBlurStyle;
1154 }
1155 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1156 style = SkBlurStyle::kInner_SkBlurStyle;
1157 }
1158 else {
1159 SkASSERT(false);
1160 style = SkBlurStyle::kNormal_SkBlurStyle;
1161 }
1162 SkBlurMaskFilter::BlurFlags flags;
1163 const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString();
1164 if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) {
1165 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1166 }
1167 else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) {
1168 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag;
1169 }
1170 else {
1171 SkASSERT(false);
1172 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1173 }
1174 target->setMaskFilter(SkBlurMaskFilter::Create(style, sigma, flags));
1175 }
1176}
1177
1178static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1179 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1180 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1181 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1182 Json::ArrayIndex count = jsonIntervals.size();
1183 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1184 for (Json::ArrayIndex i = 0; i < count; i++) {
1185 intervals[i] = jsonIntervals[i].asFloat();
1186 }
1187 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
1188 target->setPathEffect(SkDashPathEffect::Create(intervals, count, phase));
1189 sk_free(intervals);
1190 }
1191}
1192
1193static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1194 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1195 SkPaint::Align textAlign;
1196 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1197 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1198 textAlign = SkPaint::kLeft_Align;
1199 }
1200 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1201 textAlign = SkPaint::kCenter_Align;
1202 }
1203 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1204 textAlign = SkPaint::kRight_Align;
1205 }
1206 else {
1207 SkASSERT(false);
1208 textAlign = SkPaint::kLeft_Align;
1209 }
1210 target->setTextAlign(textAlign);
1211 }
1212}
1213
1214static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1215 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1216 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1217 target->setTextSize(textSize);
1218 }
1219}
1220
1221static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1222 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1223 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1224 target->setTextScaleX(textScaleX);
1225 }
1226}
1227
1228static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1229 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1230 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1231 target->setTextSkewX(textSkewX);
1232 }
1233}
1234
1235static void extract_json_paint_typeface(Json::Value& jsonPaint, SkPaint* target) {
1236 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1237 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1238 Json::Value bytes = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_BYTES];
1239 void* data;
1240 Json::ArrayIndex length = decode_data(bytes, &data);
1241 SkMemoryStream buffer(data, length);
1242 SkTypeface* typeface = SkTypeface::Deserialize(&buffer);
1243 sk_free(data);
1244 target->setTypeface(typeface);
1245 }
1246}
1247
1248static void extract_json_paint(Json::Value& paint, SkPaint* result) {
1249 extract_json_paint_color(paint, result);
1250 extract_json_paint_shader(paint, result);
1251 extract_json_paint_patheffect(paint, result);
1252 extract_json_paint_maskfilter(paint, result);
1253 extract_json_paint_colorfilter(paint, result);
1254 extract_json_paint_xfermode(paint, result);
1255 extract_json_paint_imagefilter(paint, result);
1256 extract_json_paint_style(paint, result);
1257 extract_json_paint_strokewidth(paint, result);
1258 extract_json_paint_strokemiter(paint, result);
1259 extract_json_paint_cap(paint, result);
1260 extract_json_paint_antialias(paint, result);
1261 extract_json_paint_blur(paint, result);
1262 extract_json_paint_dashing(paint, result);
1263 extract_json_paint_textalign(paint, result);
1264 extract_json_paint_textsize(paint, result);
1265 extract_json_paint_textscalex(paint, result);
1266 extract_json_paint_textskewx(paint, result);
1267 extract_json_paint_typeface(paint, result);
1268}
1269
1270static void extract_json_rect(Json::Value& rect, SkRect* result) {
1271 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1272}
1273
1274static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1275 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1276}
1277
1278static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1279 SkVector radii[4] = {
1280 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1281 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1282 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
1283 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1284 };
1285 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1286 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
1287 radii);
1288}
1289
1290static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
1291 SkScalar values[] = {
1292 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1293 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
1294 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
1295 };
1296 result->set9(values);
1297}
1298
1299static void extract_json_path(Json::Value& path, SkPath* result) {
1300 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1301 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1302 result->setFillType(SkPath::kWinding_FillType);
1303 }
1304 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1305 result->setFillType(SkPath::kEvenOdd_FillType);
1306 }
1307 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1308 result->setFillType(SkPath::kInverseWinding_FillType);
1309 }
1310 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1311 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1312 }
1313 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1314 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1315 Json::Value verb = verbs[i];
1316 if (verb.isString()) {
1317 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1318 result->close();
1319 }
1320 else {
1321 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1322 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1323 result->moveTo(move[0].asFloat(), move[1].asFloat());
1324 }
1325 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1326 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1327 result->lineTo(line[0].asFloat(), line[1].asFloat());
1328 }
1329 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1330 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1331 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1332 quad[1][0].asFloat(), quad[1][1].asFloat());
1333 }
1334 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1335 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1336 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1337 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1338 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1339 }
1340 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1341 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1342 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1343 conic[1][0].asFloat(), conic[1][1].asFloat(),
1344 conic[2].asFloat());
1345 }
1346 else {
1347 SkASSERT(false);
1348 }
1349 }
1350 }
1351}
1352
1353SkRegion::Op get_json_regionop(Json::Value& jsonOp) {
1354 const char* op = jsonOp.asCString();
1355 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
1356 return SkRegion::kDifference_Op;
1357 }
1358 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
1359 return SkRegion::kIntersect_Op;
1360 }
1361 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
1362 return SkRegion::kUnion_Op;
1363 }
1364 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
1365 return SkRegion::kXOR_Op;
1366 }
1367 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
1368 return SkRegion::kReverseDifference_Op;
1369 }
1370 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
1371 return SkRegion::kReplace_Op;
1372 }
1373 SkASSERT(false);
1374 return SkRegion::kIntersect_Op;
1375}
1376
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001377
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001378SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkRegion::Op op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001379 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001380 fPath = path;
1381 fOp = op;
1382 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001383
robertphillips@google.com91217d02013-03-17 18:33:46 +00001384 fInfo.push(SkObjectParser::PathToString(path));
1385 fInfo.push(SkObjectParser::RegionOpToString(op));
1386 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001387}
1388
fmalita8c89c522014-11-08 16:18:56 -08001389void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001390 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001391}
1392
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001393bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001394 render_path(canvas, fPath);
1395 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001396}
1397
ethannicholas50a8dd02016-02-10 05:40:46 -08001398Json::Value SkClipPathCommand::toJSON() const {
1399 Json::Value result = INHERITED::toJSON();
1400 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
1401 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1402 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1403 return result;
1404}
1405
1406SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command) {
1407 SkPath path;
1408 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
1409 return new SkClipPathCommand(path, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1410 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1411}
1412
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001413SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkRegion::Op op)
robertphillips9bafc302015-02-13 11:13:00 -08001414 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001415 fRegion = region;
1416 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001417
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001418 fInfo.push(SkObjectParser::RegionToString(region));
1419 fInfo.push(SkObjectParser::RegionOpToString(op));
chudy@google.com902ebe52012-06-29 14:21:22 +00001420}
1421
fmalita8c89c522014-11-08 16:18:56 -08001422void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001423 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001424}
1425
ethannicholas50a8dd02016-02-10 05:40:46 -08001426Json::Value SkClipRegionCommand::toJSON() const {
1427 Json::Value result = INHERITED::toJSON();
1428 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = make_json_region(fRegion);
1429 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1430 return result;
1431}
1432
1433SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command) {
1434 SkASSERT(false);
1435 return nullptr;
1436}
1437
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001438SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkRegion::Op op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001439 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001440 fRect = rect;
1441 fOp = op;
1442 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001443
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001444 fInfo.push(SkObjectParser::RectToString(rect));
1445 fInfo.push(SkObjectParser::RegionOpToString(op));
1446 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001447}
1448
fmalita8c89c522014-11-08 16:18:56 -08001449void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001450 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001451}
1452
ethannicholas50a8dd02016-02-10 05:40:46 -08001453Json::Value SkClipRectCommand::toJSON() const {
1454 Json::Value result = INHERITED::toJSON();
1455 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect);
1456 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1457 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1458 return result;
1459}
1460
1461SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command) {
1462 SkRect rect;
1463 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
1464 return new SkClipRectCommand(rect, get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1465 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1466}
1467
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001468SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkRegion::Op op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001469 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001470 fRRect = rrect;
1471 fOp = op;
1472 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001473
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001474 fInfo.push(SkObjectParser::RRectToString(rrect));
1475 fInfo.push(SkObjectParser::RegionOpToString(op));
1476 fInfo.push(SkObjectParser::BoolToString(doAA));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001477}
1478
fmalita8c89c522014-11-08 16:18:56 -08001479void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001480 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001481}
1482
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001483bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001484 render_rrect(canvas, fRRect);
1485 return true;
1486}
1487
ethannicholas50a8dd02016-02-10 05:40:46 -08001488Json::Value SkClipRRectCommand::toJSON() const {
1489 Json::Value result = INHERITED::toJSON();
1490 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1491 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1492 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1493 return result;
1494}
1495
1496SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command) {
1497 SkRRect rrect;
1498 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
1499 return new SkClipRRectCommand(rrect,
1500 get_json_regionop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
1501 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1502}
1503
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001504SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001505 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001506 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001507
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001508 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00001509}
1510
fmalita8c89c522014-11-08 16:18:56 -08001511void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001512 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001513}
1514
ethannicholas50a8dd02016-02-10 05:40:46 -08001515Json::Value SkConcatCommand::toJSON() const {
1516 Json::Value result = INHERITED::toJSON();
1517 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix);
1518 return result;
1519}
1520
1521SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command) {
1522 SkMatrix matrix;
1523 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1524 return new SkConcatCommand(matrix);
1525}
1526
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001527SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07001528 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08001529 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001530 fBitmap = bitmap;
1531 fLeft = left;
1532 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07001533 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001534 fPaint = *paint;
1535 fPaintPtr = &fPaint;
1536 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001537 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001538 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001539
1540 fInfo.push(SkObjectParser::BitmapToString(bitmap));
1541 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
1542 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
bsalomon49f085d2014-09-05 13:34:00 -07001543 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001544 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001545 }
chudy@google.com902ebe52012-06-29 14:21:22 +00001546}
1547
fmalita8c89c522014-11-08 16:18:56 -08001548void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001549 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00001550}
1551
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001552bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001553 render_bitmap(canvas, fBitmap);
1554 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001555}
1556
ethannicholas50a8dd02016-02-10 05:40:46 -08001557Json::Value SkDrawBitmapCommand::toJSON() const {
1558 Json::Value result = INHERITED::toJSON();
1559 Json::Value encoded;
1560 if (flatten(fBitmap, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1561 Json::Value command(Json::objectValue);
1562 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1563 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop);
1564 if (fPaintPtr != nullptr) {
1565 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr, SKDEBUGCANVAS_SEND_BINARIES);
1566 }
1567 }
1568 return result;
1569}
1570
1571SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command) {
1572 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP]);
1573 if (bitmap == nullptr) {
1574 return nullptr;
1575 }
1576 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
1577 SkPaint* paintPtr;
1578 SkPaint paint;
1579 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1580 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1581 paintPtr = &paint;
1582 }
1583 else {
1584 paintPtr = nullptr;
1585 }
1586 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
1587 point[1].asFloat(), paintPtr);
1588 delete bitmap;
1589 return result;
1590}
1591
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001592SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001593 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08001594 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001595 fBitmap = bitmap;
1596 fCenter = center;
1597 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07001598 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001599 fPaint = *paint;
1600 fPaintPtr = &fPaint;
1601 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001602 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001603 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001604
1605 fInfo.push(SkObjectParser::BitmapToString(bitmap));
1606 fInfo.push(SkObjectParser::IRectToString(center));
1607 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07001608 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001609 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001610 }
chudy@google.com902ebe52012-06-29 14:21:22 +00001611}
1612
fmalita8c89c522014-11-08 16:18:56 -08001613void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001614 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00001615}
1616
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001617bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08001618 SkRect tmp = SkRect::Make(fCenter);
1619 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001620 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001621}
1622
ethannicholas50a8dd02016-02-10 05:40:46 -08001623Json::Value SkDrawBitmapNineCommand::toJSON() const {
1624 Json::Value result = INHERITED::toJSON();
1625 Json::Value encoded;
1626 if (flatten(fBitmap, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1627 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1628 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = make_json_irect(fCenter);
1629 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
1630 if (fPaintPtr != nullptr) {
1631 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
1632 SKDEBUGCANVAS_SEND_BINARIES);
1633 }
1634 }
1635 return result;
1636}
1637
1638SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command) {
1639 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP]);
1640 if (bitmap == nullptr) {
1641 return nullptr;
1642 }
1643 SkIRect center;
1644 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
1645 SkRect dst;
1646 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
1647 SkPaint* paintPtr;
1648 SkPaint paint;
1649 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1650 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1651 paintPtr = &paint;
1652 }
1653 else {
1654 paintPtr = nullptr;
1655 }
1656 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
1657 delete bitmap;
1658 return result;
1659}
1660
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001661SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00001662 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07001663 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08001664 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001665 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07001666 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001667 fSrc = *src;
1668 } else {
1669 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001670 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00001671 fDst = dst;
1672
bsalomon49f085d2014-09-05 13:34:00 -07001673 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001674 fPaint = *paint;
1675 fPaintPtr = &fPaint;
1676 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001677 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00001678 }
reeda5517e22015-07-14 10:54:12 -07001679 fConstraint = constraint;
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00001680
robertphillips@google.com91217d02013-03-17 18:33:46 +00001681 fInfo.push(SkObjectParser::BitmapToString(bitmap));
bsalomon49f085d2014-09-05 13:34:00 -07001682 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001683 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
1684 }
1685 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07001686 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001687 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001688 }
reeda5517e22015-07-14 10:54:12 -07001689 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
chudy@google.com902ebe52012-06-29 14:21:22 +00001690}
1691
fmalita8c89c522014-11-08 16:18:56 -08001692void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07001693 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001694}
1695
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001696bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001697 render_bitmap(canvas, fBitmap, this->srcRect());
1698 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001699}
1700
ethannicholas50a8dd02016-02-10 05:40:46 -08001701Json::Value SkDrawBitmapRectCommand::toJSON() const {
1702 Json::Value result = INHERITED::toJSON();
1703 Json::Value encoded;
1704 if (flatten(fBitmap, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1705 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1706 if (!fSrc.isEmpty()) {
1707 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(fSrc);
1708 }
1709 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
1710 if (fPaintPtr != nullptr) {
1711 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
1712 SKDEBUGCANVAS_SEND_BINARIES);
1713 }
1714 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1715 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
1716 }
1717 }
1718 return result;
1719}
1720
1721SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command) {
1722 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP]);
1723 if (bitmap == nullptr) {
1724 return nullptr;
1725 }
1726 SkRect dst;
1727 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
1728 SkPaint* paintPtr;
1729 SkPaint paint;
1730 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1731 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1732 paintPtr = &paint;
1733 }
1734 else {
1735 paintPtr = nullptr;
1736 }
1737 SkCanvas::SrcRectConstraint constraint;
1738 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
1739 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
1740 constraint = SkCanvas::kStrict_SrcRectConstraint;
1741 }
1742 else {
1743 constraint = SkCanvas::kFast_SrcRectConstraint;
1744 }
1745 SkRect* srcPtr;
1746 SkRect src;
1747 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
1748 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
1749 srcPtr = &src;
1750 }
1751 else {
1752 srcPtr = nullptr;
1753 }
1754 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
1755 constraint);
1756 delete bitmap;
1757 return result;
1758}
1759
fmalita651c9202015-07-22 10:23:01 -07001760SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
1761 const SkPaint* paint)
1762 : INHERITED(kDrawImage_OpType)
1763 , fImage(SkRef(image))
1764 , fLeft(left)
1765 , fTop(top) {
1766
fmalita7361bf02015-10-29 12:13:48 -07001767 fInfo.push(SkObjectParser::ImageToString(image));
1768 fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
1769 fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));
1770
fmalita651c9202015-07-22 10:23:01 -07001771 if (paint) {
1772 fPaint.set(*paint);
fmalita7361bf02015-10-29 12:13:48 -07001773 fInfo.push(SkObjectParser::PaintToString(*paint));
fmalita651c9202015-07-22 10:23:01 -07001774 }
1775}
1776
1777void SkDrawImageCommand::execute(SkCanvas* canvas) const {
1778 canvas->drawImage(fImage, fLeft, fTop, fPaint.getMaybeNull());
1779}
1780
1781bool SkDrawImageCommand::render(SkCanvas* canvas) const {
1782 SkAutoCanvasRestore acr(canvas, true);
1783 canvas->clear(0xFFFFFFFF);
1784
1785 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
1786 SkIntToScalar(fImage->width()),
1787 SkIntToScalar(fImage->height())));
1788 this->execute(canvas);
1789 return true;
1790}
1791
ethannicholas50a8dd02016-02-10 05:40:46 -08001792Json::Value SkDrawImageCommand::toJSON() const {
1793 Json::Value result = INHERITED::toJSON();
1794 Json::Value encoded;
1795 if (flatten(*fImage, &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1796 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
1797 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fLeft, fTop);
1798 if (fPaint.isValid()) {
1799 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(),
1800 SKDEBUGCANVAS_SEND_BINARIES);
1801 }
1802 }
1803 return result;
1804}
1805
1806SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command) {
1807 SkImage* image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE]);
1808 if (image == nullptr) {
1809 return nullptr;
1810 }
1811 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
1812 SkPaint* paintPtr;
1813 SkPaint paint;
1814 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1815 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1816 paintPtr = &paint;
1817 }
1818 else {
1819 paintPtr = nullptr;
1820 }
1821 SkDrawImageCommand* result = new SkDrawImageCommand(image, point[0].asFloat(),
1822 point[1].asFloat(), paintPtr);
1823 image->unref();
1824 return result;
1825}
1826
fmalita651c9202015-07-22 10:23:01 -07001827SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
1828 const SkRect& dst, const SkPaint* paint,
1829 SkCanvas::SrcRectConstraint constraint)
1830 : INHERITED(kDrawImageRect_OpType)
1831 , fImage(SkRef(image))
1832 , fDst(dst)
1833 , fConstraint(constraint) {
1834
1835 if (src) {
1836 fSrc.set(*src);
1837 }
1838
1839 if (paint) {
1840 fPaint.set(*paint);
1841 }
robertphillips80af6452015-08-24 08:27:38 -07001842
1843 fInfo.push(SkObjectParser::ImageToString(image));
1844 if (src) {
1845 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
1846 }
1847 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
1848 if (paint) {
1849 fInfo.push(SkObjectParser::PaintToString(*paint));
1850 }
1851 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
fmalita651c9202015-07-22 10:23:01 -07001852}
1853
1854void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07001855 canvas->legacy_drawImageRect(fImage, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07001856}
1857
1858bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
1859 SkAutoCanvasRestore acr(canvas, true);
1860 canvas->clear(0xFFFFFFFF);
1861
1862 xlate_and_scale_to_bounds(canvas, fDst);
1863
1864 this->execute(canvas);
1865 return true;
1866}
1867
ethannicholas50a8dd02016-02-10 05:40:46 -08001868Json::Value SkDrawImageRectCommand::toJSON() const {
1869 Json::Value result = INHERITED::toJSON();
1870 Json::Value encoded;
1871 if (flatten(*fImage.get(), &encoded, SKDEBUGCANVAS_SEND_BINARIES)) {
1872 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1873 if (fSrc.isValid()) {
1874 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = make_json_rect(*fSrc.get());
1875 }
1876 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = make_json_rect(fDst);
1877 if (fPaint.isValid()) {
1878 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaint.get(),
1879 SKDEBUGCANVAS_SEND_BINARIES);
1880 }
1881 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1882 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
1883 }
1884 }
1885 return result;
1886}
1887
1888SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command) {
1889 SkImage* image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE]);
1890 if (image == nullptr) {
1891 return nullptr;
1892 }
1893 SkRect dst;
1894 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
1895 SkPaint* paintPtr;
1896 SkPaint paint;
1897 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
1898 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1899 paintPtr = &paint;
1900 }
1901 else {
1902 paintPtr = nullptr;
1903 }
1904 SkCanvas::SrcRectConstraint constraint;
1905 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
1906 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
1907 constraint = SkCanvas::kStrict_SrcRectConstraint;
1908 }
1909 else {
1910 constraint = SkCanvas::kFast_SrcRectConstraint;
1911 }
1912 SkRect* srcPtr;
1913 SkRect src;
1914 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
1915 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
1916 srcPtr = &src;
1917 }
1918 else {
1919 srcPtr = nullptr;
1920 }
1921 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image, srcPtr, dst, paintPtr,
1922 constraint);
1923 image->unref();
1924 return result;
1925}
1926
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001927SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001928 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001929 fOval = oval;
1930 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001931
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001932 fInfo.push(SkObjectParser::RectToString(oval));
1933 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001934}
1935
fmalita8c89c522014-11-08 16:18:56 -08001936void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001937 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001938}
1939
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001940bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001941 canvas->clear(0xFFFFFFFF);
1942 canvas->save();
1943
1944 xlate_and_scale_to_bounds(canvas, fOval);
1945
1946 SkPaint p;
1947 p.setColor(SK_ColorBLACK);
1948 p.setStyle(SkPaint::kStroke_Style);
1949
1950 canvas->drawOval(fOval, p);
1951 canvas->restore();
1952
1953 return true;
1954}
1955
ethannicholas50a8dd02016-02-10 05:40:46 -08001956Json::Value SkDrawOvalCommand::toJSON() const {
1957 Json::Value result = INHERITED::toJSON();
1958 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fOval);
1959 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
1960 return result;
1961}
1962
1963SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command) {
1964 SkRect coords;
1965 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
1966 SkPaint paint;
1967 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1968 return new SkDrawOvalCommand(coords, paint);
1969}
1970
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001971SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001972 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001973 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00001974
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001975 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00001976}
1977
fmalita8c89c522014-11-08 16:18:56 -08001978void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001979 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001980}
1981
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001982bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001983 canvas->clear(0xFFFFFFFF);
1984 canvas->drawPaint(fPaint);
1985 return true;
1986}
1987
ethannicholas50a8dd02016-02-10 05:40:46 -08001988Json::Value SkDrawPaintCommand::toJSON() const {
1989 Json::Value result = INHERITED::toJSON();
1990 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
1991 return result;
1992}
1993
1994SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command) {
1995 SkPaint paint;
1996 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
1997 return new SkDrawPaintCommand(paint);
1998}
1999
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002000SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002001 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002002 fPath = path;
2003 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002004
robertphillips@google.com91217d02013-03-17 18:33:46 +00002005 fInfo.push(SkObjectParser::PathToString(path));
2006 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002007}
2008
fmalita8c89c522014-11-08 16:18:56 -08002009void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002010 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002011}
2012
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002013bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002014 render_path(canvas, fPath);
2015 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002016}
2017
ethannicholas50a8dd02016-02-10 05:40:46 -08002018Json::Value SkDrawPathCommand::toJSON() const {
2019 Json::Value result = INHERITED::toJSON();
2020 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
2021 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2022 return result;
2023}
2024
2025SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command) {
2026 SkPath path;
2027 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2028 SkPaint paint;
2029 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2030 return new SkDrawPathCommand(path, paint);
2031}
2032
fmalita160ebb22015-04-01 20:58:37 -07002033SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2034 const SkMatrix* matrix,
2035 const SkPaint* paint)
2036 : INHERITED(kBeginDrawPicture_OpType)
2037 , fPicture(SkRef(picture)) {
2038
2039 SkString* str = new SkString;
2040 str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
2041 picture->cullRect().fLeft, picture->cullRect().fTop,
2042 picture->cullRect().fRight, picture->cullRect().fBottom);
2043 fInfo.push(str);
robertphillipsb3f319f2014-08-13 10:46:23 -07002044
bsalomon49f085d2014-09-05 13:34:00 -07002045 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002046 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002047 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2048 }
fmalita160ebb22015-04-01 20:58:37 -07002049
bsalomon49f085d2014-09-05 13:34:00 -07002050 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002051 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002052 fInfo.push(SkObjectParser::PaintToString(*paint));
2053 }
fmalita160ebb22015-04-01 20:58:37 -07002054
2055}
2056
2057void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2058 if (fPaint.isValid()) {
2059 SkRect bounds = fPicture->cullRect();
2060 if (fMatrix.isValid()) {
2061 fMatrix.get()->mapRect(&bounds);
2062 }
2063 canvas->saveLayer(&bounds, fPaint.get());
2064 }
2065
2066 if (fMatrix.isValid()) {
2067 if (!fPaint.isValid()) {
2068 canvas->save();
2069 }
2070 canvas->concat(*fMatrix.get());
2071 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002072}
2073
fmalita160ebb22015-04-01 20:58:37 -07002074bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002075 canvas->clear(0xFFFFFFFF);
2076 canvas->save();
2077
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002078 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002079
robertphillips9b14f262014-06-04 05:40:44 -07002080 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002081
2082 canvas->restore();
2083
2084 return true;
2085}
2086
fmalita160ebb22015-04-01 20:58:37 -07002087SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2088 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2089
2090void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2091 if (fRestore) {
2092 canvas->restore();
2093 }
2094}
2095
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002096SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002097 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002098 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002099 fMode = mode;
2100 fCount = count;
2101 fPts = new SkPoint[count];
2102 memcpy(fPts, pts, count * sizeof(SkPoint));
2103 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002104
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002105 fInfo.push(SkObjectParser::PointsToString(pts, count));
2106 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
2107 "Points: "));
2108 fInfo.push(SkObjectParser::PointModeToString(mode));
2109 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002110}
2111
fmalita8c89c522014-11-08 16:18:56 -08002112void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002113 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002114}
2115
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002116bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002117 canvas->clear(0xFFFFFFFF);
2118 canvas->save();
2119
2120 SkRect bounds;
2121
2122 bounds.setEmpty();
2123 for (unsigned int i = 0; i < fCount; ++i) {
2124 bounds.growToInclude(fPts[i].fX, fPts[i].fY);
2125 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002126
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002127 xlate_and_scale_to_bounds(canvas, bounds);
2128
2129 SkPaint p;
2130 p.setColor(SK_ColorBLACK);
2131 p.setStyle(SkPaint::kStroke_Style);
2132
2133 canvas->drawPoints(fMode, fCount, fPts, p);
2134 canvas->restore();
2135
2136 return true;
2137}
2138
ethannicholas50a8dd02016-02-10 05:40:46 -08002139Json::Value SkDrawPointsCommand::toJSON() const {
2140 Json::Value result = INHERITED::toJSON();
2141 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2142 Json::Value points(Json::arrayValue);
2143 for (size_t i = 0; i < fCount; i++) {
2144 points.append(make_json_point(fPts[i]));
2145 }
2146 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
2147 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2148 return result;
2149}
2150
2151SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command) {
2152 SkCanvas::PointMode mode;
2153 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2154 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2155 mode = SkCanvas::kPoints_PointMode;
2156 }
2157 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2158 mode = SkCanvas::kLines_PointMode;
2159 }
2160 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2161 mode = SkCanvas::kPolygon_PointMode;
2162 }
2163 else {
2164 SkASSERT(false);
2165 return nullptr;
2166 }
2167 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2168 int count = (int) jsonPoints.size();
2169 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2170 for (int i = 0; i < count; i++) {
2171 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2172 }
2173 SkPaint paint;
2174 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2175 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2176 sk_free(points);
2177 return result;
2178}
2179
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002180SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002181 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002182 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002183 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002184
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002185 fText = new char[byteLength];
2186 memcpy(fText, text, byteLength);
2187 fByteLength = byteLength;
2188
2189 fPos = new SkPoint[numPts];
2190 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2191
2192 fPaint = paint;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002193
2194 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
chudy@google.com902ebe52012-06-29 14:21:22 +00002195 // TODO(chudy): Test that this works.
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002196 fInfo.push(SkObjectParser::PointsToString(pos, 1));
2197 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002198}
2199
fmalita8c89c522014-11-08 16:18:56 -08002200void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002201 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002202}
2203
ethannicholas50a8dd02016-02-10 05:40:46 -08002204Json::Value SkDrawPosTextCommand::toJSON() const {
2205 Json::Value result = INHERITED::toJSON();
2206 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2207 ((const char*) fText) + fByteLength);
2208 Json::Value coords(Json::arrayValue);
2209 for (size_t i = 0; i < fByteLength; i++) {
2210 coords.append(make_json_point(fPos[i]));
2211 }
2212 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
2213 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2214 return result;
2215}
2216
2217SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command) {
2218 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2219 SkPaint paint;
2220 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2221 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2222 int count = (int) coords.size();
2223 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2224 for (int i = 0; i < count; i++) {
2225 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2226 }
2227 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2228}
chudy@google.com902ebe52012-06-29 14:21:22 +00002229
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002230SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2231 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002232 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002233 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002234 size_t numPts = paint.countText(text, byteLength);
2235
2236 fText = new char[byteLength];
2237 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002238 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002239
2240 fXpos = new SkScalar[numPts];
2241 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2242
robertphillips@google.com91217d02013-03-17 18:33:46 +00002243 fConstY = constY;
2244 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002245
robertphillips@google.com91217d02013-03-17 18:33:46 +00002246 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2247 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
2248 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
2249 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002250}
2251
fmalita8c89c522014-11-08 16:18:56 -08002252void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002253 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002254}
2255
fmalita0d48e412016-01-04 08:08:04 -08002256static const char* gPositioningLabels[] = {
2257 "kDefault_Positioning",
2258 "kHorizontal_Positioning",
2259 "kFull_Positioning",
2260};
2261
fmalitab7425172014-08-26 07:56:44 -07002262SkDrawTextBlobCommand::SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y,
2263 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002264 : INHERITED(kDrawTextBlob_OpType)
fmalitae77f2da2015-12-08 18:59:18 -08002265 , fBlob(SkRef(blob))
fmalitab7425172014-08-26 07:56:44 -07002266 , fXPos(x)
2267 , fYPos(y)
2268 , fPaint(paint) {
2269
fmalitae77f2da2015-12-08 18:59:18 -08002270 SkAutoTDelete<SkString> runsStr(new SkString);
fmalitab7425172014-08-26 07:56:44 -07002271 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
fmalitaff3106c2014-12-09 05:28:20 -08002272 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
2273 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
fmalitae77f2da2015-12-08 18:59:18 -08002274 fInfo.push(runsStr);
fmalitab7425172014-08-26 07:56:44 -07002275 fInfo.push(SkObjectParser::PaintToString(paint));
fmalitae77f2da2015-12-08 18:59:18 -08002276
2277 unsigned runs = 0;
2278 SkPaint runPaint(paint);
2279 SkTextBlobRunIterator iter(blob);
2280 while (!iter.done()) {
fmalita0d48e412016-01-04 08:08:04 -08002281 SkAutoTDelete<SkString> tmpStr(new SkString);
2282 tmpStr->printf("==== Run [%d] ====", runs++);
2283 fInfo.push(tmpStr.release());
fmalitae77f2da2015-12-08 18:59:18 -08002284
2285 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
fmalita0d48e412016-01-04 08:08:04 -08002286 tmpStr.reset(new SkString("GlyphPositioning: "));
2287 tmpStr->append(gPositioningLabels[iter.positioning()]);
2288 fInfo.push(tmpStr.release());
2289
fmalitae77f2da2015-12-08 18:59:18 -08002290 iter.applyFontToPaint(&runPaint);
2291 fInfo.push(SkObjectParser::PaintToString(runPaint));
2292
2293 iter.next();
2294 }
2295
2296 runsStr->printf("Runs: %d", runs);
2297 // runStr is owned by fInfo at this point.
2298 runsStr.release();
fmalitab7425172014-08-26 07:56:44 -07002299}
2300
fmalita8c89c522014-11-08 16:18:56 -08002301void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07002302 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2303}
2304
fmalita55773872014-08-29 15:08:20 -07002305bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
2306 canvas->clear(SK_ColorWHITE);
2307 canvas->save();
2308
2309 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
2310 xlate_and_scale_to_bounds(canvas, bounds);
2311
2312 canvas->drawTextBlob(fBlob.get(), fXPos, fYPos, fPaint);
2313
2314 canvas->restore();
2315
2316 return true;
2317}
2318
ethannicholas50a8dd02016-02-10 05:40:46 -08002319Json::Value SkDrawTextBlobCommand::toJSON() const {
2320 Json::Value result = INHERITED::toJSON();
2321 Json::Value runs(Json::arrayValue);
2322 SkTextBlobRunIterator iter(fBlob.get());
2323 while (!iter.done()) {
2324 Json::Value run(Json::objectValue);
2325 Json::Value jsonPositions(Json::arrayValue);
2326 Json::Value jsonGlyphs(Json::arrayValue);
2327 const SkScalar* iterPositions = iter.pos();
2328 const uint16_t* iterGlyphs = iter.glyphs();
2329 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
2330 switch (iter.positioning()) {
2331 case SkTextBlob::kFull_Positioning:
2332 jsonPositions.append(make_json_point(iterPositions[i * 2],
2333 iterPositions[i * 2 + 1]));
2334 break;
2335 case SkTextBlob::kHorizontal_Positioning:
2336 jsonPositions.append(Json::Value(iterPositions[i]));
2337 break;
2338 case SkTextBlob::kDefault_Positioning:
2339 break;
2340 }
2341 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
2342 }
2343 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
2344 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
2345 }
2346 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
2347 SkPaint fontPaint;
2348 iter.applyFontToPaint(&fontPaint);
2349 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = make_json_paint(fontPaint, SKDEBUGCANVAS_SEND_BINARIES);
2350 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(iter.offset());
2351 runs.append(run);
2352 iter.next();
2353 }
2354 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
2355 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
2356 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
2357 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2358 return result;
2359}
2360
2361SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command) {
2362 SkTextBlobBuilder builder;
2363 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
2364 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
2365 Json::Value run = runs[i];
2366 SkPaint font;
2367 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
2368 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], &font);
2369 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
2370 int count = glyphs.size();
2371 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2372 SkScalar x = coords[0].asFloat();
2373 SkScalar y = coords[1].asFloat();
2374 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
2375 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2376 if (positions.size() > 0 && positions[0].isNumeric()) {
2377 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y);
2378 for (int j = 0; j < count; j++) {
2379 buffer.glyphs[j] = glyphs[j].asUInt();
2380 buffer.pos[j] = positions[j].asFloat();
2381 }
2382 }
2383 else {
2384 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count);
2385 for (int j = 0; j < count; j++) {
2386 buffer.glyphs[j] = glyphs[j].asUInt();
2387 buffer.pos[j * 2] = positions[j][0].asFloat();
2388 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
2389 }
2390 }
2391 }
2392 else {
2393 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y);
2394 for (int j = 0; j < count; j++) {
2395 buffer.glyphs[j] = glyphs[j].asUInt();
2396 }
2397 }
2398 }
2399 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
2400 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2401 SkPaint paint;
2402 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2403 return new SkDrawTextBlobCommand(builder.build(), x, y, paint);
2404}
2405
robertphillips9bafc302015-02-13 11:13:00 -08002406SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
2407 const SkPoint texCoords[4], SkXfermode* xfermode,
2408 const SkPaint& paint)
2409 : INHERITED(kDrawPatch_OpType) {
2410 memcpy(fCubics, cubics, sizeof(fCubics));
2411 memcpy(fColors, colors, sizeof(fColors));
2412 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
2413 fXfermode.reset(xfermode);
2414 fPaint = paint;
2415
2416 fInfo.push(SkObjectParser::PaintToString(paint));
2417}
2418
2419void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
2420 canvas->drawPatch(fCubics, fColors, fTexCoords, fXfermode, fPaint);
2421}
2422
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002423SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002424 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002425 fRect = rect;
2426 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002427
robertphillips@google.com91217d02013-03-17 18:33:46 +00002428 fInfo.push(SkObjectParser::RectToString(rect));
2429 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002430}
2431
fmalita8c89c522014-11-08 16:18:56 -08002432void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002433 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002434}
2435
ethannicholas50a8dd02016-02-10 05:40:46 -08002436Json::Value SkDrawRectCommand::toJSON() const {
2437 Json::Value result = INHERITED::toJSON();
2438 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rect(fRect);
2439 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2440 return result;
2441}
2442
2443SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command) {
2444 SkRect coords;
2445 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2446 SkPaint paint;
2447 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2448 return new SkDrawRectCommand(coords, paint);
2449}
2450
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002451SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002452 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002453 fRRect = rrect;
2454 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002455
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002456 fInfo.push(SkObjectParser::RRectToString(rrect));
2457 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00002458}
2459
fmalita8c89c522014-11-08 16:18:56 -08002460void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00002461 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002462}
2463
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002464bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002465 render_rrect(canvas, fRRect);
2466 return true;
2467}
2468
ethannicholas50a8dd02016-02-10 05:40:46 -08002469Json::Value SkDrawRRectCommand::toJSON() const {
2470 Json::Value result = INHERITED::toJSON();
2471 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
2472 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2473 return result;
2474}
2475
2476SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command) {
2477 SkRRect coords;
2478 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2479 SkPaint paint;
2480 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2481 return new SkDrawRRectCommand(coords, paint);
2482}
2483
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00002484SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002485 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002486 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002487 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002488 fOuter = outer;
2489 fInner = inner;
2490 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002491
2492 fInfo.push(SkObjectParser::RRectToString(outer));
2493 fInfo.push(SkObjectParser::RRectToString(inner));
2494 fInfo.push(SkObjectParser::PaintToString(paint));
2495}
2496
fmalita8c89c522014-11-08 16:18:56 -08002497void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002498 canvas->drawDRRect(fOuter, fInner, fPaint);
2499}
2500
2501bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
2502 render_drrect(canvas, fOuter, fInner);
2503 return true;
2504}
2505
ethannicholas50a8dd02016-02-10 05:40:46 -08002506Json::Value SkDrawDRRectCommand::toJSON() const {
2507 Json::Value result = INHERITED::toJSON();
2508 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
2509 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
2510 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2511 return result;
2512}
2513
2514SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command) {
2515 SkRRect outer;
2516 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
2517 SkRRect inner;
2518 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
2519 SkPaint paint;
2520 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2521 return new SkDrawDRRectCommand(outer, inner, paint);
2522}
2523
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002524SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002525 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002526 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002527 fText = new char[byteLength];
2528 memcpy(fText, text, byteLength);
2529 fByteLength = byteLength;
2530 fX = x;
2531 fY = y;
2532 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002533
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002534 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2535 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
2536 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
2537 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002538}
2539
fmalita8c89c522014-11-08 16:18:56 -08002540void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002541 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002542}
2543
ethannicholas50a8dd02016-02-10 05:40:46 -08002544Json::Value SkDrawTextCommand::toJSON() const {
2545 Json::Value result = INHERITED::toJSON();
2546 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2547 ((const char*) fText) + fByteLength);
2548 Json::Value coords(Json::arrayValue);
2549 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_point(fX, fY);
2550 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2551 return result;
2552}
2553
2554SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command) {
2555 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2556 SkPaint paint;
2557 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2558 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2559 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
2560 paint);
2561}
2562
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002563SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
2564 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002565 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002566 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002567 fText = new char[byteLength];
2568 memcpy(fText, text, byteLength);
2569 fByteLength = byteLength;
2570 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07002571 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002572 fMatrix = *matrix;
2573 } else {
2574 fMatrix.setIdentity();
2575 }
2576 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002577
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002578 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2579 fInfo.push(SkObjectParser::PathToString(path));
bsalomon49f085d2014-09-05 13:34:00 -07002580 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002581 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2582 }
2583 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002584}
2585
fmalita8c89c522014-11-08 16:18:56 -08002586void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002587 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07002588 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002589 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002590}
2591
ethannicholas50a8dd02016-02-10 05:40:46 -08002592Json::Value SkDrawTextOnPathCommand::toJSON() const {
2593 Json::Value result = INHERITED::toJSON();
2594 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2595 ((const char*) fText) + fByteLength);
2596 Json::Value coords(Json::arrayValue);
2597 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = make_json_path(fPath);
2598 if (!fMatrix.isIdentity()) {
2599 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix);
2600 }
2601 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(fPaint, SKDEBUGCANVAS_SEND_BINARIES);
2602 return result;
2603}
2604
2605SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command) {
2606 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2607 SkPaint paint;
2608 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2609 SkPath path;
2610 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2611 SkMatrix* matrixPtr;
2612 SkMatrix matrix;
2613 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
2614 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
2615 matrixPtr = &matrix;
2616 }
2617 else {
2618 matrixPtr = nullptr;
2619 }
2620 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
2621}
2622
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002623SkDrawVerticesCommand::SkDrawVerticesCommand(SkCanvas::VertexMode vmode, int vertexCount,
2624 const SkPoint vertices[], const SkPoint texs[],
2625 const SkColor colors[], SkXfermode* xfermode,
2626 const uint16_t indices[], int indexCount,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002627 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002628 : INHERITED(kDrawVertices_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002629 fVmode = vmode;
2630
2631 fVertexCount = vertexCount;
2632
2633 fVertices = new SkPoint[vertexCount];
2634 memcpy(fVertices, vertices, vertexCount * sizeof(SkPoint));
2635
bsalomon49f085d2014-09-05 13:34:00 -07002636 if (texs) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002637 fTexs = new SkPoint[vertexCount];
2638 memcpy(fTexs, texs, vertexCount * sizeof(SkPoint));
2639 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002640 fTexs = nullptr;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002641 }
2642
bsalomon49f085d2014-09-05 13:34:00 -07002643 if (colors) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002644 fColors = new SkColor[vertexCount];
2645 memcpy(fColors, colors, vertexCount * sizeof(SkColor));
2646 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002647 fColors = nullptr;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002648 }
2649
2650 fXfermode = xfermode;
bsalomon49f085d2014-09-05 13:34:00 -07002651 if (fXfermode) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002652 fXfermode->ref();
2653 }
2654
2655 if (indexCount > 0) {
2656 fIndices = new uint16_t[indexCount];
2657 memcpy(fIndices, indices, indexCount * sizeof(uint16_t));
2658 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002659 fIndices = nullptr;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002660 }
2661
2662 fIndexCount = indexCount;
2663 fPaint = paint;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002664
chudy@google.com902ebe52012-06-29 14:21:22 +00002665 // TODO(chudy)
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002666 fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
2667 fInfo.push(SkObjectParser::PaintToString(paint));
2668}
2669
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002670SkDrawVerticesCommand::~SkDrawVerticesCommand() {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002671 delete [] fVertices;
2672 delete [] fTexs;
2673 delete [] fColors;
2674 SkSafeUnref(fXfermode);
2675 delete [] fIndices;
chudy@google.com902ebe52012-06-29 14:21:22 +00002676}
2677
fmalita8c89c522014-11-08 16:18:56 -08002678void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002679 canvas->drawVertices(fVmode, fVertexCount, fVertices,
2680 fTexs, fColors, fXfermode, fIndices,
2681 fIndexCount, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002682}
2683
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002684SkRestoreCommand::SkRestoreCommand()
robertphillips9bafc302015-02-13 11:13:00 -08002685 : INHERITED(kRestore_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002686 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
chudy@google.com902ebe52012-06-29 14:21:22 +00002687}
2688
fmalita8c89c522014-11-08 16:18:56 -08002689void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00002690 canvas->restore();
2691}
2692
ethannicholas50a8dd02016-02-10 05:40:46 -08002693SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command) {
2694 return new SkRestoreCommand();
2695}
2696
Florin Malita5f6102d2014-06-30 10:13:28 -04002697SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08002698 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00002699}
2700
fmalita8c89c522014-11-08 16:18:56 -08002701void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04002702 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00002703}
2704
ethannicholas50a8dd02016-02-10 05:40:46 -08002705SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command) {
2706 return new SkSaveCommand();
2707}
2708
reed4960eee2015-12-18 07:09:18 -08002709SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08002710 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08002711 if (rec.fBounds) {
2712 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002713 } else {
2714 fBounds.setEmpty();
2715 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002716
reed4960eee2015-12-18 07:09:18 -08002717 if (rec.fPaint) {
2718 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002719 fPaintPtr = &fPaint;
2720 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002721 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002722 }
reed4960eee2015-12-18 07:09:18 -08002723 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002724
ethannicholas50a8dd02016-02-10 05:40:46 -08002725 if (rec.fBackdrop) {
2726 fBackdrop = rec.fBackdrop;
2727 fBackdrop->ref();
2728 } else {
2729 fBackdrop = nullptr;
2730 }
2731
reed4960eee2015-12-18 07:09:18 -08002732 if (rec.fBounds) {
2733 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002734 }
reed4960eee2015-12-18 07:09:18 -08002735 if (rec.fPaint) {
2736 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002737 }
reed4960eee2015-12-18 07:09:18 -08002738 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00002739}
2740
ethannicholas50a8dd02016-02-10 05:40:46 -08002741SkSaveLayerCommand::~SkSaveLayerCommand() {
2742 if (fBackdrop != nullptr) {
2743 fBackdrop->unref();
2744 }
2745}
2746
fmalita8c89c522014-11-08 16:18:56 -08002747void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08002748 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
2749 fPaintPtr,
2750 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00002751}
2752
fmalita8c89c522014-11-08 16:18:56 -08002753void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
commit-bot@chromium.org1643b2c2014-03-03 23:25:41 +00002754 canvas->save();
2755}
2756
ethannicholas50a8dd02016-02-10 05:40:46 -08002757Json::Value SkSaveLayerCommand::toJSON() const {
2758 Json::Value result = INHERITED::toJSON();
2759 if (!fBounds.isEmpty()) {
2760 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = make_json_rect(fBounds);
2761 }
2762 if (fPaintPtr != nullptr) {
2763 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = make_json_paint(*fPaintPtr,
2764 SKDEBUGCANVAS_SEND_BINARIES);
2765 }
2766 if (fBackdrop != nullptr) {
2767 Json::Value jsonBackdrop;
2768 flatten(fBackdrop, &jsonBackdrop, SKDEBUGCANVAS_SEND_BINARIES);
2769 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
2770 }
2771 if (fSaveLayerFlags != 0) {
2772 SkDebugf("unsupported: saveLayer flags\n");
2773 SkASSERT(false);
2774 }
2775 return result;
2776}
2777
2778SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command) {
2779 SkCanvas::SaveLayerRec rec;
2780 SkRect bounds;
2781 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
2782 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
2783 rec.fBounds = &bounds;
2784 }
2785 SkPaint paint;
2786 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2787 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], &paint);
2788 rec.fPaint = &paint;
2789 }
2790 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
2791 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
2792 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop);
2793 }
2794 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
2795 if (rec.fBackdrop != nullptr) {
2796 rec.fBackdrop->unref();
2797 }
2798 return result;
2799}
2800
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002801SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08002802 : INHERITED(kSetMatrix_OpType) {
robertphillips70171682014-10-16 14:28:28 -07002803 fUserMatrix.reset();
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002804 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00002805
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002806 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00002807}
2808
robertphillips70171682014-10-16 14:28:28 -07002809void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
2810 fUserMatrix = userMatrix;
2811}
2812
fmalita8c89c522014-11-08 16:18:56 -08002813void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
robertphillips70171682014-10-16 14:28:28 -07002814 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
2815 canvas->setMatrix(temp);
chudy@google.com902ebe52012-06-29 14:21:22 +00002816}
2817
ethannicholas50a8dd02016-02-10 05:40:46 -08002818Json::Value SkSetMatrixCommand::toJSON() const {
2819 Json::Value result = INHERITED::toJSON();
2820 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = make_json_matrix(fMatrix);
2821 return result;
2822}
2823
2824SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command) {
2825 SkMatrix matrix;
2826 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
2827 return new SkSetMatrixCommand(matrix);
2828}