blob: 8f6f66a30418ee3e63b5dfa029d081e2e64a3679 [file] [log] [blame]
chudy@google.com902ebe52012-06-29 14:21:22 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
chudy@google.com902ebe52012-06-29 14:21:22 +00008#include "SkDrawCommand.h"
joshualitt6b3cf732016-02-17 11:20:26 -08009
halcanarya73d76a2016-10-17 13:19:02 -070010#include "png.h"
11
Hal Canary95e3c052017-01-11 12:44:43 -050012#include "SkAutoMalloc.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080013#include "SkBlurMaskFilter.h"
14#include "SkColorFilter.h"
15#include "SkDashPathEffect.h"
16#include "SkImageFilter.h"
brianosmanfad98562016-05-04 11:06:28 -070017#include "SkJsonWriteBuffer.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080018#include "SkMaskFilter.h"
chudy@google.com902ebe52012-06-29 14:21:22 +000019#include "SkObjectParser.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080020#include "SkPaintDefaults.h"
21#include "SkPathEffect.h"
robertphillips9bafc302015-02-13 11:13:00 -080022#include "SkPicture.h"
fmalitab7425172014-08-26 07:56:44 -070023#include "SkTextBlob.h"
fmalitae77f2da2015-12-08 18:59:18 -080024#include "SkTextBlobRunIterator.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080025#include "SkTHash.h"
26#include "SkTypeface.h"
27#include "SkValidatingReadBuffer.h"
28#include "SkWriteBuffer.h"
msaretta5cf4f42016-06-30 10:06:51 -070029#include "picture_utils.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050030#include "SkClipOpPriv.h"
Stan Ilievac42aeb2017-01-12 16:20:50 -050031#include <SkLatticeIter.h>
ethannicholas50a8dd02016-02-10 05:40:46 -080032
ethannicholas50a8dd02016-02-10 05:40:46 -080033#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
ethannicholas807dcab2016-02-23 06:53:37 -080034#define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
ethannicholas50a8dd02016-02-10 05:40:46 -080035#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
vjiaoblacke5de1302016-07-13 14:05:28 -070036#define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
ethannicholas50a8dd02016-02-10 05:40:46 -080037#define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
halcanaryf412f092016-08-25 11:10:41 -070038#define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
ethannicholas50a8dd02016-02-10 05:40:46 -080039#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
40#define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
41#define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
42#define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
43#define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
44#define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
45#define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
46#define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
47#define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
48#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Florin Malita82d80872017-06-06 16:58:40 -040049#define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
ethannicholas50a8dd02016-02-10 05:40:46 -080050#define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
51#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
52#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
ethannicholas1446a9a2016-02-10 14:05:02 -080053#define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
ethannicholas50a8dd02016-02-10 05:40:46 -080054#define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
55#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
ethannicholas1446a9a2016-02-10 14:05:02 -080056#define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
ethannicholas50a8dd02016-02-10 05:40:46 -080057#define SKDEBUGCANVAS_ATTRIBUTE_REGION "region"
58#define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
59#define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
60#define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
61#define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur"
62#define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
63#define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
64#define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign"
65#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
66#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
67#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
68#define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
69#define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
70#define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
71#define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
72#define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
73#define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
ethannicholasf62a8b72016-02-11 10:35:21 -080074#define SKDEBUGCANVAS_ATTRIBUTE_DATA "data"
brianosmanfad98562016-05-04 11:06:28 -070075#define SKDEBUGCANVAS_ATTRIBUTE_VALUES "values"
ethannicholas50a8dd02016-02-10 05:40:46 -080076#define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
77#define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
78#define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
79#define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
ethannicholas1446a9a2016-02-10 14:05:02 -080080#define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
ethannicholas50a8dd02016-02-10 05:40:46 -080081#define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
82#define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
83#define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
84#define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
85#define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
86#define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
87#define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
88#define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
89#define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
90#define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
91#define SKDEBUGCANVAS_ATTRIBUTE_X "x"
92#define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
93#define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
94#define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
95#define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
96#define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
97#define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
ethannicholas1446a9a2016-02-10 14:05:02 -080098#define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
99#define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors"
100#define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
101#define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
bsalomonac3aa242016-08-19 11:25:19 -0700102#define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
103#define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
104#define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
jcgregorioee0c5552016-06-30 09:18:27 -0700105#define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
msarett0ac1bec2016-08-29 09:15:33 -0700106#define SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
107#define SKDEBUGCANVAS_ATTRIBUTE_WIDTH "width"
108#define SKDEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
109#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Stan Ilievac42aeb2017-01-12 16:20:50 -0500110#define SKDEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
111#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
112#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
113#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
114#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
115#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
reed67f62fa2016-06-29 11:36:34 -0700116
ethannicholas50a8dd02016-02-10 05:40:46 -0800117#define SKDEBUGCANVAS_VERB_MOVE "move"
118#define SKDEBUGCANVAS_VERB_LINE "line"
119#define SKDEBUGCANVAS_VERB_QUAD "quad"
120#define SKDEBUGCANVAS_VERB_CUBIC "cubic"
121#define SKDEBUGCANVAS_VERB_CONIC "conic"
122#define SKDEBUGCANVAS_VERB_CLOSE "close"
123
124#define SKDEBUGCANVAS_STYLE_FILL "fill"
125#define SKDEBUGCANVAS_STYLE_STROKE "stroke"
126#define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
127
128#define SKDEBUGCANVAS_POINTMODE_POINTS "points"
129#define SKDEBUGCANVAS_POINTMODE_LINES "lines"
130#define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
131
132#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
133#define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
134#define SKDEBUGCANVAS_REGIONOP_UNION "union"
135#define SKDEBUGCANVAS_REGIONOP_XOR "xor"
136#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
137#define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
138
139#define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
140#define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
141#define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
142#define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
143
144#define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
145#define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
146
147#define SKDEBUGCANVAS_ALIGN_LEFT "left"
148#define SKDEBUGCANVAS_ALIGN_CENTER "center"
149#define SKDEBUGCANVAS_ALIGN_RIGHT "right"
150
151#define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
152#define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
153#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
154#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
155
156#define SKDEBUGCANVAS_CAP_BUTT "butt"
157#define SKDEBUGCANVAS_CAP_ROUND "round"
158#define SKDEBUGCANVAS_CAP_SQUARE "square"
159
ethannicholas1446a9a2016-02-10 14:05:02 -0800160#define SKDEBUGCANVAS_MITER_JOIN "miter"
161#define SKDEBUGCANVAS_ROUND_JOIN "round"
162#define SKDEBUGCANVAS_BEVEL_JOIN "bevel"
163
ethannicholas50a8dd02016-02-10 05:40:46 -0800164#define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
165#define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
166#define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
167#define SKDEBUGCANVAS_COLORTYPE_565 "565"
168#define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
169#define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
170#define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
171
172#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
173#define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
174#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
msarett0ac1bec2016-08-29 09:15:33 -0700175#define SKDEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
ethannicholas50a8dd02016-02-10 05:40:46 -0800176
ethannicholas1446a9a2016-02-10 14:05:02 -0800177#define SKDEBUGCANVAS_FILTERQUALITY_NONE "none"
178#define SKDEBUGCANVAS_FILTERQUALITY_LOW "low"
179#define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
180#define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high"
181
halcanaryf412f092016-08-25 11:10:41 -0700182#define SKDEBUGCANVAS_HINTING_NONE "none"
183#define SKDEBUGCANVAS_HINTING_SLIGHT "slight"
184#define SKDEBUGCANVAS_HINTING_NORMAL "normal"
185#define SKDEBUGCANVAS_HINTING_FULL "full"
186
ethannicholasf62a8b72016-02-11 10:35:21 -0800187typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&);
fmalitab7425172014-08-26 07:56:44 -0700188
reed67f62fa2016-06-29 11:36:34 -0700189static SkString* str_append(SkString* str, const SkRect& r) {
190 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
191 return str;
192}
193
chudy@google.com902ebe52012-06-29 14:21:22 +0000194// TODO(chudy): Refactor into non subclass model.
195
robertphillips9bafc302015-02-13 11:13:00 -0800196SkDrawCommand::SkDrawCommand(OpType type)
197 : fOpType(type)
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000198 , fVisible(true) {
199}
200
chudy@google.com902ebe52012-06-29 14:21:22 +0000201SkDrawCommand::~SkDrawCommand() {
chudy@google.com97cee972012-08-07 20:41:37 +0000202 fInfo.deleteAll();
chudy@google.com902ebe52012-06-29 14:21:22 +0000203}
204
robertphillips9bafc302015-02-13 11:13:00 -0800205const char* SkDrawCommand::GetCommandString(OpType type) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000206 switch (type) {
fmalita160ebb22015-04-01 20:58:37 -0700207 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800208 case kClipPath_OpType: return "ClipPath";
209 case kClipRegion_OpType: return "ClipRegion";
210 case kClipRect_OpType: return "ClipRect";
211 case kClipRRect_OpType: return "ClipRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800212 case kConcat_OpType: return "Concat";
robertphillipsfb409232016-06-29 10:28:11 -0700213 case kDrawAnnotation_OpType: return "DrawAnnotation";
robertphillips9bafc302015-02-13 11:13:00 -0800214 case kDrawBitmap_OpType: return "DrawBitmap";
215 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
216 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
217 case kDrawClear_OpType: return "DrawClear";
218 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700219 case kDrawImage_OpType: return "DrawImage";
Stan Ilievac42aeb2017-01-12 16:20:50 -0500220 case kDrawImageLattice_OpType: return "DrawImageLattice";
fmalita651c9202015-07-22 10:23:01 -0700221 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800222 case kDrawOval_OpType: return "DrawOval";
223 case kDrawPaint_OpType: return "DrawPaint";
224 case kDrawPatch_OpType: return "DrawPatch";
225 case kDrawPath_OpType: return "DrawPath";
robertphillips9bafc302015-02-13 11:13:00 -0800226 case kDrawPoints_OpType: return "DrawPoints";
227 case kDrawPosText_OpType: return "DrawPosText";
228 case kDrawPosTextH_OpType: return "DrawPosTextH";
229 case kDrawRect_OpType: return "DrawRect";
230 case kDrawRRect_OpType: return "DrawRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800231 case kDrawText_OpType: return "DrawText";
232 case kDrawTextBlob_OpType: return "DrawTextBlob";
233 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
reed63f30d92016-07-07 16:32:51 -0700234 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
robertphillips9bafc302015-02-13 11:13:00 -0800235 case kDrawVertices_OpType: return "DrawVertices";
fmalita160ebb22015-04-01 20:58:37 -0700236 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800237 case kRestore_OpType: return "Restore";
238 case kSave_OpType: return "Save";
239 case kSaveLayer_OpType: return "SaveLayer";
240 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000241 default:
robertphillips9bafc302015-02-13 11:13:00 -0800242 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000243 SkASSERT(0);
244 break;
245 }
246 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700247 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000248}
249
fmalita8c89c522014-11-08 16:18:56 -0800250SkString SkDrawCommand::toString() const {
robertphillips9bafc302015-02-13 11:13:00 -0800251 return SkString(GetCommandString(fOpType));
chudy@google.com902ebe52012-06-29 14:21:22 +0000252}
253
ethannicholasf62a8b72016-02-11 10:35:21 -0800254Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800255 Json::Value result;
256 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800257 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800258 return result;
259}
260
261#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
262 (FROM_JSON) Sk ## name ## Command::fromJSON)
ethannicholasf62a8b72016-02-11 10:35:21 -0800263SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800264 static SkTHashMap<SkString, FROM_JSON> factories;
265 static bool initialized = false;
266 if (!initialized) {
267 initialized = true;
268 INSTALL_FACTORY(Restore);
269 INSTALL_FACTORY(ClipPath);
270 INSTALL_FACTORY(ClipRegion);
271 INSTALL_FACTORY(ClipRect);
272 INSTALL_FACTORY(ClipRRect);
273 INSTALL_FACTORY(Concat);
reed97660cc2016-06-28 18:54:19 -0700274 INSTALL_FACTORY(DrawAnnotation);
ethannicholas50a8dd02016-02-10 05:40:46 -0800275 INSTALL_FACTORY(DrawBitmap);
276 INSTALL_FACTORY(DrawBitmapRect);
277 INSTALL_FACTORY(DrawBitmapNine);
278 INSTALL_FACTORY(DrawImage);
279 INSTALL_FACTORY(DrawImageRect);
280 INSTALL_FACTORY(DrawOval);
281 INSTALL_FACTORY(DrawPaint);
282 INSTALL_FACTORY(DrawPath);
283 INSTALL_FACTORY(DrawPoints);
284 INSTALL_FACTORY(DrawText);
285 INSTALL_FACTORY(DrawPosText);
bungeman51190df2016-03-09 07:42:54 -0800286 INSTALL_FACTORY(DrawPosTextH);
ethannicholas50a8dd02016-02-10 05:40:46 -0800287 INSTALL_FACTORY(DrawTextOnPath);
reed45561a02016-07-07 12:47:17 -0700288 INSTALL_FACTORY(DrawTextRSXform);
ethannicholas50a8dd02016-02-10 05:40:46 -0800289 INSTALL_FACTORY(DrawTextBlob);
290
291 INSTALL_FACTORY(DrawRect);
292 INSTALL_FACTORY(DrawRRect);
293 INSTALL_FACTORY(DrawDRRect);
ethannicholas1446a9a2016-02-10 14:05:02 -0800294 INSTALL_FACTORY(DrawPatch);
ethannicholas50a8dd02016-02-10 05:40:46 -0800295 INSTALL_FACTORY(Save);
296 INSTALL_FACTORY(SaveLayer);
297 INSTALL_FACTORY(SetMatrix);
298 }
299 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
300 FROM_JSON* factory = factories.find(name);
301 if (factory == nullptr) {
302 SkDebugf("no JSON factory for '%s'\n", name.c_str());
303 return nullptr;
304 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800305 return (*factory)(command, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800306}
307
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000308namespace {
309
310void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500311 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000312
313 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
314
315 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
316 if (bounds.width() > bounds.height()) {
317 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
318 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
319 } else {
320 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
321 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
322 }
323 canvas->translate(-bounds.centerX(), -bounds.centerY());
324}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000325
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000326
327void render_path(SkCanvas* canvas, const SkPath& path) {
328 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000329
330 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700331 if (bounds.isEmpty()) {
332 return;
333 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000334
fmalitab0cd8b72015-10-06 07:24:03 -0700335 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000336 xlate_and_scale_to_bounds(canvas, bounds);
337
338 SkPaint p;
339 p.setColor(SK_ColorBLACK);
340 p.setStyle(SkPaint::kStroke_Style);
341
342 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000343}
344
halcanary96fcdcc2015-08-27 07:41:13 -0700345void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500346 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000347
348 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
349 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
350
351 if (input.width() > input.height()) {
352 yScale *= input.height() / (float) input.width();
353 } else {
354 xScale *= input.width() / (float) input.height();
355 }
356
357 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
358 xScale * input.width(),
359 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000360
robertphillips96a5cff2015-09-24 06:56:27 -0700361 static const int kNumBlocks = 8;
362
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000363 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700364 SkISize block = {
365 canvas->imageInfo().width()/kNumBlocks,
366 canvas->imageInfo().height()/kNumBlocks
367 };
368 for (int y = 0; y < kNumBlocks; ++y) {
369 for (int x = 0; x < kNumBlocks; ++x) {
370 SkPaint paint;
371 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
372 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
373 SkIntToScalar(y*block.height()),
374 SkIntToScalar(block.width()),
375 SkIntToScalar(block.height()));
376 canvas->drawRect(r, paint);
377 }
378 }
379
reede47829b2015-08-06 10:02:53 -0700380 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000381
bsalomon49f085d2014-09-05 13:34:00 -0700382 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000383 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
384 srcRect->fTop * yScale + SK_Scalar1,
385 srcRect->fRight * xScale + SK_Scalar1,
386 srcRect->fBottom * yScale + SK_Scalar1);
387 SkPaint p;
388 p.setColor(SK_ColorRED);
389 p.setStyle(SkPaint::kStroke_Style);
390
391 canvas->drawRect(r, p);
392 }
393}
394
395void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
396 canvas->clear(0xFFFFFFFF);
397 canvas->save();
398
399 const SkRect& bounds = rrect.getBounds();
400
401 xlate_and_scale_to_bounds(canvas, bounds);
402
403 SkPaint p;
404 p.setColor(SK_ColorBLACK);
405 p.setStyle(SkPaint::kStroke_Style);
406
407 canvas->drawRRect(rrect, p);
408 canvas->restore();
409}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000410
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000411void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
412 canvas->clear(0xFFFFFFFF);
413 canvas->save();
414
415 const SkRect& bounds = outer.getBounds();
416
417 xlate_and_scale_to_bounds(canvas, bounds);
418
419 SkPaint p;
420 p.setColor(SK_ColorBLACK);
421 p.setStyle(SkPaint::kStroke_Style);
422
423 canvas->drawDRRect(outer, inner, p);
424 canvas->restore();
425}
426
Florin Malita82d80872017-06-06 16:58:40 -0400427static const char* const gBlendModeMap[] = {
428 "clear",
429 "src",
430 "dst",
431 "srcOver",
432 "dstOver",
433 "srcIn",
434 "dstIn",
435 "srcOut",
436 "dstOut",
437 "srcATop",
438 "dstATop",
439 "xor",
440 "plus",
441 "modulate",
442
443 "screen",
444
445 "overlay",
446 "darken",
447 "lighten",
448 "colorDodge",
449 "colorBurn",
450 "hardLight",
451 "softLight",
452 "difference",
453 "exclusion",
454 "multiply",
455
456 "hue",
457 "saturation",
458 "color",
459 "luminosity",
460};
461
462static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
463 "blendMode mismatch");
464static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
465 "blendMode mismatch");
466
467void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
468 const auto mode = paint.getBlendMode();
469 if (mode != SkBlendMode::kSrcOver) {
470 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
471 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
472 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
473 }
474}
475
476void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
477 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
478 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
479
480 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
481 if (!strcmp(mode, gBlendModeMap[i])) {
482 target->setBlendMode(static_cast<SkBlendMode>(i));
483 break;
484 }
485 }
486 }
487}
488
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000489};
490
brianosmanfad98562016-05-04 11:06:28 -0700491Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800492 Json::Value result(Json::arrayValue);
493 result.append(Json::Value(SkColorGetA(color)));
494 result.append(Json::Value(SkColorGetR(color)));
495 result.append(Json::Value(SkColorGetG(color)));
496 result.append(Json::Value(SkColorGetB(color)));
497 return result;
498}
499
brianosman97bbf822016-09-25 13:15:58 -0700500Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
501 Json::Value result(Json::arrayValue);
502 result.append(Json::Value(color.fA));
503 result.append(Json::Value(color.fR));
504 result.append(Json::Value(color.fG));
505 result.append(Json::Value(color.fB));
506 return result;
507}
508
brianosmanfad98562016-05-04 11:06:28 -0700509Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800510 Json::Value result(Json::arrayValue);
511 result.append(Json::Value(point.x()));
512 result.append(Json::Value(point.y()));
513 return result;
514}
515
brianosmanfad98562016-05-04 11:06:28 -0700516Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800517 Json::Value result(Json::arrayValue);
518 result.append(Json::Value(x));
519 result.append(Json::Value(y));
520 return result;
521}
522
brianosmanfad98562016-05-04 11:06:28 -0700523Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800524 Json::Value result(Json::arrayValue);
525 result.append(Json::Value(rect.left()));
526 result.append(Json::Value(rect.top()));
527 result.append(Json::Value(rect.right()));
528 result.append(Json::Value(rect.bottom()));
529 return result;
530}
531
joshualittbd724132016-03-03 11:39:38 -0800532Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800533 Json::Value result(Json::arrayValue);
534 result.append(Json::Value(rect.left()));
535 result.append(Json::Value(rect.top()));
536 result.append(Json::Value(rect.right()));
537 result.append(Json::Value(rect.bottom()));
538 return result;
539}
540
541static Json::Value make_json_rrect(const SkRRect& rrect) {
542 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700543 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
544 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
545 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
546 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
547 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800548 return result;
549}
550
joshualittbd724132016-03-03 11:39:38 -0800551Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800552 Json::Value result(Json::arrayValue);
553 Json::Value row1(Json::arrayValue);
554 row1.append(Json::Value(matrix[0]));
555 row1.append(Json::Value(matrix[1]));
556 row1.append(Json::Value(matrix[2]));
557 result.append(row1);
558 Json::Value row2(Json::arrayValue);
559 row2.append(Json::Value(matrix[3]));
560 row2.append(Json::Value(matrix[4]));
561 row2.append(Json::Value(matrix[5]));
562 result.append(row2);
563 Json::Value row3(Json::arrayValue);
564 row3.append(Json::Value(matrix[6]));
565 row3.append(Json::Value(matrix[7]));
566 row3.append(Json::Value(matrix[8]));
567 result.append(row3);
568 return result;
569}
ethannicholas1446a9a2016-02-10 14:05:02 -0800570
vjiaoblacke5de1302016-07-13 14:05:28 -0700571Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
572 Json::Value result(z);
573 return result;
574}
575
brianosmanfad98562016-05-04 11:06:28 -0700576Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800577 Json::Value result(Json::objectValue);
578 switch (path.getFillType()) {
579 case SkPath::kWinding_FillType:
580 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
581 break;
582 case SkPath::kEvenOdd_FillType:
583 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
584 break;
585 case SkPath::kInverseWinding_FillType:
586 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
587 break;
588 case SkPath::kInverseEvenOdd_FillType:
589 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
590 break;
halcanary9d524f22016-03-29 09:03:52 -0700591 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800592 Json::Value verbs(Json::arrayValue);
593 SkPath::Iter iter(path, false);
594 SkPoint pts[4];
595 SkPath::Verb verb;
596 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
597 switch (verb) {
598 case SkPath::kLine_Verb: {
599 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700600 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800601 verbs.append(line);
602 break;
603 }
604 case SkPath::kQuad_Verb: {
605 Json::Value quad(Json::objectValue);
606 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700607 coords.append(MakeJsonPoint(pts[1]));
608 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800609 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
610 verbs.append(quad);
611 break;
612 }
613 case SkPath::kCubic_Verb: {
614 Json::Value cubic(Json::objectValue);
615 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700616 coords.append(MakeJsonPoint(pts[1]));
617 coords.append(MakeJsonPoint(pts[2]));
618 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800619 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
620 verbs.append(cubic);
621 break;
622 }
623 case SkPath::kConic_Verb: {
624 Json::Value conic(Json::objectValue);
625 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700626 coords.append(MakeJsonPoint(pts[1]));
627 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800628 coords.append(Json::Value(iter.conicWeight()));
629 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
630 verbs.append(conic);
631 break;
632 }
633 case SkPath::kMove_Verb: {
634 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700635 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800636 verbs.append(move);
637 break;
638 }
639 case SkPath::kClose_Verb:
640 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
641 break;
642 case SkPath::kDone_Verb:
643 break;
644 }
645 }
646 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
647 return result;
648}
649
brianosmanfad98562016-05-04 11:06:28 -0700650Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800651 return Json::Value("<unimplemented>");
652}
653
Mike Reedc1f77742016-12-09 09:00:50 -0500654static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800655 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500656 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800657 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500658 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800659 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500660 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800661 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500662 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800663 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500664 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800665 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500666 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800667 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
668 default:
669 SkASSERT(false);
670 return Json::Value("<invalid region op>");
671 };
672}
673
674static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
675 switch (mode) {
676 case SkCanvas::kPoints_PointMode:
677 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
678 case SkCanvas::kLines_PointMode:
679 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700680 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800681 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
682 default:
683 SkASSERT(false);
684 return Json::Value("<invalid point mode>");
685 };
686}
687
halcanary9d524f22016-03-29 09:03:52 -0700688static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800689 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800690 if (value != defaultValue) {
691 (*target)[key] = Json::Value(value);
692 }
693}
694
ethannicholasbd3dae82016-02-10 12:10:00 -0800695static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800696 if (value != defaultValue) {
697 (*target)[key] = Json::Value(value);
698 }
699}
700
halcanary9d524f22016-03-29 09:03:52 -0700701static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800702 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700703 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
704 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800705 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800706}
707
brianosmanfad98562016-05-04 11:06:28 -0700708void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
709 UrlDataManager& urlDataManager) {
710 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800711 flattenable->flatten(buffer);
712 void* data = sk_malloc_throw(buffer.bytesWritten());
713 buffer.writeToMemory(data);
714 Json::Value jsonData;
715 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
716 Json::Value jsonFlattenable;
717 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
718 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700719
720 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
721 flattenable->flatten(jsonBuffer);
722 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
723
ethannicholasf62a8b72016-02-11 10:35:21 -0800724 (*target) = jsonFlattenable;
725 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800726}
727
ethannicholasf67531f2016-03-21 10:19:39 -0700728static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
729 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
730 out->write(data, length);
731}
732
halcanarya73d76a2016-10-17 13:19:02 -0700733void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700734 SkWStream& out, bool isOpaque) {
ethannicholasf67531f2016-03-21 10:19:39 -0700735 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
736 SkASSERT(png != nullptr);
737 png_infop info_ptr = png_create_info_struct(png);
738 SkASSERT(info_ptr != nullptr);
739 if (setjmp(png_jmpbuf(png))) {
740 SkFAIL("png encode error");
741 }
msaretta5cf4f42016-06-30 10:06:51 -0700742 png_set_write_fn(png, &out, write_png_callback, NULL);
743 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
744 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700745 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
746 png_set_compression_level(png, 1);
747 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700748 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700749 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700750 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700751 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700752 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700753 rows[y][x * 4] = src[x * 4];
754 rows[y][x * 4 + 1] = src[x * 4 + 1];
755 rows[y][x * 4 + 2] = src[x * 4 + 2];
756 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700757 }
758 }
msaretta5cf4f42016-06-30 10:06:51 -0700759 png_write_info(png, info_ptr);
760 if (isOpaque) {
761 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
762 }
ethannicholasf67531f2016-03-21 10:19:39 -0700763 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700764 png_write_image(png, &rows[0]);
ethannicholasf67531f2016-03-21 10:19:39 -0700765 png_destroy_write_struct(&png, NULL);
766 sk_free(rows);
767 sk_free(pixels);
768}
769
brianosmanfad98562016-05-04 11:06:28 -0700770bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
771 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700772 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500773 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700774 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700775 kN32_SkColorType, kPremul_SkAlphaType);
776 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
777 SkDebugf("readPixels failed\n");
778 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800779 }
msaretta5cf4f42016-06-30 10:06:51 -0700780
781 SkBitmap bm;
782 bm.installPixels(dstInfo, buffer.get(), rowBytes);
783 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
784
ethannicholasf67531f2016-03-21 10:19:39 -0700785 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700786 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700787 out, false);
reed42943c82016-09-12 12:01:44 -0700788 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800789 Json::Value jsonData;
790 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
791 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800792 return true;
793}
794
795static const char* color_type_name(SkColorType colorType) {
796 switch (colorType) {
797 case kARGB_4444_SkColorType:
798 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
799 case kRGBA_8888_SkColorType:
800 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
801 case kBGRA_8888_SkColorType:
802 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
803 case kRGB_565_SkColorType:
804 return SKDEBUGCANVAS_COLORTYPE_565;
805 case kGray_8_SkColorType:
806 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
807 case kIndex_8_SkColorType:
808 return SKDEBUGCANVAS_COLORTYPE_INDEX8;
809 case kAlpha_8_SkColorType:
810 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
811 default:
812 SkASSERT(false);
813 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
814 }
815}
816
817static const char* alpha_type_name(SkAlphaType alphaType) {
818 switch (alphaType) {
819 case kOpaque_SkAlphaType:
820 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
821 case kPremul_SkAlphaType:
822 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
823 case kUnpremul_SkAlphaType:
824 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
825 default:
826 SkASSERT(false);
827 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
828 }
829}
830
halcanary9d524f22016-03-29 09:03:52 -0700831static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -0800832 const void** target) {
833 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
834 if (urlData == nullptr) {
835 SkASSERT(false);
836 *target = nullptr;
837 return 0;
ethannicholas50a8dd02016-02-10 05:40:46 -0800838 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800839 *target = urlData->fData->data();
840 // cast should be safe for any reasonably-sized object...
841 return (Json::ArrayIndex) urlData->fData->size();
ethannicholas50a8dd02016-02-10 05:40:46 -0800842}
843
halcanary9d524f22016-03-29 09:03:52 -0700844static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
ethannicholasf62a8b72016-02-11 10:35:21 -0800845 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800846 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
847 return nullptr;
848 }
849 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
850 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
851 if (factory == nullptr) {
852 SkDebugf("no factory for loading '%s'\n", name);
853 return nullptr;
854 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800855 const void* data;
856 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800857 SkValidatingReadBuffer buffer(data, size);
reed60c9b582016-04-03 09:11:13 -0700858 sk_sp<SkFlattenable> result = factory(buffer);
ethannicholas50a8dd02016-02-10 05:40:46 -0800859 if (!buffer.isValid()) {
860 SkDebugf("invalid buffer loading flattenable\n");
861 return nullptr;
862 }
reed60c9b582016-04-03 09:11:13 -0700863 return result.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800864}
865
866static SkColorType colortype_from_name(const char* name) {
867 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
868 return kARGB_4444_SkColorType;
869 }
870 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
871 return kRGBA_8888_SkColorType;
872 }
873 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
874 return kBGRA_8888_SkColorType;
875 }
876 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
877 return kRGB_565_SkColorType;
878 }
879 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
880 return kGray_8_SkColorType;
881 }
882 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_INDEX8)) {
883 return kIndex_8_SkColorType;
884 }
885 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
886 return kAlpha_8_SkColorType;
887 }
888 SkASSERT(false);
889 return kN32_SkColorType;
890}
891
892static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
893 if (bitmap->colorType() == colorType ) {
894 return bitmap;
895 }
896 SkBitmap* dst = new SkBitmap();
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400897 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
898 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
899 {
ethannicholas50a8dd02016-02-10 05:40:46 -0800900 delete bitmap;
901 return dst;
902 }
903 SkASSERT(false);
904 delete dst;
905 return bitmap;
906}
907
908// caller is responsible for freeing return value
ethannicholasf62a8b72016-02-11 10:35:21 -0800909static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
910 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800911 SkDebugf("invalid bitmap\n");
912 return nullptr;
913 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800914 const void* data;
915 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
bungeman38d909e2016-08-02 14:40:46 -0700916 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
reed9ce9d672016-03-17 10:51:11 -0700917 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
msarett790f99a2016-03-09 06:16:55 -0800918
Ben Wagner145dbcd2016-11-03 14:40:50 -0400919 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
msarett790f99a2016-03-09 06:16:55 -0800920 if (nullptr != image) {
Ben Wagner145dbcd2016-11-03 14:40:50 -0400921 if (!image->asLegacyBitmap(bitmap.get(), SkImage::kRW_LegacyBitmapMode)) {
msarett790f99a2016-03-09 06:16:55 -0800922 SkDebugf("image decode failed\n");
923 return nullptr;
924 }
925
ethannicholas50a8dd02016-02-10 05:40:46 -0800926 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
927 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
928 SkColorType ct = colortype_from_name(ctName);
929 if (ct != kIndex_8_SkColorType) {
mtklein18300a32016-03-16 13:53:35 -0700930 bitmap.reset(convert_colortype(bitmap.release(), ct));
ethannicholas50a8dd02016-02-10 05:40:46 -0800931 }
932 }
mtklein18300a32016-03-16 13:53:35 -0700933 return bitmap.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800934 }
935 SkDebugf("image decode failed\n");
ethannicholas50a8dd02016-02-10 05:40:46 -0800936 return nullptr;
937}
938
reed9ce9d672016-03-17 10:51:11 -0700939static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
ethannicholasf62a8b72016-02-11 10:35:21 -0800940 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800941 if (bitmap == nullptr) {
942 return nullptr;
943 }
reed9ce9d672016-03-17 10:51:11 -0700944 auto result = SkImage::MakeFromBitmap(*bitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800945 delete bitmap;
946 return result;
947}
948
brianosmanfad98562016-05-04 11:06:28 -0700949bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
950 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -0700951 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -0800952 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
953 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -0800954 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800955 return success;
956}
957
halcanaryf412f092016-08-25 11:10:41 -0700958static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
959 SkPaint::Hinting hinting = paint.getHinting();
960 if (hinting != SkPaintDefaults_Hinting) {
961 switch (hinting) {
962 case SkPaint::kNo_Hinting:
963 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
964 break;
965 case SkPaint::kSlight_Hinting:
966 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
967 break;
968 case SkPaint::kNormal_Hinting:
969 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
970 break;
971 case SkPaint::kFull_Hinting:
972 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
973 break;
974 }
975 }
976}
977
ethannicholas50a8dd02016-02-10 05:40:46 -0800978static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
979 SkColor color = paint.getColor();
980 if (color != SK_ColorBLACK) {
981 Json::Value colorValue(Json::arrayValue);
982 colorValue.append(Json::Value(SkColorGetA(color)));
983 colorValue.append(Json::Value(SkColorGetR(color)));
984 colorValue.append(Json::Value(SkColorGetG(color)));
985 colorValue.append(Json::Value(SkColorGetB(color)));
986 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
987 }
988}
989
990static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
991 SkPaint::Style style = paint.getStyle();
992 if (style != SkPaint::kFill_Style) {
993 switch (style) {
994 case SkPaint::kStroke_Style: {
995 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
996 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
997 break;
998 }
999 case SkPaint::kStrokeAndFill_Style: {
1000 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1001 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1002 break;
1003 }
1004 default: SkASSERT(false);
1005 }
1006 }
1007}
1008
1009static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1010 SkPaint::Cap cap = paint.getStrokeCap();
1011 if (cap != SkPaint::kDefault_Cap) {
1012 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001013 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001014 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1015 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001016 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001017 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1018 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001019 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001020 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1021 break;
ethannicholas50a8dd02016-02-10 05:40:46 -08001022 default: SkASSERT(false);
1023 }
1024 }
1025}
ethannicholas1446a9a2016-02-10 14:05:02 -08001026
1027static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1028 SkPaint::Join join = paint.getStrokeJoin();
1029 if (join != SkPaint::kDefault_Join) {
1030 switch (join) {
1031 case SkPaint::kMiter_Join:
1032 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1033 SKDEBUGCANVAS_MITER_JOIN);
1034 break;
1035 case SkPaint::kRound_Join:
1036 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1037 SKDEBUGCANVAS_ROUND_JOIN);
1038 break;
1039 case SkPaint::kBevel_Join:
1040 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1041 SKDEBUGCANVAS_BEVEL_JOIN);
1042 break;
1043 default: SkASSERT(false);
1044 }
1045 }
1046}
1047
1048static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1049 SkFilterQuality quality = paint.getFilterQuality();
1050 switch (quality) {
1051 case kNone_SkFilterQuality:
1052 break;
1053 case kLow_SkFilterQuality:
1054 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1055 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1056 break;
1057 case kMedium_SkFilterQuality:
1058 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1059 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1060 break;
1061 case kHigh_SkFilterQuality:
1062 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1063 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1064 break;
1065 }
1066}
1067
halcanary9d524f22016-03-29 09:03:52 -07001068static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001069 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001070 SkMaskFilter* maskFilter = paint.getMaskFilter();
1071 if (maskFilter != nullptr) {
1072 SkMaskFilter::BlurRec blurRec;
1073 if (maskFilter->asABlur(&blurRec)) {
1074 Json::Value blur(Json::objectValue);
1075 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1076 switch (blurRec.fStyle) {
1077 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001078 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1079 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -08001080 break;
1081 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001082 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1083 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -08001084 break;
1085 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001086 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1087 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001088 break;
1089 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001090 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1091 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001092 break;
1093 default:
1094 SkASSERT(false);
1095 }
1096 switch (blurRec.fQuality) {
1097 case SkBlurQuality::kLow_SkBlurQuality:
ethannicholas1446a9a2016-02-10 14:05:02 -08001098 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
1099 SKDEBUGCANVAS_BLURQUALITY_LOW);
ethannicholas50a8dd02016-02-10 05:40:46 -08001100 break;
1101 case SkBlurQuality::kHigh_SkBlurQuality:
ethannicholas1446a9a2016-02-10 14:05:02 -08001102 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
1103 SKDEBUGCANVAS_BLURQUALITY_HIGH);
ethannicholas50a8dd02016-02-10 05:40:46 -08001104 break;
1105 default:
1106 SkASSERT(false);
1107 }
1108 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1109 } else {
1110 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -07001111 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001112 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1113 }
1114 }
1115}
1116
halcanary9d524f22016-03-29 09:03:52 -07001117static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001118 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001119 SkPathEffect* pathEffect = paint.getPathEffect();
1120 if (pathEffect != nullptr) {
1121 SkPathEffect::DashInfo dashInfo;
1122 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1123 if (dashType == SkPathEffect::kDash_DashType) {
1124 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1125 pathEffect->asADash(&dashInfo);
1126 Json::Value dashing(Json::objectValue);
1127 Json::Value intervals(Json::arrayValue);
1128 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1129 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1130 }
1131 sk_free(dashInfo.fIntervals);
1132 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1133 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1134 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1135 } else {
1136 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001137 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001138 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1139 }
1140 }
1141}
halcanary9d524f22016-03-29 09:03:52 -07001142
ethannicholas50a8dd02016-02-10 05:40:46 -08001143static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1144 SkPaint::Align textAlign = paint.getTextAlign();
1145 if (textAlign != SkPaint::kLeft_Align) {
1146 switch (textAlign) {
1147 case SkPaint::kCenter_Align: {
1148 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1149 break;
1150 }
1151 case SkPaint::kRight_Align: {
1152 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1153 break;
1154 }
1155 default: SkASSERT(false);
1156 }
1157 }
1158}
1159
halcanary9d524f22016-03-29 09:03:52 -07001160static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001161 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001162 SkTypeface* typeface = paint.getTypeface();
1163 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001164 Json::Value jsonTypeface;
1165 SkDynamicMemoryWStream buffer;
1166 typeface->serialize(&buffer);
1167 void* data = sk_malloc_throw(buffer.bytesWritten());
1168 buffer.copyTo(data);
1169 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001170 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001171 &jsonData);
1172 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1173 sk_free(data);
1174 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001175 }
1176}
1177
halcanary9d524f22016-03-29 09:03:52 -07001178static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001179 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001180 SkFlattenable* shader = paint.getShader();
1181 if (shader != nullptr) {
1182 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001183 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001184 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1185 }
1186}
1187
ethannicholasf62a8b72016-02-11 10:35:21 -08001188static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1189 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001190 SkFlattenable* imageFilter = paint.getImageFilter();
1191 if (imageFilter != nullptr) {
1192 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001193 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001194 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1195 }
1196}
1197
halcanary9d524f22016-03-29 09:03:52 -07001198static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001199 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001200 SkFlattenable* colorFilter = paint.getColorFilter();
1201 if (colorFilter != nullptr) {
1202 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001203 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001204 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1205 }
1206}
1207
halcanary9d524f22016-03-29 09:03:52 -07001208static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001209 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001210 SkFlattenable* looper = paint.getLooper();
1211 if (looper != nullptr) {
1212 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001213 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001214 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1215 }
1216}
1217
brianosmanfad98562016-05-04 11:06:28 -07001218Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001219 Json::Value result(Json::objectValue);
1220 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001221 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001222 SkPaintDefaults_MiterLimit);
1223 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001224 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
halcanary9d524f22016-03-29 09:03:52 -07001225 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001226 SkPaintDefaults_TextSize);
1227 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1228 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001229 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001230 apply_paint_color(paint, &result);
1231 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001232 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001233 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001234 apply_paint_join(paint, &result);
1235 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001236 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001237 apply_paint_patheffect(paint, &result, urlDataManager);
1238 apply_paint_maskfilter(paint, &result, urlDataManager);
1239 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001240 apply_paint_looper(paint, &result, urlDataManager);
1241 apply_paint_imagefilter(paint, &result, urlDataManager);
1242 apply_paint_colorfilter(paint, &result, urlDataManager);
1243 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001244 return result;
1245}
1246
Stan Ilievac42aeb2017-01-12 16:20:50 -05001247Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1248 Json::Value result(Json::objectValue);
1249 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1250 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1251 if (nullptr != lattice.fBounds) {
1252 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1253 }
1254 Json::Value XDivs(Json::arrayValue);
1255 for (int i = 0; i < lattice.fXCount; i++) {
1256 XDivs.append(Json::Value(lattice.fXDivs[i]));
1257 }
1258 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1259 Json::Value YDivs(Json::arrayValue);
1260 for (int i = 0; i < lattice.fYCount; i++) {
1261 YDivs.append(Json::Value(lattice.fYDivs[i]));
1262 }
1263 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
1264 if (nullptr != lattice.fFlags) {
1265 Json::Value flags(Json::arrayValue);
1266 int flagCount = 0;
1267 for (int row = 0; row < lattice.fYCount+1; row++) {
1268 Json::Value flagsRow(Json::arrayValue);
1269 for (int column = 0; column < lattice.fXCount+1; column++) {
1270 flagsRow.append(Json::Value(lattice.fFlags[flagCount++]));
1271 }
1272 flags.append(flagsRow);
1273 }
1274 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1275 }
1276 return result;
1277}
1278
ethannicholas1446a9a2016-02-10 14:05:02 -08001279static SkPoint get_json_point(Json::Value point) {
1280 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1281}
1282
1283static SkColor get_json_color(Json::Value color) {
1284 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1285}
1286
ethannicholas50a8dd02016-02-10 05:40:46 -08001287static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1288 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001289 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001290 }
1291}
1292
halcanary9d524f22016-03-29 09:03:52 -07001293static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001294 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001295 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1296 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
ethannicholasf62a8b72016-02-11 10:35:21 -08001297 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001298 if (shader != nullptr) {
reedfe630452016-03-25 09:08:00 -07001299 target->setShader(sk_ref_sp(shader));
ethannicholas50a8dd02016-02-10 05:40:46 -08001300 }
1301 }
1302}
1303
halcanary9d524f22016-03-29 09:03:52 -07001304static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001305 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001306 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1307 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
reeda4393342016-03-18 11:22:57 -07001308 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1309 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001310 if (pathEffect != nullptr) {
1311 target->setPathEffect(pathEffect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001312 }
1313 }
1314}
1315
halcanary9d524f22016-03-29 09:03:52 -07001316static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001317 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001318 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1319 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
reedefdfd512016-04-04 10:02:58 -07001320 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1321 urlDataManager));
1322 if (maskFilter) {
1323 target->setMaskFilter(std::move(maskFilter));
ethannicholas50a8dd02016-02-10 05:40:46 -08001324 }
1325 }
1326}
1327
halcanary9d524f22016-03-29 09:03:52 -07001328static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001329 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001330 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1331 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
reedd053ce92016-03-22 10:17:23 -07001332 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1333 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001334 if (colorFilter != nullptr) {
1335 target->setColorFilter(colorFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001336 }
1337 }
1338}
1339
halcanary9d524f22016-03-29 09:03:52 -07001340static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001341 SkPaint* target) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001342 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1343 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
reed7b380d02016-03-21 13:25:16 -07001344 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
ethannicholas1446a9a2016-02-10 14:05:02 -08001345 if (looper != nullptr) {
reed7b380d02016-03-21 13:25:16 -07001346 target->setLooper(std::move(looper));
ethannicholas1446a9a2016-02-10 14:05:02 -08001347 }
1348 }
1349}
1350
halcanary9d524f22016-03-29 09:03:52 -07001351static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001352 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001353 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1354 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
Mike Reed5e257172016-11-01 11:22:05 -04001355 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1356 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001357 if (imageFilter != nullptr) {
1358 target->setImageFilter(imageFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001359 }
1360 }
1361}
1362
halcanary9d524f22016-03-29 09:03:52 -07001363static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001364 SkPaint* target) {
1365 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1366 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1367 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1368 const void* data;
1369 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1370 SkMemoryStream buffer(data, length);
bungeman13b9c952016-05-12 10:09:30 -07001371 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
ethannicholasf62a8b72016-02-11 10:35:21 -08001372 }
1373}
1374
halcanaryf412f092016-08-25 11:10:41 -07001375static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1376 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1377 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1378 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1379 target->setHinting(SkPaint::kNo_Hinting);
1380 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1381 target->setHinting(SkPaint::kSlight_Hinting);
1382 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1383 target->setHinting(SkPaint::kNormal_Hinting);
1384 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1385 target->setHinting(SkPaint::kFull_Hinting);
1386 }
1387 }
1388}
1389
ethannicholas50a8dd02016-02-10 05:40:46 -08001390static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1391 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1392 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1393 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1394 target->setStyle(SkPaint::kFill_Style);
1395 }
1396 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1397 target->setStyle(SkPaint::kStroke_Style);
1398 }
1399 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1400 target->setStyle(SkPaint::kStrokeAndFill_Style);
1401 }
1402 }
1403}
1404
1405static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1406 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1407 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1408 target->setStrokeWidth(strokeWidth);
halcanary9d524f22016-03-29 09:03:52 -07001409 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001410}
1411
1412static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1413 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1414 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1415 target->setStrokeMiter(strokeMiter);
halcanary9d524f22016-03-29 09:03:52 -07001416 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001417}
1418
ethannicholas1446a9a2016-02-10 14:05:02 -08001419static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1420 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1421 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1422 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1423 target->setStrokeJoin(SkPaint::kMiter_Join);
1424 }
1425 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1426 target->setStrokeJoin(SkPaint::kRound_Join);
1427 }
1428 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1429 target->setStrokeJoin(SkPaint::kBevel_Join);
1430 }
1431 else {
1432 SkASSERT(false);
1433 }
1434 }
1435}
1436
ethannicholas50a8dd02016-02-10 05:40:46 -08001437static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1438 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1439 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1440 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1441 target->setStrokeCap(SkPaint::kButt_Cap);
1442 }
1443 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1444 target->setStrokeCap(SkPaint::kRound_Cap);
1445 }
1446 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1447 target->setStrokeCap(SkPaint::kSquare_Cap);
1448 }
1449 }
1450}
1451
ethannicholas1446a9a2016-02-10 14:05:02 -08001452static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1453 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1454 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1455 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1456 target->setFilterQuality(kNone_SkFilterQuality);
1457 }
1458 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1459 target->setFilterQuality(kLow_SkFilterQuality);
1460 }
1461 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1462 target->setFilterQuality(kMedium_SkFilterQuality);
1463 }
1464 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1465 target->setFilterQuality(kHigh_SkFilterQuality);
1466 }
1467 }
1468}
1469
ethannicholas50a8dd02016-02-10 05:40:46 -08001470static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1471 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1472 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1473 }
1474}
1475
ethannicholas1446a9a2016-02-10 14:05:02 -08001476static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1477 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1478 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1479 }
1480}
1481
ethannicholas50a8dd02016-02-10 05:40:46 -08001482static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1483 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1484 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1485 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1486 SkBlurStyle style;
1487 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1488 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1489 style = SkBlurStyle::kNormal_SkBlurStyle;
1490 }
1491 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1492 style = SkBlurStyle::kSolid_SkBlurStyle;
1493 }
1494 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1495 style = SkBlurStyle::kOuter_SkBlurStyle;
1496 }
1497 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1498 style = SkBlurStyle::kInner_SkBlurStyle;
1499 }
1500 else {
1501 SkASSERT(false);
1502 style = SkBlurStyle::kNormal_SkBlurStyle;
1503 }
1504 SkBlurMaskFilter::BlurFlags flags;
1505 const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString();
1506 if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) {
1507 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1508 }
1509 else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) {
1510 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag;
1511 }
1512 else {
1513 SkASSERT(false);
1514 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1515 }
reedefdfd512016-04-04 10:02:58 -07001516 target->setMaskFilter(SkBlurMaskFilter::Make(style, sigma, flags));
ethannicholas50a8dd02016-02-10 05:40:46 -08001517 }
1518}
1519
1520static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1521 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1522 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1523 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1524 Json::ArrayIndex count = jsonIntervals.size();
1525 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1526 for (Json::ArrayIndex i = 0; i < count; i++) {
1527 intervals[i] = jsonIntervals[i].asFloat();
1528 }
1529 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
reeda4393342016-03-18 11:22:57 -07001530 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
ethannicholas50a8dd02016-02-10 05:40:46 -08001531 sk_free(intervals);
1532 }
1533}
1534
1535static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1536 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1537 SkPaint::Align textAlign;
1538 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1539 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1540 textAlign = SkPaint::kLeft_Align;
1541 }
1542 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1543 textAlign = SkPaint::kCenter_Align;
1544 }
1545 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1546 textAlign = SkPaint::kRight_Align;
1547 }
1548 else {
1549 SkASSERT(false);
1550 textAlign = SkPaint::kLeft_Align;
1551 }
1552 target->setTextAlign(textAlign);
1553 }
1554}
1555
1556static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1557 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1558 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1559 target->setTextSize(textSize);
1560 }
1561}
1562
1563static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1564 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1565 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1566 target->setTextScaleX(textScaleX);
1567 }
1568}
1569
1570static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1571 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1572 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1573 target->setTextSkewX(textSkewX);
1574 }
1575}
1576
halcanary9d524f22016-03-29 09:03:52 -07001577static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001578 SkPaint* result) {
halcanaryf412f092016-08-25 11:10:41 -07001579 extract_json_paint_hinting(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001580 extract_json_paint_color(paint, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001581 extract_json_paint_shader(paint, urlDataManager, result);
1582 extract_json_paint_patheffect(paint, urlDataManager, result);
1583 extract_json_paint_maskfilter(paint, urlDataManager, result);
1584 extract_json_paint_colorfilter(paint, urlDataManager, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001585 extract_json_paint_looper(paint, urlDataManager, result);
1586 extract_json_paint_imagefilter(paint, urlDataManager, result);
1587 extract_json_paint_typeface(paint, urlDataManager, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001588 extract_json_paint_style(paint, result);
Florin Malita82d80872017-06-06 16:58:40 -04001589 extract_json_paint_blend_mode(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001590 extract_json_paint_strokewidth(paint, result);
1591 extract_json_paint_strokemiter(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001592 extract_json_paint_strokejoin(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001593 extract_json_paint_cap(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001594 extract_json_paint_filterquality(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001595 extract_json_paint_antialias(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001596 extract_json_paint_dither(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001597 extract_json_paint_blur(paint, result);
1598 extract_json_paint_dashing(paint, result);
1599 extract_json_paint_textalign(paint, result);
1600 extract_json_paint_textsize(paint, result);
1601 extract_json_paint_textscalex(paint, result);
1602 extract_json_paint_textskewx(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001603}
1604
1605static void extract_json_rect(Json::Value& rect, SkRect* result) {
1606 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1607}
1608
1609static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1610 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1611}
1612
1613static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1614 SkVector radii[4] = {
halcanary9d524f22016-03-29 09:03:52 -07001615 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1616 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1617 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
ethannicholas50a8dd02016-02-10 05:40:46 -08001618 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1619 };
halcanary9d524f22016-03-29 09:03:52 -07001620 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1621 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
ethannicholas50a8dd02016-02-10 05:40:46 -08001622 radii);
1623}
1624
1625static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
halcanary9d524f22016-03-29 09:03:52 -07001626 SkScalar values[] = {
ethannicholas50a8dd02016-02-10 05:40:46 -08001627 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1628 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
halcanary9d524f22016-03-29 09:03:52 -07001629 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
ethannicholas50a8dd02016-02-10 05:40:46 -08001630 };
1631 result->set9(values);
1632}
1633
1634static void extract_json_path(Json::Value& path, SkPath* result) {
1635 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1636 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1637 result->setFillType(SkPath::kWinding_FillType);
1638 }
1639 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1640 result->setFillType(SkPath::kEvenOdd_FillType);
1641 }
1642 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1643 result->setFillType(SkPath::kInverseWinding_FillType);
1644 }
1645 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1646 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1647 }
1648 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1649 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1650 Json::Value verb = verbs[i];
1651 if (verb.isString()) {
1652 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1653 result->close();
1654 }
1655 else {
1656 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1657 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1658 result->moveTo(move[0].asFloat(), move[1].asFloat());
1659 }
1660 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1661 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1662 result->lineTo(line[0].asFloat(), line[1].asFloat());
1663 }
1664 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1665 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1666 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1667 quad[1][0].asFloat(), quad[1][1].asFloat());
1668 }
1669 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1670 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1671 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1672 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1673 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1674 }
1675 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1676 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1677 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1678 conic[1][0].asFloat(), conic[1][1].asFloat(),
1679 conic[2].asFloat());
1680 }
1681 else {
1682 SkASSERT(false);
1683 }
1684 }
1685 }
1686}
1687
Mike Reedc1f77742016-12-09 09:00:50 -05001688SkClipOp get_json_clipop(Json::Value& jsonOp) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001689 const char* op = jsonOp.asCString();
1690 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001691 return kDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001692 }
1693 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001694 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001695 }
1696 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001697 return kUnion_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001698 }
1699 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001700 return kXOR_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001701 }
1702 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001703 return kReverseDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001704 }
1705 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001706 return kReplace_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001707 }
1708 SkASSERT(false);
Mike Reedc1f77742016-12-09 09:00:50 -05001709 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001710}
1711
ethannicholas1446a9a2016-02-10 14:05:02 -08001712SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kDrawClear_OpType) {
1713 fColor = color;
1714 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
1715}
1716
1717void SkClearCommand::execute(SkCanvas* canvas) const {
1718 canvas->clear(fColor);
1719}
1720
ethannicholasf62a8b72016-02-11 10:35:21 -08001721Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1722 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001723 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001724 return result;
1725}
1726
ethannicholasf62a8b72016-02-11 10:35:21 -08001727 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001728 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1729 return new SkClearCommand(get_json_color(color));
1730}
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001731
Mike Reedc1f77742016-12-09 09:00:50 -05001732SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001733 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001734 fPath = path;
1735 fOp = op;
1736 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001737
robertphillips@google.com91217d02013-03-17 18:33:46 +00001738 fInfo.push(SkObjectParser::PathToString(path));
reed73603f32016-09-20 08:42:38 -07001739 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.com91217d02013-03-17 18:33:46 +00001740 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001741}
1742
fmalita8c89c522014-11-08 16:18:56 -08001743void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001744 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001745}
1746
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001747bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001748 render_path(canvas, fPath);
1749 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001750}
1751
ethannicholasf62a8b72016-02-11 10:35:21 -08001752Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1753 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001754 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001755 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1756 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1757 return result;
1758}
1759
halcanary9d524f22016-03-29 09:03:52 -07001760SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001761 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001762 SkPath path;
1763 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
reed73603f32016-09-20 08:42:38 -07001764 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001765 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1766}
1767
Mike Reedc1f77742016-12-09 09:00:50 -05001768SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001769 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001770 fRegion = region;
1771 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001772
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001773 fInfo.push(SkObjectParser::RegionToString(region));
reed73603f32016-09-20 08:42:38 -07001774 fInfo.push(SkObjectParser::ClipOpToString(op));
chudy@google.com902ebe52012-06-29 14:21:22 +00001775}
1776
fmalita8c89c522014-11-08 16:18:56 -08001777void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001778 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001779}
1780
ethannicholasf62a8b72016-02-11 10:35:21 -08001781Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1782 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001783 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001784 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1785 return result;
1786}
1787
halcanary9d524f22016-03-29 09:03:52 -07001788SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001789 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001790 SkASSERT(false);
1791 return nullptr;
1792}
1793
Mike Reedc1f77742016-12-09 09:00:50 -05001794SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001795 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001796 fRect = rect;
1797 fOp = op;
1798 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001799
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001800 fInfo.push(SkObjectParser::RectToString(rect));
reed73603f32016-09-20 08:42:38 -07001801 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001802 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001803}
1804
fmalita8c89c522014-11-08 16:18:56 -08001805void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001806 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001807}
1808
ethannicholasf62a8b72016-02-11 10:35:21 -08001809Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1810 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001811 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001812 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1813 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001814
1815 SkString desc;
1816 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1817
ethannicholas50a8dd02016-02-10 05:40:46 -08001818 return result;
1819}
1820
halcanary9d524f22016-03-29 09:03:52 -07001821SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001822 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001823 SkRect rect;
1824 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
reed73603f32016-09-20 08:42:38 -07001825 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001826 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1827}
1828
Mike Reedc1f77742016-12-09 09:00:50 -05001829SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001830 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001831 fRRect = rrect;
1832 fOp = op;
1833 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001834
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001835 fInfo.push(SkObjectParser::RRectToString(rrect));
reed73603f32016-09-20 08:42:38 -07001836 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001837 fInfo.push(SkObjectParser::BoolToString(doAA));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001838}
1839
fmalita8c89c522014-11-08 16:18:56 -08001840void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001841 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001842}
1843
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001844bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001845 render_rrect(canvas, fRRect);
1846 return true;
1847}
1848
ethannicholasf62a8b72016-02-11 10:35:21 -08001849Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1850 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001851 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1852 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1853 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1854 return result;
1855}
1856
halcanary9d524f22016-03-29 09:03:52 -07001857SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001858 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001859 SkRRect rrect;
1860 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
halcanary9d524f22016-03-29 09:03:52 -07001861 return new SkClipRRectCommand(rrect,
reed73603f32016-09-20 08:42:38 -07001862 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001863 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1864}
1865
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001866SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001867 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001868 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001869
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001870 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00001871}
1872
fmalita8c89c522014-11-08 16:18:56 -08001873void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001874 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001875}
1876
ethannicholasf62a8b72016-02-11 10:35:21 -08001877Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1878 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001879 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001880 return result;
1881}
1882
ethannicholasf62a8b72016-02-11 10:35:21 -08001883SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001884 SkMatrix matrix;
1885 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1886 return new SkConcatCommand(matrix);
1887}
1888
reed97660cc2016-06-28 18:54:19 -07001889////
1890
1891SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1892 sk_sp<SkData> value)
1893 : INHERITED(kDrawAnnotation_OpType)
1894 , fRect(rect)
1895 , fKey(key)
1896 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07001897{
1898 SkString str;
1899 str.appendf("Key: %s Value: ", key);
1900 if (fValue && fValue->size()) {
1901 str.append((const char*) fValue->bytes(), fValue->size());
1902 } else {
1903 str.appendf("no value");
1904 }
1905 str.appendf("\n");
1906 fInfo.push(new SkString(str));
1907}
reed97660cc2016-06-28 18:54:19 -07001908
1909void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1910 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1911}
1912
1913Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1914 Json::Value result = INHERITED::toJSON(urlDataManager);
1915
1916 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1917 result["key"] = Json::Value(fKey.c_str());
1918 if (fValue.get()) {
1919 // TODO: dump out the "value"
1920 }
reed67f62fa2016-06-29 11:36:34 -07001921
1922 SkString desc;
1923 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
1924 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
1925
reed97660cc2016-06-28 18:54:19 -07001926 return result;
1927}
1928
1929SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
1930 UrlDataManager& urlDataManager) {
1931 SkRect rect;
1932 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
1933 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
1934 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
1935}
1936
1937////
1938
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001939SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07001940 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08001941 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001942 fBitmap = bitmap;
1943 fLeft = left;
1944 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07001945 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001946 fPaint = *paint;
1947 fPaintPtr = &fPaint;
1948 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07001949 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001950 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001951
1952 fInfo.push(SkObjectParser::BitmapToString(bitmap));
1953 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
1954 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
bsalomon49f085d2014-09-05 13:34:00 -07001955 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001956 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00001957 }
chudy@google.com902ebe52012-06-29 14:21:22 +00001958}
1959
fmalita8c89c522014-11-08 16:18:56 -08001960void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001961 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00001962}
1963
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001964bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001965 render_bitmap(canvas, fBitmap);
1966 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001967}
1968
ethannicholasf62a8b72016-02-11 10:35:21 -08001969Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
1970 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001971 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08001972 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001973 Json::Value command(Json::objectValue);
1974 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07001975 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08001976 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07001977 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001978 }
1979 }
1980 return result;
1981}
1982
halcanary9d524f22016-03-29 09:03:52 -07001983SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001984 UrlDataManager& urlDataManager) {
1985 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001986 if (bitmap == nullptr) {
1987 return nullptr;
1988 }
1989 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
1990 SkPaint* paintPtr;
1991 SkPaint paint;
1992 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001993 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08001994 paintPtr = &paint;
1995 }
1996 else {
1997 paintPtr = nullptr;
1998 }
halcanary9d524f22016-03-29 09:03:52 -07001999 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002000 point[1].asFloat(), paintPtr);
2001 delete bitmap;
2002 return result;
2003}
2004
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002005SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00002006 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002007 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002008 fBitmap = bitmap;
2009 fCenter = center;
2010 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07002011 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002012 fPaint = *paint;
2013 fPaintPtr = &fPaint;
2014 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002015 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002016 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002017
2018 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2019 fInfo.push(SkObjectParser::IRectToString(center));
2020 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07002021 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002022 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002023 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002024}
2025
fmalita8c89c522014-11-08 16:18:56 -08002026void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002027 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002028}
2029
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002030bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08002031 SkRect tmp = SkRect::Make(fCenter);
2032 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002033 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002034}
2035
ethannicholasf62a8b72016-02-11 10:35:21 -08002036Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2037 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002038 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002039 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002040 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08002041 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07002042 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002043 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002044 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002045 }
2046 }
2047 return result;
2048}
2049
halcanary9d524f22016-03-29 09:03:52 -07002050SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002051 UrlDataManager& urlDataManager) {
2052 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002053 if (bitmap == nullptr) {
2054 return nullptr;
2055 }
2056 SkIRect center;
2057 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2058 SkRect dst;
2059 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2060 SkPaint* paintPtr;
2061 SkPaint paint;
2062 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002063 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002064 paintPtr = &paint;
2065 }
2066 else {
2067 paintPtr = nullptr;
2068 }
2069 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2070 delete bitmap;
2071 return result;
2072}
2073
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002074SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002075 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002076 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08002077 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002078 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07002079 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002080 fSrc = *src;
2081 } else {
2082 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002083 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00002084 fDst = dst;
2085
bsalomon49f085d2014-09-05 13:34:00 -07002086 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002087 fPaint = *paint;
2088 fPaintPtr = &fPaint;
2089 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002090 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00002091 }
reeda5517e22015-07-14 10:54:12 -07002092 fConstraint = constraint;
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002093
robertphillips@google.com91217d02013-03-17 18:33:46 +00002094 fInfo.push(SkObjectParser::BitmapToString(bitmap));
bsalomon49f085d2014-09-05 13:34:00 -07002095 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002096 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2097 }
2098 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07002099 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002100 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002101 }
reeda5517e22015-07-14 10:54:12 -07002102 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
chudy@google.com902ebe52012-06-29 14:21:22 +00002103}
2104
fmalita8c89c522014-11-08 16:18:56 -08002105void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07002106 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002107}
2108
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002109bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002110 render_bitmap(canvas, fBitmap, this->srcRect());
2111 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002112}
2113
ethannicholasf62a8b72016-02-11 10:35:21 -08002114Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2115 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002116 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002117 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002118 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2119 if (!fSrc.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07002120 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
ethannicholas50a8dd02016-02-10 05:40:46 -08002121 }
brianosmanfad98562016-05-04 11:06:28 -07002122 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002123 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002124 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002125 }
2126 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2127 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2128 }
2129 }
reed67f62fa2016-06-29 11:36:34 -07002130
2131 SkString desc;
2132 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2133
ethannicholas50a8dd02016-02-10 05:40:46 -08002134 return result;
2135}
2136
halcanary9d524f22016-03-29 09:03:52 -07002137SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002138 UrlDataManager& urlDataManager) {
2139 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002140 if (bitmap == nullptr) {
2141 return nullptr;
2142 }
2143 SkRect dst;
2144 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2145 SkPaint* paintPtr;
2146 SkPaint paint;
2147 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002148 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002149 paintPtr = &paint;
2150 }
2151 else {
2152 paintPtr = nullptr;
2153 }
2154 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002155 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002156 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2157 constraint = SkCanvas::kStrict_SrcRectConstraint;
2158 }
2159 else {
2160 constraint = SkCanvas::kFast_SrcRectConstraint;
2161 }
2162 SkRect* srcPtr;
2163 SkRect src;
2164 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2165 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2166 srcPtr = &src;
2167 }
2168 else {
2169 srcPtr = nullptr;
2170 }
2171 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2172 constraint);
2173 delete bitmap;
2174 return result;
2175}
2176
fmalita651c9202015-07-22 10:23:01 -07002177SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2178 const SkPaint* paint)
2179 : INHERITED(kDrawImage_OpType)
2180 , fImage(SkRef(image))
2181 , fLeft(left)
2182 , fTop(top) {
2183
fmalita7361bf02015-10-29 12:13:48 -07002184 fInfo.push(SkObjectParser::ImageToString(image));
2185 fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
2186 fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));
2187
fmalita651c9202015-07-22 10:23:01 -07002188 if (paint) {
2189 fPaint.set(*paint);
fmalita7361bf02015-10-29 12:13:48 -07002190 fInfo.push(SkObjectParser::PaintToString(*paint));
fmalita651c9202015-07-22 10:23:01 -07002191 }
2192}
2193
2194void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002195 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07002196}
2197
2198bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2199 SkAutoCanvasRestore acr(canvas, true);
2200 canvas->clear(0xFFFFFFFF);
2201
2202 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2203 SkIntToScalar(fImage->width()),
2204 SkIntToScalar(fImage->height())));
2205 this->execute(canvas);
2206 return true;
2207}
2208
ethannicholasf62a8b72016-02-11 10:35:21 -08002209Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2210 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002211 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002212 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002213 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002214 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002215 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002216 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002217 }
msarett0ac1bec2016-08-29 09:15:33 -07002218
2219 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2220 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2221 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2222 switch (fImage->alphaType()) {
2223 case kOpaque_SkAlphaType:
2224 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2225 break;
2226 case kPremul_SkAlphaType:
2227 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2228 break;
2229 case kUnpremul_SkAlphaType:
2230 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2231 break;
2232 default:
2233 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2234 break;
2235 }
ethannicholas50a8dd02016-02-10 05:40:46 -08002236 }
2237 return result;
2238}
2239
halcanary9d524f22016-03-29 09:03:52 -07002240SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002241 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002242 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002243 if (image == nullptr) {
2244 return nullptr;
2245 }
2246 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2247 SkPaint* paintPtr;
2248 SkPaint paint;
2249 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002250 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002251 paintPtr = &paint;
2252 }
2253 else {
2254 paintPtr = nullptr;
2255 }
reed9ce9d672016-03-17 10:51:11 -07002256 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002257 point[1].asFloat(), paintPtr);
ethannicholas50a8dd02016-02-10 05:40:46 -08002258 return result;
2259}
2260
Stan Ilievac42aeb2017-01-12 16:20:50 -05002261SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2262 const SkCanvas::Lattice& lattice,
2263 const SkRect& dst, const SkPaint* paint)
2264 : INHERITED(kDrawImageLattice_OpType)
2265 , fImage(SkRef(image))
2266 , fLattice(lattice)
2267 , fDst(dst) {
2268
2269 fInfo.push(SkObjectParser::ImageToString(image));
2270 fInfo.push(SkObjectParser::LatticeToString(lattice));
2271 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2272 if (paint) {
2273 fPaint.set(*paint);
2274 fInfo.push(SkObjectParser::PaintToString(*paint));
2275 }
2276}
2277
2278void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
2279 SkLatticeIter iter(fLattice, fDst);
2280 SkRect srcR, dstR;
2281 while (iter.next(&srcR, &dstR)) {
2282 canvas->legacy_drawImageRect(fImage.get(), &srcR, dstR,
2283 fPaint.getMaybeNull(), SkCanvas::kStrict_SrcRectConstraint);
2284 }
2285}
2286
2287bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2288 SkAutoCanvasRestore acr(canvas, true);
2289 canvas->clear(0xFFFFFFFF);
2290
2291 xlate_and_scale_to_bounds(canvas, fDst);
2292
2293 this->execute(canvas);
2294 return true;
2295}
2296
2297Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2298 Json::Value result = INHERITED::toJSON(urlDataManager);
2299 Json::Value encoded;
2300 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2301 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2302 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2303 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2304 if (fPaint.isValid()) {
2305 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2306 }
2307 }
2308
2309 SkString desc;
2310 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2311
2312 return result;
2313}
2314
fmalita651c9202015-07-22 10:23:01 -07002315SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2316 const SkRect& dst, const SkPaint* paint,
2317 SkCanvas::SrcRectConstraint constraint)
2318 : INHERITED(kDrawImageRect_OpType)
2319 , fImage(SkRef(image))
2320 , fDst(dst)
2321 , fConstraint(constraint) {
2322
2323 if (src) {
2324 fSrc.set(*src);
2325 }
2326
2327 if (paint) {
2328 fPaint.set(*paint);
2329 }
robertphillips80af6452015-08-24 08:27:38 -07002330
2331 fInfo.push(SkObjectParser::ImageToString(image));
2332 if (src) {
2333 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2334 }
2335 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2336 if (paint) {
2337 fInfo.push(SkObjectParser::PaintToString(*paint));
2338 }
2339 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
fmalita651c9202015-07-22 10:23:01 -07002340}
2341
2342void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002343 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2344 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07002345}
2346
2347bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2348 SkAutoCanvasRestore acr(canvas, true);
2349 canvas->clear(0xFFFFFFFF);
2350
2351 xlate_and_scale_to_bounds(canvas, fDst);
2352
2353 this->execute(canvas);
2354 return true;
2355}
2356
ethannicholasf62a8b72016-02-11 10:35:21 -08002357Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2358 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002359 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002360 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002361 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2362 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002363 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002364 }
brianosmanfad98562016-05-04 11:06:28 -07002365 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002366 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002367 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002368 }
2369 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2370 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2371 }
2372 }
reed67f62fa2016-06-29 11:36:34 -07002373
2374 SkString desc;
2375 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2376
ethannicholas50a8dd02016-02-10 05:40:46 -08002377 return result;
2378}
2379
halcanary9d524f22016-03-29 09:03:52 -07002380SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002381 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002382 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002383 if (image == nullptr) {
2384 return nullptr;
2385 }
2386 SkRect dst;
2387 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2388 SkPaint* paintPtr;
2389 SkPaint paint;
2390 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002391 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002392 paintPtr = &paint;
2393 }
2394 else {
2395 paintPtr = nullptr;
2396 }
2397 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002398 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002399 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2400 constraint = SkCanvas::kStrict_SrcRectConstraint;
2401 }
2402 else {
2403 constraint = SkCanvas::kFast_SrcRectConstraint;
2404 }
2405 SkRect* srcPtr;
2406 SkRect src;
2407 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2408 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2409 srcPtr = &src;
2410 }
2411 else {
2412 srcPtr = nullptr;
2413 }
reed9ce9d672016-03-17 10:51:11 -07002414 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
ethannicholas50a8dd02016-02-10 05:40:46 -08002415 constraint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002416 return result;
2417}
2418
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002419SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002420 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002421 fOval = oval;
2422 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002423
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002424 fInfo.push(SkObjectParser::RectToString(oval));
2425 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00002426}
2427
fmalita8c89c522014-11-08 16:18:56 -08002428void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002429 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002430}
2431
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002432bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002433 canvas->clear(0xFFFFFFFF);
2434 canvas->save();
2435
2436 xlate_and_scale_to_bounds(canvas, fOval);
2437
2438 SkPaint p;
2439 p.setColor(SK_ColorBLACK);
2440 p.setStyle(SkPaint::kStroke_Style);
2441
2442 canvas->drawOval(fOval, p);
2443 canvas->restore();
2444
2445 return true;
2446}
2447
ethannicholasf62a8b72016-02-11 10:35:21 -08002448Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2449 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002450 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2451 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002452 return result;
2453}
2454
halcanary9d524f22016-03-29 09:03:52 -07002455SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002456 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002457 SkRect coords;
2458 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2459 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002460 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002461 return new SkDrawOvalCommand(coords, paint);
2462}
2463
bsalomonac3aa242016-08-19 11:25:19 -07002464SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2465 bool useCenter, const SkPaint& paint)
2466 : INHERITED(kDrawOval_OpType) {
2467 fOval = oval;
2468 fStartAngle = startAngle;
2469 fSweepAngle = sweepAngle;
2470 fUseCenter = useCenter;
2471 fPaint = paint;
2472
2473 fInfo.push(SkObjectParser::RectToString(oval));
2474 fInfo.push(SkObjectParser::ScalarToString(startAngle, "StartAngle: "));
2475 fInfo.push(SkObjectParser::ScalarToString(sweepAngle, "SweepAngle: "));
2476 fInfo.push(SkObjectParser::BoolToString(useCenter));
2477 fInfo.push(SkObjectParser::PaintToString(paint));
2478}
2479
2480void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2481 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2482}
2483
2484bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2485 canvas->clear(0xFFFFFFFF);
2486 canvas->save();
2487
2488 xlate_and_scale_to_bounds(canvas, fOval);
2489
2490 SkPaint p;
2491 p.setColor(SK_ColorBLACK);
2492 p.setStyle(SkPaint::kStroke_Style);
2493
2494 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2495 canvas->restore();
2496
2497 return true;
2498}
2499
2500Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2501 Json::Value result = INHERITED::toJSON(urlDataManager);
2502 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2503 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2504 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2505 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2506 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2507 return result;
2508}
2509
2510SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2511 UrlDataManager& urlDataManager) {
2512 SkRect coords;
2513 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2514 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2515 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2516 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2517 SkPaint paint;
2518 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2519 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2520}
2521
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002522SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002523 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002524 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002525
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002526 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002527}
2528
fmalita8c89c522014-11-08 16:18:56 -08002529void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002530 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002531}
2532
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002533bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002534 canvas->clear(0xFFFFFFFF);
2535 canvas->drawPaint(fPaint);
2536 return true;
2537}
2538
ethannicholasf62a8b72016-02-11 10:35:21 -08002539Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2540 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002541 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002542 return result;
2543}
2544
halcanary9d524f22016-03-29 09:03:52 -07002545SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002546 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002547 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002548 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002549 return new SkDrawPaintCommand(paint);
2550}
2551
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002552SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002553 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002554 fPath = path;
2555 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002556
robertphillips@google.com91217d02013-03-17 18:33:46 +00002557 fInfo.push(SkObjectParser::PathToString(path));
2558 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002559}
2560
fmalita8c89c522014-11-08 16:18:56 -08002561void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002562 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002563}
2564
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002565bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002566 render_path(canvas, fPath);
2567 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002568}
2569
ethannicholasf62a8b72016-02-11 10:35:21 -08002570Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2571 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002572 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2573 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002574 return result;
2575}
2576
halcanary9d524f22016-03-29 09:03:52 -07002577SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002578 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002579 SkPath path;
2580 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2581 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002582 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002583 return new SkDrawPathCommand(path, paint);
2584}
2585
fmalita160ebb22015-04-01 20:58:37 -07002586SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2587 const SkMatrix* matrix,
2588 const SkPaint* paint)
2589 : INHERITED(kBeginDrawPicture_OpType)
2590 , fPicture(SkRef(picture)) {
2591
2592 SkString* str = new SkString;
2593 str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
2594 picture->cullRect().fLeft, picture->cullRect().fTop,
2595 picture->cullRect().fRight, picture->cullRect().fBottom);
2596 fInfo.push(str);
robertphillipsb3f319f2014-08-13 10:46:23 -07002597
bsalomon49f085d2014-09-05 13:34:00 -07002598 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002599 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002600 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2601 }
fmalita160ebb22015-04-01 20:58:37 -07002602
bsalomon49f085d2014-09-05 13:34:00 -07002603 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002604 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002605 fInfo.push(SkObjectParser::PaintToString(*paint));
2606 }
fmalita160ebb22015-04-01 20:58:37 -07002607
2608}
2609
2610void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2611 if (fPaint.isValid()) {
2612 SkRect bounds = fPicture->cullRect();
2613 if (fMatrix.isValid()) {
2614 fMatrix.get()->mapRect(&bounds);
2615 }
2616 canvas->saveLayer(&bounds, fPaint.get());
2617 }
2618
2619 if (fMatrix.isValid()) {
2620 if (!fPaint.isValid()) {
2621 canvas->save();
2622 }
2623 canvas->concat(*fMatrix.get());
2624 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002625}
2626
fmalita160ebb22015-04-01 20:58:37 -07002627bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002628 canvas->clear(0xFFFFFFFF);
2629 canvas->save();
2630
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002631 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002632
robertphillips9b14f262014-06-04 05:40:44 -07002633 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002634
2635 canvas->restore();
2636
2637 return true;
2638}
2639
fmalita160ebb22015-04-01 20:58:37 -07002640SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2641 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2642
2643void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2644 if (fRestore) {
2645 canvas->restore();
2646 }
2647}
2648
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002649SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002650 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002651 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002652 fMode = mode;
2653 fCount = count;
2654 fPts = new SkPoint[count];
2655 memcpy(fPts, pts, count * sizeof(SkPoint));
2656 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002657
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002658 fInfo.push(SkObjectParser::PointsToString(pts, count));
2659 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
2660 "Points: "));
2661 fInfo.push(SkObjectParser::PointModeToString(mode));
2662 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002663}
2664
fmalita8c89c522014-11-08 16:18:56 -08002665void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002666 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002667}
2668
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002669bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002670 canvas->clear(0xFFFFFFFF);
2671 canvas->save();
2672
2673 SkRect bounds;
2674
2675 bounds.setEmpty();
2676 for (unsigned int i = 0; i < fCount; ++i) {
2677 bounds.growToInclude(fPts[i].fX, fPts[i].fY);
2678 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002679
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002680 xlate_and_scale_to_bounds(canvas, bounds);
2681
2682 SkPaint p;
2683 p.setColor(SK_ColorBLACK);
2684 p.setStyle(SkPaint::kStroke_Style);
2685
2686 canvas->drawPoints(fMode, fCount, fPts, p);
2687 canvas->restore();
2688
2689 return true;
2690}
2691
ethannicholasf62a8b72016-02-11 10:35:21 -08002692Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2693 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002694 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2695 Json::Value points(Json::arrayValue);
2696 for (size_t i = 0; i < fCount; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002697 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002698 }
2699 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07002700 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002701 return result;
2702}
2703
halcanary9d524f22016-03-29 09:03:52 -07002704SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002705 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002706 SkCanvas::PointMode mode;
2707 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2708 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2709 mode = SkCanvas::kPoints_PointMode;
2710 }
2711 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2712 mode = SkCanvas::kLines_PointMode;
2713 }
2714 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2715 mode = SkCanvas::kPolygon_PointMode;
2716 }
2717 else {
2718 SkASSERT(false);
2719 return nullptr;
2720 }
2721 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2722 int count = (int) jsonPoints.size();
2723 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2724 for (int i = 0; i < count; i++) {
2725 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2726 }
2727 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002728 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002729 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2730 sk_free(points);
2731 return result;
2732}
2733
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002734SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002735 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002736 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002737 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002738
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002739 fText = new char[byteLength];
2740 memcpy(fText, text, byteLength);
2741 fByteLength = byteLength;
2742
2743 fPos = new SkPoint[numPts];
2744 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2745
2746 fPaint = paint;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002747
2748 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
chudy@google.com902ebe52012-06-29 14:21:22 +00002749 // TODO(chudy): Test that this works.
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002750 fInfo.push(SkObjectParser::PointsToString(pos, 1));
2751 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002752}
2753
fmalita8c89c522014-11-08 16:18:56 -08002754void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002755 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002756}
2757
ethannicholasf62a8b72016-02-11 10:35:21 -08002758Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2759 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002760 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002761 ((const char*) fText) + fByteLength);
2762 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08002763 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2764 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002765 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002766 }
2767 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07002768 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002769 return result;
2770}
2771
halcanary9d524f22016-03-29 09:03:52 -07002772SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002773 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002774 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2775 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002776 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002777 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2778 int count = (int) coords.size();
2779 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2780 for (int i = 0; i < count; i++) {
2781 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2782 }
2783 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2784}
chudy@google.com902ebe52012-06-29 14:21:22 +00002785
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002786SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2787 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002788 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002789 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002790 size_t numPts = paint.countText(text, byteLength);
2791
2792 fText = new char[byteLength];
2793 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002794 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002795
2796 fXpos = new SkScalar[numPts];
2797 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2798
robertphillips@google.com91217d02013-03-17 18:33:46 +00002799 fConstY = constY;
2800 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002801
robertphillips@google.com91217d02013-03-17 18:33:46 +00002802 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2803 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
2804 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
2805 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002806}
2807
fmalita8c89c522014-11-08 16:18:56 -08002808void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002809 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002810}
2811
bungeman51190df2016-03-09 07:42:54 -08002812Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
2813 Json::Value result = INHERITED::toJSON(urlDataManager);
2814 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2815 ((const char*) fText) + fByteLength);
2816 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
2817 Json::Value xpos(Json::arrayValue);
2818 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2819 for (size_t i = 0; i < numXpos; i++) {
2820 xpos.append(Json::Value(fXpos[i]));
2821 }
2822 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07002823 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08002824 return result;
2825}
2826
2827SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
2828 UrlDataManager& urlDataManager) {
2829 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2830 SkPaint paint;
2831 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2832 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2833 int count = (int) jsonXpos.size();
2834 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
2835 for (int i = 0; i < count; i++) {
2836 xpos[i] = jsonXpos[i].asFloat();
2837 }
2838 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2839 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
2840}
2841
fmalita0d48e412016-01-04 08:08:04 -08002842static const char* gPositioningLabels[] = {
2843 "kDefault_Positioning",
2844 "kHorizontal_Positioning",
2845 "kFull_Positioning",
2846};
2847
fmalita37283c22016-09-13 10:00:23 -07002848SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07002849 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002850 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07002851 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07002852 , fXPos(x)
2853 , fYPos(y)
2854 , fPaint(paint) {
2855
Ben Wagner145dbcd2016-11-03 14:40:50 -04002856 std::unique_ptr<SkString> runsStr(new SkString);
fmalitab7425172014-08-26 07:56:44 -07002857 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
fmalitaff3106c2014-12-09 05:28:20 -08002858 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
2859 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
Ben Wagner145dbcd2016-11-03 14:40:50 -04002860 fInfo.push(runsStr.get());
fmalitab7425172014-08-26 07:56:44 -07002861 fInfo.push(SkObjectParser::PaintToString(paint));
fmalitae77f2da2015-12-08 18:59:18 -08002862
2863 unsigned runs = 0;
2864 SkPaint runPaint(paint);
fmalita02526bd2016-09-14 14:55:59 -07002865 SkTextBlobRunIterator iter(fBlob.get());
fmalitae77f2da2015-12-08 18:59:18 -08002866 while (!iter.done()) {
Ben Wagner145dbcd2016-11-03 14:40:50 -04002867 std::unique_ptr<SkString> tmpStr(new SkString);
fmalita0d48e412016-01-04 08:08:04 -08002868 tmpStr->printf("==== Run [%d] ====", runs++);
2869 fInfo.push(tmpStr.release());
fmalitae77f2da2015-12-08 18:59:18 -08002870
2871 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
fmalita0d48e412016-01-04 08:08:04 -08002872 tmpStr.reset(new SkString("GlyphPositioning: "));
2873 tmpStr->append(gPositioningLabels[iter.positioning()]);
2874 fInfo.push(tmpStr.release());
2875
fmalitae77f2da2015-12-08 18:59:18 -08002876 iter.applyFontToPaint(&runPaint);
2877 fInfo.push(SkObjectParser::PaintToString(runPaint));
2878
2879 iter.next();
2880 }
2881
2882 runsStr->printf("Runs: %d", runs);
2883 // runStr is owned by fInfo at this point.
2884 runsStr.release();
fmalitab7425172014-08-26 07:56:44 -07002885}
2886
fmalita8c89c522014-11-08 16:18:56 -08002887void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07002888 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2889}
2890
fmalita55773872014-08-29 15:08:20 -07002891bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
2892 canvas->clear(SK_ColorWHITE);
2893 canvas->save();
2894
2895 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
2896 xlate_and_scale_to_bounds(canvas, bounds);
2897
fmalita37283c22016-09-13 10:00:23 -07002898 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07002899
2900 canvas->restore();
2901
2902 return true;
2903}
2904
ethannicholasf62a8b72016-02-11 10:35:21 -08002905Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
2906 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002907 Json::Value runs(Json::arrayValue);
2908 SkTextBlobRunIterator iter(fBlob.get());
2909 while (!iter.done()) {
2910 Json::Value run(Json::objectValue);
2911 Json::Value jsonPositions(Json::arrayValue);
2912 Json::Value jsonGlyphs(Json::arrayValue);
2913 const SkScalar* iterPositions = iter.pos();
2914 const uint16_t* iterGlyphs = iter.glyphs();
2915 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
2916 switch (iter.positioning()) {
2917 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07002918 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
2919 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002920 break;
2921 case SkTextBlob::kHorizontal_Positioning:
2922 jsonPositions.append(Json::Value(iterPositions[i]));
2923 break;
2924 case SkTextBlob::kDefault_Positioning:
2925 break;
2926 }
2927 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
2928 }
2929 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
2930 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
2931 }
2932 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
2933 SkPaint fontPaint;
2934 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07002935 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
2936 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08002937 runs.append(run);
2938 iter.next();
2939 }
reed6d2c3e72016-07-07 14:10:14 -07002940 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08002941 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
2942 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
2943 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07002944 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07002945 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07002946
2947 SkString desc;
2948 // make the bounds local by applying the x,y
2949 bounds.offset(fXPos, fYPos);
2950 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
2951
ethannicholas50a8dd02016-02-10 05:40:46 -08002952 return result;
2953}
2954
halcanary9d524f22016-03-29 09:03:52 -07002955SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002956 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002957 SkTextBlobBuilder builder;
2958 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
2959 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
2960 Json::Value run = runs[i];
2961 SkPaint font;
2962 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
ethannicholasf62a8b72016-02-11 10:35:21 -08002963 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
ethannicholas50a8dd02016-02-10 05:40:46 -08002964 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
2965 int count = glyphs.size();
2966 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2967 SkScalar x = coords[0].asFloat();
2968 SkScalar y = coords[1].asFloat();
reed6d2c3e72016-07-07 14:10:14 -07002969 SkRect bounds;
2970 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
2971
ethannicholas50a8dd02016-02-10 05:40:46 -08002972 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
2973 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2974 if (positions.size() > 0 && positions[0].isNumeric()) {
reed6d2c3e72016-07-07 14:10:14 -07002975 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08002976 for (int j = 0; j < count; j++) {
2977 buffer.glyphs[j] = glyphs[j].asUInt();
2978 buffer.pos[j] = positions[j].asFloat();
2979 }
2980 }
2981 else {
reed6d2c3e72016-07-07 14:10:14 -07002982 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08002983 for (int j = 0; j < count; j++) {
2984 buffer.glyphs[j] = glyphs[j].asUInt();
2985 buffer.pos[j * 2] = positions[j][0].asFloat();
2986 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
2987 }
2988 }
2989 }
2990 else {
reed6d2c3e72016-07-07 14:10:14 -07002991 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08002992 for (int j = 0; j < count; j++) {
2993 buffer.glyphs[j] = glyphs[j].asUInt();
2994 }
2995 }
2996 }
2997 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
2998 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2999 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003000 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
fmalita37283c22016-09-13 10:00:23 -07003001 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003002}
3003
robertphillips9bafc302015-02-13 11:13:00 -08003004SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04003005 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08003006 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003007 : INHERITED(kDrawPatch_OpType)
3008 , fBlendMode(bmode)
3009{
robertphillips9bafc302015-02-13 11:13:00 -08003010 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08003011 if (colors != nullptr) {
3012 memcpy(fColors, colors, sizeof(fColors));
3013 fColorsPtr = fColors;
3014 } else {
3015 fColorsPtr = nullptr;
3016 }
3017 if (texCoords != nullptr) {
3018 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3019 fTexCoordsPtr = fTexCoords;
3020 } else {
3021 fTexCoordsPtr = nullptr;
3022 }
robertphillips9bafc302015-02-13 11:13:00 -08003023 fPaint = paint;
3024
3025 fInfo.push(SkObjectParser::PaintToString(paint));
3026}
3027
3028void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04003029 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08003030}
3031
ethannicholasf62a8b72016-02-11 10:35:21 -08003032Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3033 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08003034 Json::Value cubics = Json::Value(Json::arrayValue);
3035 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003036 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003037 }
3038 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3039 if (fColorsPtr != nullptr) {
3040 Json::Value colors = Json::Value(Json::arrayValue);
3041 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003042 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003043 }
3044 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3045 }
3046 if (fTexCoordsPtr != nullptr) {
3047 Json::Value texCoords = Json::Value(Json::arrayValue);
3048 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003049 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003050 }
3051 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3052 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003053 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08003054 return result;
3055}
3056
halcanary9d524f22016-03-29 09:03:52 -07003057SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003058 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08003059 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3060 SkPoint cubics[12];
3061 for (int i = 0; i < 12; i++) {
3062 cubics[i] = get_json_point(jsonCubics[i]);
3063 }
3064 SkColor* colorsPtr;
3065 SkColor colors[4];
3066 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3067 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3068 for (int i = 0; i < 4; i++) {
3069 colors[i] = get_json_color(jsonColors[i]);
3070 }
3071 colorsPtr = colors;
3072 }
3073 else {
3074 colorsPtr = nullptr;
3075 }
3076 SkPoint* texCoordsPtr;
3077 SkPoint texCoords[4];
3078 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3079 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3080 for (int i = 0; i < 4; i++) {
3081 texCoords[i] = get_json_point(jsonTexCoords[i]);
3082 }
3083 texCoordsPtr = texCoords;
3084 }
3085 else {
3086 texCoordsPtr = nullptr;
3087 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003088
3089 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3090
ethannicholas1446a9a2016-02-10 14:05:02 -08003091 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003092 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04003093 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
robertphillips9bafc302015-02-13 11:13:00 -08003094}
3095
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003096SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003097 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003098 fRect = rect;
3099 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003100
robertphillips@google.com91217d02013-03-17 18:33:46 +00003101 fInfo.push(SkObjectParser::RectToString(rect));
3102 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003103}
3104
fmalita8c89c522014-11-08 16:18:56 -08003105void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003106 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003107}
3108
ethannicholasf62a8b72016-02-11 10:35:21 -08003109Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3110 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07003111 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3112 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07003113
3114 SkString desc;
3115 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3116
ethannicholas50a8dd02016-02-10 05:40:46 -08003117 return result;
3118}
3119
halcanary9d524f22016-03-29 09:03:52 -07003120SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003121 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003122 SkRect coords;
3123 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3124 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003125 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003126 return new SkDrawRectCommand(coords, paint);
3127}
3128
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003129SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003130 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003131 fRRect = rrect;
3132 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00003133
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003134 fInfo.push(SkObjectParser::RRectToString(rrect));
3135 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00003136}
3137
fmalita8c89c522014-11-08 16:18:56 -08003138void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00003139 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00003140}
3141
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003142bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00003143 render_rrect(canvas, fRRect);
3144 return true;
3145}
3146
ethannicholasf62a8b72016-02-11 10:35:21 -08003147Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3148 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003149 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07003150 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003151 return result;
3152}
3153
halcanary9d524f22016-03-29 09:03:52 -07003154SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003155 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003156 SkRRect coords;
3157 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3158 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003159 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003160 return new SkDrawRRectCommand(coords, paint);
3161}
3162
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00003163SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003164 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003165 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003166 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003167 fOuter = outer;
3168 fInner = inner;
3169 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003170
3171 fInfo.push(SkObjectParser::RRectToString(outer));
3172 fInfo.push(SkObjectParser::RRectToString(inner));
3173 fInfo.push(SkObjectParser::PaintToString(paint));
3174}
3175
fmalita8c89c522014-11-08 16:18:56 -08003176void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003177 canvas->drawDRRect(fOuter, fInner, fPaint);
3178}
3179
3180bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3181 render_drrect(canvas, fOuter, fInner);
3182 return true;
3183}
3184
ethannicholasf62a8b72016-02-11 10:35:21 -08003185Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3186 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003187 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3188 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07003189 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003190 return result;
3191}
3192
halcanary9d524f22016-03-29 09:03:52 -07003193SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003194 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003195 SkRRect outer;
3196 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3197 SkRRect inner;
3198 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3199 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003200 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003201 return new SkDrawDRRectCommand(outer, inner, paint);
3202}
3203
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003204SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003205 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003206 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003207 fText = new char[byteLength];
3208 memcpy(fText, text, byteLength);
3209 fByteLength = byteLength;
3210 fX = x;
3211 fY = y;
3212 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003213
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003214 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3215 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
3216 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
3217 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003218}
3219
fmalita8c89c522014-11-08 16:18:56 -08003220void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003221 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003222}
3223
ethannicholasf62a8b72016-02-11 10:35:21 -08003224Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3225 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003226 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003227 ((const char*) fText) + fByteLength);
3228 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003229 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3230 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003231 return result;
3232}
3233
halcanary9d524f22016-03-29 09:03:52 -07003234SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003235 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003236 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3237 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003238 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003239 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
halcanary9d524f22016-03-29 09:03:52 -07003240 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08003241 paint);
3242}
3243
reed45561a02016-07-07 12:47:17 -07003244///////////////////////////////////////////////////////////////////////////////////////////////////
3245
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003246SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3247 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003248 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003249 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003250 fText = new char[byteLength];
3251 memcpy(fText, text, byteLength);
3252 fByteLength = byteLength;
3253 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07003254 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003255 fMatrix = *matrix;
3256 } else {
3257 fMatrix.setIdentity();
3258 }
3259 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003260
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003261 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3262 fInfo.push(SkObjectParser::PathToString(path));
bsalomon49f085d2014-09-05 13:34:00 -07003263 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003264 fInfo.push(SkObjectParser::MatrixToString(*matrix));
3265 }
3266 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003267}
3268
fmalita8c89c522014-11-08 16:18:56 -08003269void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003270 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07003271 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003272 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003273}
3274
ethannicholasf62a8b72016-02-11 10:35:21 -08003275Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3276 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003277 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003278 ((const char*) fText) + fByteLength);
3279 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003280 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08003281 if (!fMatrix.isIdentity()) {
joshualittbd724132016-03-03 11:39:38 -08003282 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003283 }
brianosmanfad98562016-05-04 11:06:28 -07003284 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003285 return result;
3286}
3287
halcanary9d524f22016-03-29 09:03:52 -07003288SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003289 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003290 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3291 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003292 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003293 SkPath path;
3294 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3295 SkMatrix* matrixPtr;
3296 SkMatrix matrix;
3297 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3298 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3299 matrixPtr = &matrix;
3300 }
3301 else {
3302 matrixPtr = nullptr;
3303 }
3304 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3305}
3306
reed45561a02016-07-07 12:47:17 -07003307///////////////////////////////////////////////////////////////////////////////////////////////////
3308
3309SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3310 const SkRSXform xform[], const SkRect* cull,
3311 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07003312 : INHERITED(kDrawTextRSXform_OpType)
reed45561a02016-07-07 12:47:17 -07003313{
3314 fText = new char[byteLength];
3315 memcpy(fText, text, byteLength);
3316 fByteLength = byteLength;
3317 int count = paint.countText(text, byteLength);
3318 fXform = new SkRSXform[count];
3319 memcpy(fXform, xform, count * sizeof(SkRSXform));
3320 if (cull) {
3321 fCullStorage = *cull;
3322 fCull = &fCullStorage;
3323 } else {
3324 fCull = nullptr;
3325 }
3326 fPaint = paint;
3327
3328 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3329 fInfo.push(SkObjectParser::PaintToString(paint));
3330}
3331
3332void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3333 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3334}
3335
3336Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3337 Json::Value result = INHERITED::toJSON(urlDataManager);
3338 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3339 ((const char*) fText) + fByteLength);
3340 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3341 return result;
3342}
3343
3344SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3345 UrlDataManager& urlDataManager) {
3346 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3347 size_t byteLength = strlen(text);
3348 SkPaint paint;
3349 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3350
3351 // TODO: handle xform and cull
3352 int count = paint.countText(text, byteLength);
3353 SkAutoTArray<SkRSXform> xform(count);
3354 for (int i = 0; i < count; ++i) {
3355 xform[i].fSCos = 1;
3356 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3357 }
3358 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3359}
3360
3361///////////////////////////////////////////////////////////////////////////////////////////////////
3362
Mike Reedfed9cfd2017-03-17 12:09:04 -04003363SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003364 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003365 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003366 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04003367 , fBlendMode(bmode)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003368 , fPaint(paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003369{
chudy@google.com902ebe52012-06-29 14:21:22 +00003370 // TODO(chudy)
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003371 fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
3372 fInfo.push(SkObjectParser::PaintToString(paint));
3373}
3374
fmalita8c89c522014-11-08 16:18:56 -08003375void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04003376 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003377}
3378
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003379SkRestoreCommand::SkRestoreCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003380 : INHERITED(kRestore_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003381 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
chudy@google.com902ebe52012-06-29 14:21:22 +00003382}
3383
fmalita8c89c522014-11-08 16:18:56 -08003384void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00003385 canvas->restore();
3386}
3387
ethannicholasf62a8b72016-02-11 10:35:21 -08003388SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003389 return new SkRestoreCommand();
3390}
3391
Florin Malita5f6102d2014-06-30 10:13:28 -04003392SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003393 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00003394}
3395
fmalita8c89c522014-11-08 16:18:56 -08003396void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04003397 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00003398}
3399
ethannicholasf62a8b72016-02-11 10:35:21 -08003400SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003401 return new SkSaveCommand();
3402}
3403
reed4960eee2015-12-18 07:09:18 -08003404SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08003405 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08003406 if (rec.fBounds) {
3407 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003408 } else {
3409 fBounds.setEmpty();
3410 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003411
reed4960eee2015-12-18 07:09:18 -08003412 if (rec.fPaint) {
3413 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003414 fPaintPtr = &fPaint;
3415 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07003416 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003417 }
reed4960eee2015-12-18 07:09:18 -08003418 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003419
ethannicholas50a8dd02016-02-10 05:40:46 -08003420 if (rec.fBackdrop) {
3421 fBackdrop = rec.fBackdrop;
3422 fBackdrop->ref();
3423 } else {
3424 fBackdrop = nullptr;
3425 }
3426
reed4960eee2015-12-18 07:09:18 -08003427 if (rec.fBounds) {
3428 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003429 }
reed4960eee2015-12-18 07:09:18 -08003430 if (rec.fPaint) {
3431 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003432 }
reed4960eee2015-12-18 07:09:18 -08003433 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003434}
3435
ethannicholas50a8dd02016-02-10 05:40:46 -08003436SkSaveLayerCommand::~SkSaveLayerCommand() {
3437 if (fBackdrop != nullptr) {
3438 fBackdrop->unref();
3439 }
3440}
3441
fmalita8c89c522014-11-08 16:18:56 -08003442void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08003443 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3444 fPaintPtr,
3445 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003446}
3447
fmalita8c89c522014-11-08 16:18:56 -08003448void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
commit-bot@chromium.org1643b2c2014-03-03 23:25:41 +00003449 canvas->save();
3450}
3451
ethannicholasf62a8b72016-02-11 10:35:21 -08003452Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3453 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003454 if (!fBounds.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07003455 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003456 }
3457 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07003458 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
ethannicholasf62a8b72016-02-11 10:35:21 -08003459 urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003460 }
3461 if (fBackdrop != nullptr) {
3462 Json::Value jsonBackdrop;
ethannicholasf62a8b72016-02-11 10:35:21 -08003463 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003464 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3465 }
3466 if (fSaveLayerFlags != 0) {
3467 SkDebugf("unsupported: saveLayer flags\n");
3468 SkASSERT(false);
3469 }
3470 return result;
3471}
3472
halcanary9d524f22016-03-29 09:03:52 -07003473SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003474 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003475 SkCanvas::SaveLayerRec rec;
3476 SkRect bounds;
3477 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3478 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3479 rec.fBounds = &bounds;
3480 }
3481 SkPaint paint;
3482 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08003483 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003484 rec.fPaint = &paint;
3485 }
3486 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3487 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
ethannicholasf62a8b72016-02-11 10:35:21 -08003488 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003489 }
3490 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3491 if (rec.fBackdrop != nullptr) {
3492 rec.fBackdrop->unref();
3493 }
3494 return result;
3495}
3496
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003497SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08003498 : INHERITED(kSetMatrix_OpType) {
robertphillips70171682014-10-16 14:28:28 -07003499 fUserMatrix.reset();
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003500 fMatrix = matrix;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003501 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00003502}
3503
robertphillips70171682014-10-16 14:28:28 -07003504void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
3505 fUserMatrix = userMatrix;
3506}
3507
fmalita8c89c522014-11-08 16:18:56 -08003508void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
robertphillips70171682014-10-16 14:28:28 -07003509 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
3510 canvas->setMatrix(temp);
chudy@google.com902ebe52012-06-29 14:21:22 +00003511}
3512
ethannicholasf62a8b72016-02-11 10:35:21 -08003513Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3514 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08003515 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003516 return result;
3517}
3518
halcanary9d524f22016-03-29 09:03:52 -07003519SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003520 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003521 SkMatrix matrix;
3522 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3523 return new SkSetMatrixCommand(matrix);
3524}