blob: 7138596adccb28cbc9b9a9a88a5550f1fe293337 [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"
Mike Reed80747ef2018-01-23 15:29:32 -050018#include "SkMaskFilterBase.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"
Mike Reedfadbfcd2017-12-06 16:09:20 -050023#include "SkReadBuffer.h"
Mike Reed185ffe92018-01-08 17:09:54 -050024#include "SkRectPriv.h"
fmalitab7425172014-08-26 07:56:44 -070025#include "SkTextBlob.h"
fmalitae77f2da2015-12-08 18:59:18 -080026#include "SkTextBlobRunIterator.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080027#include "SkTHash.h"
28#include "SkTypeface.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080029#include "SkWriteBuffer.h"
msaretta5cf4f42016-06-30 10:06:51 -070030#include "picture_utils.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050031#include "SkClipOpPriv.h"
Stan Ilievac42aeb2017-01-12 16:20:50 -050032#include <SkLatticeIter.h>
ethannicholas50a8dd02016-02-10 05:40:46 -080033
ethannicholas50a8dd02016-02-10 05:40:46 -080034#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
ethannicholas807dcab2016-02-23 06:53:37 -080035#define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
ethannicholas50a8dd02016-02-10 05:40:46 -080036#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
vjiaoblacke5de1302016-07-13 14:05:28 -070037#define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
ethannicholas50a8dd02016-02-10 05:40:46 -080038#define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
halcanaryf412f092016-08-25 11:10:41 -070039#define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
ethannicholas50a8dd02016-02-10 05:40:46 -080040#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
41#define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
42#define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
43#define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
44#define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
45#define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
46#define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
47#define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
48#define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
49#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Florin Malita82d80872017-06-06 16:58:40 -040050#define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
ethannicholas50a8dd02016-02-10 05:40:46 -080051#define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
52#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
53#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
ethannicholas1446a9a2016-02-10 14:05:02 -080054#define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
ethannicholas50a8dd02016-02-10 05:40:46 -080055#define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
56#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
ethannicholas1446a9a2016-02-10 14:05:02 -080057#define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
Ben Wagner78f1f5a2017-06-23 14:35:07 -040058#define SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
59#define SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
60#define SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
61#define SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
62#define SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
63#define SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
64#define SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
65#define SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT "verticalText"
ethannicholas50a8dd02016-02-10 05:40:46 -080066#define SKDEBUGCANVAS_ATTRIBUTE_REGION "region"
67#define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
68#define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
69#define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
70#define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur"
71#define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
72#define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
73#define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign"
74#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
75#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
76#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
77#define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
78#define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
79#define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
80#define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
81#define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
82#define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
ethannicholasf62a8b72016-02-11 10:35:21 -080083#define SKDEBUGCANVAS_ATTRIBUTE_DATA "data"
brianosmanfad98562016-05-04 11:06:28 -070084#define SKDEBUGCANVAS_ATTRIBUTE_VALUES "values"
ethannicholas50a8dd02016-02-10 05:40:46 -080085#define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
86#define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
87#define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
88#define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
ethannicholas1446a9a2016-02-10 14:05:02 -080089#define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
ethannicholas50a8dd02016-02-10 05:40:46 -080090#define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
91#define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
92#define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
93#define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
94#define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
95#define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
96#define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
97#define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
98#define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
99#define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
100#define SKDEBUGCANVAS_ATTRIBUTE_X "x"
101#define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
102#define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
103#define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
104#define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
105#define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
106#define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
ethannicholas1446a9a2016-02-10 14:05:02 -0800107#define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
108#define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors"
109#define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
110#define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
bsalomonac3aa242016-08-19 11:25:19 -0700111#define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
112#define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
113#define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
jcgregorioee0c5552016-06-30 09:18:27 -0700114#define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
msarett0ac1bec2016-08-29 09:15:33 -0700115#define SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
116#define SKDEBUGCANVAS_ATTRIBUTE_WIDTH "width"
117#define SKDEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
118#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Stan Ilievac42aeb2017-01-12 16:20:50 -0500119#define SKDEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
120#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
121#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
122#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
123#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
124#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
reed67f62fa2016-06-29 11:36:34 -0700125
ethannicholas50a8dd02016-02-10 05:40:46 -0800126#define SKDEBUGCANVAS_VERB_MOVE "move"
127#define SKDEBUGCANVAS_VERB_LINE "line"
128#define SKDEBUGCANVAS_VERB_QUAD "quad"
129#define SKDEBUGCANVAS_VERB_CUBIC "cubic"
130#define SKDEBUGCANVAS_VERB_CONIC "conic"
131#define SKDEBUGCANVAS_VERB_CLOSE "close"
132
133#define SKDEBUGCANVAS_STYLE_FILL "fill"
134#define SKDEBUGCANVAS_STYLE_STROKE "stroke"
135#define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
136
137#define SKDEBUGCANVAS_POINTMODE_POINTS "points"
138#define SKDEBUGCANVAS_POINTMODE_LINES "lines"
139#define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
140
141#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
142#define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
143#define SKDEBUGCANVAS_REGIONOP_UNION "union"
144#define SKDEBUGCANVAS_REGIONOP_XOR "xor"
145#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
146#define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
147
148#define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
149#define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
150#define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
151#define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
152
153#define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
154#define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
155
156#define SKDEBUGCANVAS_ALIGN_LEFT "left"
157#define SKDEBUGCANVAS_ALIGN_CENTER "center"
158#define SKDEBUGCANVAS_ALIGN_RIGHT "right"
159
160#define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
161#define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
162#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
163#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
164
165#define SKDEBUGCANVAS_CAP_BUTT "butt"
166#define SKDEBUGCANVAS_CAP_ROUND "round"
167#define SKDEBUGCANVAS_CAP_SQUARE "square"
168
ethannicholas1446a9a2016-02-10 14:05:02 -0800169#define SKDEBUGCANVAS_MITER_JOIN "miter"
170#define SKDEBUGCANVAS_ROUND_JOIN "round"
171#define SKDEBUGCANVAS_BEVEL_JOIN "bevel"
172
ethannicholas50a8dd02016-02-10 05:40:46 -0800173#define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
174#define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
175#define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
176#define SKDEBUGCANVAS_COLORTYPE_565 "565"
177#define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
178#define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
179#define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
180
181#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
182#define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
183#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
msarett0ac1bec2016-08-29 09:15:33 -0700184#define SKDEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
ethannicholas50a8dd02016-02-10 05:40:46 -0800185
ethannicholas1446a9a2016-02-10 14:05:02 -0800186#define SKDEBUGCANVAS_FILTERQUALITY_NONE "none"
187#define SKDEBUGCANVAS_FILTERQUALITY_LOW "low"
188#define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
189#define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high"
190
halcanaryf412f092016-08-25 11:10:41 -0700191#define SKDEBUGCANVAS_HINTING_NONE "none"
192#define SKDEBUGCANVAS_HINTING_SLIGHT "slight"
193#define SKDEBUGCANVAS_HINTING_NORMAL "normal"
194#define SKDEBUGCANVAS_HINTING_FULL "full"
195
ethannicholasf62a8b72016-02-11 10:35:21 -0800196typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&);
fmalitab7425172014-08-26 07:56:44 -0700197
reed67f62fa2016-06-29 11:36:34 -0700198static SkString* str_append(SkString* str, const SkRect& r) {
199 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
200 return str;
201}
202
chudy@google.com902ebe52012-06-29 14:21:22 +0000203// TODO(chudy): Refactor into non subclass model.
204
robertphillips9bafc302015-02-13 11:13:00 -0800205SkDrawCommand::SkDrawCommand(OpType type)
206 : fOpType(type)
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000207 , fVisible(true) {
208}
209
chudy@google.com902ebe52012-06-29 14:21:22 +0000210SkDrawCommand::~SkDrawCommand() {
chudy@google.com97cee972012-08-07 20:41:37 +0000211 fInfo.deleteAll();
chudy@google.com902ebe52012-06-29 14:21:22 +0000212}
213
robertphillips9bafc302015-02-13 11:13:00 -0800214const char* SkDrawCommand::GetCommandString(OpType type) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000215 switch (type) {
fmalita160ebb22015-04-01 20:58:37 -0700216 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
Brian Osmanc25e2692018-03-12 10:57:28 -0400217 case kClear_OpType: return "DrawClear";
robertphillips9bafc302015-02-13 11:13:00 -0800218 case kClipPath_OpType: return "ClipPath";
219 case kClipRegion_OpType: return "ClipRegion";
220 case kClipRect_OpType: return "ClipRect";
221 case kClipRRect_OpType: return "ClipRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800222 case kConcat_OpType: return "Concat";
robertphillipsfb409232016-06-29 10:28:11 -0700223 case kDrawAnnotation_OpType: return "DrawAnnotation";
robertphillips9bafc302015-02-13 11:13:00 -0800224 case kDrawBitmap_OpType: return "DrawBitmap";
225 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
226 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
robertphillips9bafc302015-02-13 11:13:00 -0800227 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700228 case kDrawImage_OpType: return "DrawImage";
Stan Ilievac42aeb2017-01-12 16:20:50 -0500229 case kDrawImageLattice_OpType: return "DrawImageLattice";
Brian Osmanc25e2692018-03-12 10:57:28 -0400230 case kDrawImageNine_OpType: return "DrawImageNine";
fmalita651c9202015-07-22 10:23:01 -0700231 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800232 case kDrawOval_OpType: return "DrawOval";
233 case kDrawPaint_OpType: return "DrawPaint";
234 case kDrawPatch_OpType: return "DrawPatch";
235 case kDrawPath_OpType: return "DrawPath";
Brian Osmanc25e2692018-03-12 10:57:28 -0400236 case kDrawArc_OpType: return "DrawArc";
robertphillips9bafc302015-02-13 11:13:00 -0800237 case kDrawPoints_OpType: return "DrawPoints";
238 case kDrawPosText_OpType: return "DrawPosText";
239 case kDrawPosTextH_OpType: return "DrawPosTextH";
240 case kDrawRect_OpType: return "DrawRect";
241 case kDrawRRect_OpType: return "DrawRRect";
Brian Osmanc25e2692018-03-12 10:57:28 -0400242 case kDrawRegion_OpType: return "DrawRegion";
robertphillips9bafc302015-02-13 11:13:00 -0800243 case kDrawText_OpType: return "DrawText";
244 case kDrawTextBlob_OpType: return "DrawTextBlob";
245 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
reed63f30d92016-07-07 16:32:51 -0700246 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
robertphillips9bafc302015-02-13 11:13:00 -0800247 case kDrawVertices_OpType: return "DrawVertices";
fmalita160ebb22015-04-01 20:58:37 -0700248 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800249 case kRestore_OpType: return "Restore";
250 case kSave_OpType: return "Save";
251 case kSaveLayer_OpType: return "SaveLayer";
252 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000253 default:
robertphillips9bafc302015-02-13 11:13:00 -0800254 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000255 SkASSERT(0);
256 break;
257 }
258 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700259 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000260}
261
fmalita8c89c522014-11-08 16:18:56 -0800262SkString SkDrawCommand::toString() const {
robertphillips9bafc302015-02-13 11:13:00 -0800263 return SkString(GetCommandString(fOpType));
chudy@google.com902ebe52012-06-29 14:21:22 +0000264}
265
ethannicholasf62a8b72016-02-11 10:35:21 -0800266Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800267 Json::Value result;
268 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800269 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800270 return result;
271}
272
273#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
274 (FROM_JSON) Sk ## name ## Command::fromJSON)
ethannicholasf62a8b72016-02-11 10:35:21 -0800275SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800276 static SkTHashMap<SkString, FROM_JSON> factories;
277 static bool initialized = false;
278 if (!initialized) {
279 initialized = true;
280 INSTALL_FACTORY(Restore);
Brian Osmanc25e2692018-03-12 10:57:28 -0400281 INSTALL_FACTORY(Clear);
ethannicholas50a8dd02016-02-10 05:40:46 -0800282 INSTALL_FACTORY(ClipPath);
283 INSTALL_FACTORY(ClipRegion);
284 INSTALL_FACTORY(ClipRect);
285 INSTALL_FACTORY(ClipRRect);
286 INSTALL_FACTORY(Concat);
reed97660cc2016-06-28 18:54:19 -0700287 INSTALL_FACTORY(DrawAnnotation);
ethannicholas50a8dd02016-02-10 05:40:46 -0800288 INSTALL_FACTORY(DrawBitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800289 INSTALL_FACTORY(DrawBitmapNine);
Brian Osmanc25e2692018-03-12 10:57:28 -0400290 INSTALL_FACTORY(DrawBitmapRect);
ethannicholas50a8dd02016-02-10 05:40:46 -0800291 INSTALL_FACTORY(DrawImage);
Brian Osmanc25e2692018-03-12 10:57:28 -0400292 INSTALL_FACTORY(DrawImageLattice);
293 INSTALL_FACTORY(DrawImageNine);
ethannicholas50a8dd02016-02-10 05:40:46 -0800294 INSTALL_FACTORY(DrawImageRect);
295 INSTALL_FACTORY(DrawOval);
Brian Osmanc25e2692018-03-12 10:57:28 -0400296 INSTALL_FACTORY(DrawArc);
ethannicholas50a8dd02016-02-10 05:40:46 -0800297 INSTALL_FACTORY(DrawPaint);
298 INSTALL_FACTORY(DrawPath);
299 INSTALL_FACTORY(DrawPoints);
Brian Osmanc25e2692018-03-12 10:57:28 -0400300 INSTALL_FACTORY(DrawRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -0800301 INSTALL_FACTORY(DrawText);
302 INSTALL_FACTORY(DrawPosText);
bungeman51190df2016-03-09 07:42:54 -0800303 INSTALL_FACTORY(DrawPosTextH);
ethannicholas50a8dd02016-02-10 05:40:46 -0800304 INSTALL_FACTORY(DrawTextOnPath);
reed45561a02016-07-07 12:47:17 -0700305 INSTALL_FACTORY(DrawTextRSXform);
ethannicholas50a8dd02016-02-10 05:40:46 -0800306 INSTALL_FACTORY(DrawTextBlob);
307
308 INSTALL_FACTORY(DrawRect);
309 INSTALL_FACTORY(DrawRRect);
310 INSTALL_FACTORY(DrawDRRect);
ethannicholas1446a9a2016-02-10 14:05:02 -0800311 INSTALL_FACTORY(DrawPatch);
ethannicholas50a8dd02016-02-10 05:40:46 -0800312 INSTALL_FACTORY(Save);
313 INSTALL_FACTORY(SaveLayer);
314 INSTALL_FACTORY(SetMatrix);
315 }
316 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
317 FROM_JSON* factory = factories.find(name);
318 if (factory == nullptr) {
319 SkDebugf("no JSON factory for '%s'\n", name.c_str());
320 return nullptr;
321 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800322 return (*factory)(command, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800323}
324
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000325namespace {
326
327void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500328 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000329
330 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
331
332 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
333 if (bounds.width() > bounds.height()) {
334 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
335 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
336 } else {
337 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
338 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
339 }
340 canvas->translate(-bounds.centerX(), -bounds.centerY());
341}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000342
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000343
344void render_path(SkCanvas* canvas, const SkPath& path) {
345 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000346
347 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700348 if (bounds.isEmpty()) {
349 return;
350 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000351
fmalitab0cd8b72015-10-06 07:24:03 -0700352 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000353 xlate_and_scale_to_bounds(canvas, bounds);
354
355 SkPaint p;
356 p.setColor(SK_ColorBLACK);
357 p.setStyle(SkPaint::kStroke_Style);
358
359 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000360}
361
Brian Osmanc25e2692018-03-12 10:57:28 -0400362void render_region(SkCanvas* canvas, const SkRegion& region) {
363 canvas->clear(0xFFFFFFFF);
364
365 const SkIRect& bounds = region.getBounds();
366 if (bounds.isEmpty()) {
367 return;
368 }
369
370 SkAutoCanvasRestore acr(canvas, true);
371 xlate_and_scale_to_bounds(canvas, SkRect::MakeFromIRect(bounds));
372
373 SkPaint p;
374 p.setColor(SK_ColorBLACK);
375 p.setStyle(SkPaint::kStroke_Style);
376
377 canvas->drawRegion(region, p);
378}
379
halcanary96fcdcc2015-08-27 07:41:13 -0700380void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500381 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000382
383 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
384 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
385
386 if (input.width() > input.height()) {
387 yScale *= input.height() / (float) input.width();
388 } else {
389 xScale *= input.width() / (float) input.height();
390 }
391
392 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
393 xScale * input.width(),
394 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000395
robertphillips96a5cff2015-09-24 06:56:27 -0700396 static const int kNumBlocks = 8;
397
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000398 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700399 SkISize block = {
400 canvas->imageInfo().width()/kNumBlocks,
401 canvas->imageInfo().height()/kNumBlocks
402 };
403 for (int y = 0; y < kNumBlocks; ++y) {
404 for (int x = 0; x < kNumBlocks; ++x) {
405 SkPaint paint;
406 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
407 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
408 SkIntToScalar(y*block.height()),
409 SkIntToScalar(block.width()),
410 SkIntToScalar(block.height()));
411 canvas->drawRect(r, paint);
412 }
413 }
414
reede47829b2015-08-06 10:02:53 -0700415 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000416
bsalomon49f085d2014-09-05 13:34:00 -0700417 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000418 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
419 srcRect->fTop * yScale + SK_Scalar1,
420 srcRect->fRight * xScale + SK_Scalar1,
421 srcRect->fBottom * yScale + SK_Scalar1);
422 SkPaint p;
423 p.setColor(SK_ColorRED);
424 p.setStyle(SkPaint::kStroke_Style);
425
426 canvas->drawRect(r, p);
427 }
428}
429
430void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
431 canvas->clear(0xFFFFFFFF);
432 canvas->save();
433
434 const SkRect& bounds = rrect.getBounds();
435
436 xlate_and_scale_to_bounds(canvas, bounds);
437
438 SkPaint p;
439 p.setColor(SK_ColorBLACK);
440 p.setStyle(SkPaint::kStroke_Style);
441
442 canvas->drawRRect(rrect, p);
443 canvas->restore();
444}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000445
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000446void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
447 canvas->clear(0xFFFFFFFF);
448 canvas->save();
449
450 const SkRect& bounds = outer.getBounds();
451
452 xlate_and_scale_to_bounds(canvas, bounds);
453
454 SkPaint p;
455 p.setColor(SK_ColorBLACK);
456 p.setStyle(SkPaint::kStroke_Style);
457
458 canvas->drawDRRect(outer, inner, p);
459 canvas->restore();
460}
461
Florin Malita82d80872017-06-06 16:58:40 -0400462static const char* const gBlendModeMap[] = {
463 "clear",
464 "src",
465 "dst",
466 "srcOver",
467 "dstOver",
468 "srcIn",
469 "dstIn",
470 "srcOut",
471 "dstOut",
472 "srcATop",
473 "dstATop",
474 "xor",
475 "plus",
476 "modulate",
477
478 "screen",
479
480 "overlay",
481 "darken",
482 "lighten",
483 "colorDodge",
484 "colorBurn",
485 "hardLight",
486 "softLight",
487 "difference",
488 "exclusion",
489 "multiply",
490
491 "hue",
492 "saturation",
493 "color",
494 "luminosity",
495};
496
497static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
498 "blendMode mismatch");
499static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
500 "blendMode mismatch");
501
502void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
503 const auto mode = paint.getBlendMode();
504 if (mode != SkBlendMode::kSrcOver) {
505 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
506 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
507 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
508 }
509}
510
511void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
512 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
513 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
514
515 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
516 if (!strcmp(mode, gBlendModeMap[i])) {
517 target->setBlendMode(static_cast<SkBlendMode>(i));
518 break;
519 }
520 }
521 }
522}
523
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000524};
525
brianosmanfad98562016-05-04 11:06:28 -0700526Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800527 Json::Value result(Json::arrayValue);
528 result.append(Json::Value(SkColorGetA(color)));
529 result.append(Json::Value(SkColorGetR(color)));
530 result.append(Json::Value(SkColorGetG(color)));
531 result.append(Json::Value(SkColorGetB(color)));
532 return result;
533}
534
brianosman97bbf822016-09-25 13:15:58 -0700535Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
536 Json::Value result(Json::arrayValue);
537 result.append(Json::Value(color.fA));
538 result.append(Json::Value(color.fR));
539 result.append(Json::Value(color.fG));
540 result.append(Json::Value(color.fB));
541 return result;
542}
543
brianosmanfad98562016-05-04 11:06:28 -0700544Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800545 Json::Value result(Json::arrayValue);
546 result.append(Json::Value(point.x()));
547 result.append(Json::Value(point.y()));
548 return result;
549}
550
brianosmanfad98562016-05-04 11:06:28 -0700551Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800552 Json::Value result(Json::arrayValue);
553 result.append(Json::Value(x));
554 result.append(Json::Value(y));
555 return result;
556}
557
brianosmanfad98562016-05-04 11:06:28 -0700558Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800559 Json::Value result(Json::arrayValue);
560 result.append(Json::Value(rect.left()));
561 result.append(Json::Value(rect.top()));
562 result.append(Json::Value(rect.right()));
563 result.append(Json::Value(rect.bottom()));
564 return result;
565}
566
joshualittbd724132016-03-03 11:39:38 -0800567Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800568 Json::Value result(Json::arrayValue);
569 result.append(Json::Value(rect.left()));
570 result.append(Json::Value(rect.top()));
571 result.append(Json::Value(rect.right()));
572 result.append(Json::Value(rect.bottom()));
573 return result;
574}
575
576static Json::Value make_json_rrect(const SkRRect& rrect) {
577 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700578 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
579 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
580 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
581 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
582 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800583 return result;
584}
585
joshualittbd724132016-03-03 11:39:38 -0800586Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800587 Json::Value result(Json::arrayValue);
588 Json::Value row1(Json::arrayValue);
589 row1.append(Json::Value(matrix[0]));
590 row1.append(Json::Value(matrix[1]));
591 row1.append(Json::Value(matrix[2]));
592 result.append(row1);
593 Json::Value row2(Json::arrayValue);
594 row2.append(Json::Value(matrix[3]));
595 row2.append(Json::Value(matrix[4]));
596 row2.append(Json::Value(matrix[5]));
597 result.append(row2);
598 Json::Value row3(Json::arrayValue);
599 row3.append(Json::Value(matrix[6]));
600 row3.append(Json::Value(matrix[7]));
601 row3.append(Json::Value(matrix[8]));
602 result.append(row3);
603 return result;
604}
ethannicholas1446a9a2016-02-10 14:05:02 -0800605
vjiaoblacke5de1302016-07-13 14:05:28 -0700606Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
607 Json::Value result(z);
608 return result;
609}
610
brianosmanfad98562016-05-04 11:06:28 -0700611Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800612 Json::Value result(Json::objectValue);
613 switch (path.getFillType()) {
614 case SkPath::kWinding_FillType:
615 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
616 break;
617 case SkPath::kEvenOdd_FillType:
618 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
619 break;
620 case SkPath::kInverseWinding_FillType:
621 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
622 break;
623 case SkPath::kInverseEvenOdd_FillType:
624 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
625 break;
halcanary9d524f22016-03-29 09:03:52 -0700626 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800627 Json::Value verbs(Json::arrayValue);
628 SkPath::Iter iter(path, false);
629 SkPoint pts[4];
630 SkPath::Verb verb;
631 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
632 switch (verb) {
633 case SkPath::kLine_Verb: {
634 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700635 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800636 verbs.append(line);
637 break;
638 }
639 case SkPath::kQuad_Verb: {
640 Json::Value quad(Json::objectValue);
641 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700642 coords.append(MakeJsonPoint(pts[1]));
643 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800644 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
645 verbs.append(quad);
646 break;
647 }
648 case SkPath::kCubic_Verb: {
649 Json::Value cubic(Json::objectValue);
650 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700651 coords.append(MakeJsonPoint(pts[1]));
652 coords.append(MakeJsonPoint(pts[2]));
653 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800654 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
655 verbs.append(cubic);
656 break;
657 }
658 case SkPath::kConic_Verb: {
659 Json::Value conic(Json::objectValue);
660 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700661 coords.append(MakeJsonPoint(pts[1]));
662 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800663 coords.append(Json::Value(iter.conicWeight()));
664 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
665 verbs.append(conic);
666 break;
667 }
668 case SkPath::kMove_Verb: {
669 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700670 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800671 verbs.append(move);
672 break;
673 }
674 case SkPath::kClose_Verb:
675 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
676 break;
677 case SkPath::kDone_Verb:
678 break;
679 }
680 }
681 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
682 return result;
683}
684
brianosmanfad98562016-05-04 11:06:28 -0700685Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
Brian Osmanc25e2692018-03-12 10:57:28 -0400686 // TODO: Actually serialize the rectangles, rather than just devolving to path
687 SkPath path;
688 region.getBoundaryPath(&path);
689 return MakeJsonPath(path);
ethannicholas50a8dd02016-02-10 05:40:46 -0800690}
691
Mike Reedc1f77742016-12-09 09:00:50 -0500692static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800693 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500694 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800695 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500696 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800697 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500698 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800699 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500700 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800701 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500702 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800703 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500704 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800705 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
706 default:
707 SkASSERT(false);
708 return Json::Value("<invalid region op>");
709 };
710}
711
712static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
713 switch (mode) {
714 case SkCanvas::kPoints_PointMode:
715 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
716 case SkCanvas::kLines_PointMode:
717 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700718 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800719 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
720 default:
721 SkASSERT(false);
722 return Json::Value("<invalid point mode>");
723 };
724}
725
halcanary9d524f22016-03-29 09:03:52 -0700726static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800727 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800728 if (value != defaultValue) {
729 (*target)[key] = Json::Value(value);
730 }
731}
732
ethannicholasbd3dae82016-02-10 12:10:00 -0800733static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800734 if (value != defaultValue) {
735 (*target)[key] = Json::Value(value);
736 }
737}
738
halcanary9d524f22016-03-29 09:03:52 -0700739static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800740 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700741 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
742 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800743 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800744}
745
brianosmanfad98562016-05-04 11:06:28 -0700746void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
747 UrlDataManager& urlDataManager) {
748 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800749 flattenable->flatten(buffer);
750 void* data = sk_malloc_throw(buffer.bytesWritten());
751 buffer.writeToMemory(data);
752 Json::Value jsonData;
753 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
754 Json::Value jsonFlattenable;
755 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
756 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700757
758 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
759 flattenable->flatten(jsonBuffer);
760 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
761
ethannicholasf62a8b72016-02-11 10:35:21 -0800762 (*target) = jsonFlattenable;
763 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800764}
765
ethannicholasf67531f2016-03-21 10:19:39 -0700766static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
767 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
768 out->write(data, length);
769}
770
halcanarya73d76a2016-10-17 13:19:02 -0700771void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700772 SkWStream& out, bool isOpaque) {
Ben Wagnera93a14a2017-08-28 10:34:05 -0400773 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700774 SkASSERT(png != nullptr);
775 png_infop info_ptr = png_create_info_struct(png);
776 SkASSERT(info_ptr != nullptr);
777 if (setjmp(png_jmpbuf(png))) {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400778 SK_ABORT("png encode error");
ethannicholasf67531f2016-03-21 10:19:39 -0700779 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400780 png_set_write_fn(png, &out, write_png_callback, nullptr);
msaretta5cf4f42016-06-30 10:06:51 -0700781 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
782 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700783 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
784 png_set_compression_level(png, 1);
785 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700786 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700787 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700788 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700789 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700790 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700791 rows[y][x * 4] = src[x * 4];
792 rows[y][x * 4 + 1] = src[x * 4 + 1];
793 rows[y][x * 4 + 2] = src[x * 4 + 2];
794 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700795 }
796 }
msaretta5cf4f42016-06-30 10:06:51 -0700797 png_write_info(png, info_ptr);
798 if (isOpaque) {
799 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
800 }
ethannicholasf67531f2016-03-21 10:19:39 -0700801 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700802 png_write_image(png, &rows[0]);
Ben Wagnera93a14a2017-08-28 10:34:05 -0400803 png_destroy_write_struct(&png, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700804 sk_free(rows);
805 sk_free(pixels);
806}
807
brianosmanfad98562016-05-04 11:06:28 -0700808bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
809 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700810 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500811 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700812 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700813 kN32_SkColorType, kPremul_SkAlphaType);
814 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
815 SkDebugf("readPixels failed\n");
816 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800817 }
msaretta5cf4f42016-06-30 10:06:51 -0700818
819 SkBitmap bm;
820 bm.installPixels(dstInfo, buffer.get(), rowBytes);
821 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
822
ethannicholasf67531f2016-03-21 10:19:39 -0700823 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700824 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700825 out, false);
reed42943c82016-09-12 12:01:44 -0700826 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800827 Json::Value jsonData;
828 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
829 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800830 return true;
831}
832
833static const char* color_type_name(SkColorType colorType) {
834 switch (colorType) {
835 case kARGB_4444_SkColorType:
836 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
837 case kRGBA_8888_SkColorType:
838 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
839 case kBGRA_8888_SkColorType:
840 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
841 case kRGB_565_SkColorType:
842 return SKDEBUGCANVAS_COLORTYPE_565;
843 case kGray_8_SkColorType:
844 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
ethannicholas50a8dd02016-02-10 05:40:46 -0800845 case kAlpha_8_SkColorType:
846 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
847 default:
848 SkASSERT(false);
849 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
850 }
851}
852
853static const char* alpha_type_name(SkAlphaType alphaType) {
854 switch (alphaType) {
855 case kOpaque_SkAlphaType:
856 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
857 case kPremul_SkAlphaType:
858 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
859 case kUnpremul_SkAlphaType:
860 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
861 default:
862 SkASSERT(false);
863 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
864 }
865}
866
halcanary9d524f22016-03-29 09:03:52 -0700867static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -0800868 const void** target) {
869 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
870 if (urlData == nullptr) {
871 SkASSERT(false);
872 *target = nullptr;
873 return 0;
ethannicholas50a8dd02016-02-10 05:40:46 -0800874 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800875 *target = urlData->fData->data();
876 // cast should be safe for any reasonably-sized object...
877 return (Json::ArrayIndex) urlData->fData->size();
ethannicholas50a8dd02016-02-10 05:40:46 -0800878}
879
halcanary9d524f22016-03-29 09:03:52 -0700880static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
ethannicholasf62a8b72016-02-11 10:35:21 -0800881 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800882 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
883 return nullptr;
884 }
885 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
886 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
887 if (factory == nullptr) {
888 SkDebugf("no factory for loading '%s'\n", name);
889 return nullptr;
890 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800891 const void* data;
892 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
Mike Reedfadbfcd2017-12-06 16:09:20 -0500893 SkReadBuffer buffer(data, size);
reed60c9b582016-04-03 09:11:13 -0700894 sk_sp<SkFlattenable> result = factory(buffer);
ethannicholas50a8dd02016-02-10 05:40:46 -0800895 if (!buffer.isValid()) {
896 SkDebugf("invalid buffer loading flattenable\n");
897 return nullptr;
898 }
reed60c9b582016-04-03 09:11:13 -0700899 return result.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800900}
901
902static SkColorType colortype_from_name(const char* name) {
903 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
904 return kARGB_4444_SkColorType;
905 }
906 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
907 return kRGBA_8888_SkColorType;
908 }
909 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
910 return kBGRA_8888_SkColorType;
911 }
912 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
913 return kRGB_565_SkColorType;
914 }
915 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
916 return kGray_8_SkColorType;
917 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800918 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
919 return kAlpha_8_SkColorType;
920 }
921 SkASSERT(false);
922 return kN32_SkColorType;
923}
924
925static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
926 if (bitmap->colorType() == colorType ) {
927 return bitmap;
928 }
929 SkBitmap* dst = new SkBitmap();
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400930 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
931 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
932 {
ethannicholas50a8dd02016-02-10 05:40:46 -0800933 delete bitmap;
934 return dst;
935 }
936 SkASSERT(false);
937 delete dst;
938 return bitmap;
939}
940
941// caller is responsible for freeing return value
ethannicholasf62a8b72016-02-11 10:35:21 -0800942static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
943 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800944 SkDebugf("invalid bitmap\n");
945 return nullptr;
946 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800947 const void* data;
948 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
bungeman38d909e2016-08-02 14:40:46 -0700949 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
reed9ce9d672016-03-17 10:51:11 -0700950 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
msarett790f99a2016-03-09 06:16:55 -0800951
Ben Wagner145dbcd2016-11-03 14:40:50 -0400952 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
msarett790f99a2016-03-09 06:16:55 -0800953 if (nullptr != image) {
Cary Clark4f5a79c2018-02-07 15:51:00 -0500954 if (!image->asLegacyBitmap(bitmap.get())) {
msarett790f99a2016-03-09 06:16:55 -0800955 SkDebugf("image decode failed\n");
956 return nullptr;
957 }
958
ethannicholas50a8dd02016-02-10 05:40:46 -0800959 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
960 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
961 SkColorType ct = colortype_from_name(ctName);
Mike Reed304a07c2017-07-12 15:10:28 -0400962 bitmap.reset(convert_colortype(bitmap.release(), ct));
ethannicholas50a8dd02016-02-10 05:40:46 -0800963 }
mtklein18300a32016-03-16 13:53:35 -0700964 return bitmap.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800965 }
966 SkDebugf("image decode failed\n");
ethannicholas50a8dd02016-02-10 05:40:46 -0800967 return nullptr;
968}
969
reed9ce9d672016-03-17 10:51:11 -0700970static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
ethannicholasf62a8b72016-02-11 10:35:21 -0800971 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800972 if (bitmap == nullptr) {
973 return nullptr;
974 }
reed9ce9d672016-03-17 10:51:11 -0700975 auto result = SkImage::MakeFromBitmap(*bitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800976 delete bitmap;
977 return result;
978}
979
brianosmanfad98562016-05-04 11:06:28 -0700980bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
981 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -0700982 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -0800983 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
984 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -0800985 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800986 return success;
987}
988
halcanaryf412f092016-08-25 11:10:41 -0700989static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
990 SkPaint::Hinting hinting = paint.getHinting();
991 if (hinting != SkPaintDefaults_Hinting) {
992 switch (hinting) {
993 case SkPaint::kNo_Hinting:
994 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
995 break;
996 case SkPaint::kSlight_Hinting:
997 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
998 break;
999 case SkPaint::kNormal_Hinting:
1000 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
1001 break;
1002 case SkPaint::kFull_Hinting:
1003 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
1004 break;
1005 }
1006 }
1007}
1008
ethannicholas50a8dd02016-02-10 05:40:46 -08001009static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
1010 SkColor color = paint.getColor();
1011 if (color != SK_ColorBLACK) {
1012 Json::Value colorValue(Json::arrayValue);
1013 colorValue.append(Json::Value(SkColorGetA(color)));
1014 colorValue.append(Json::Value(SkColorGetR(color)));
1015 colorValue.append(Json::Value(SkColorGetG(color)));
1016 colorValue.append(Json::Value(SkColorGetB(color)));
1017 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
1018 }
1019}
1020
1021static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
1022 SkPaint::Style style = paint.getStyle();
1023 if (style != SkPaint::kFill_Style) {
1024 switch (style) {
1025 case SkPaint::kStroke_Style: {
1026 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
1027 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
1028 break;
1029 }
1030 case SkPaint::kStrokeAndFill_Style: {
1031 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1032 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1033 break;
1034 }
1035 default: SkASSERT(false);
1036 }
1037 }
1038}
1039
1040static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1041 SkPaint::Cap cap = paint.getStrokeCap();
1042 if (cap != SkPaint::kDefault_Cap) {
1043 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001044 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001045 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1046 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001047 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001048 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1049 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001050 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001051 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1052 break;
ethannicholas50a8dd02016-02-10 05:40:46 -08001053 default: SkASSERT(false);
1054 }
1055 }
1056}
ethannicholas1446a9a2016-02-10 14:05:02 -08001057
1058static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1059 SkPaint::Join join = paint.getStrokeJoin();
1060 if (join != SkPaint::kDefault_Join) {
1061 switch (join) {
1062 case SkPaint::kMiter_Join:
1063 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1064 SKDEBUGCANVAS_MITER_JOIN);
1065 break;
1066 case SkPaint::kRound_Join:
1067 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1068 SKDEBUGCANVAS_ROUND_JOIN);
1069 break;
1070 case SkPaint::kBevel_Join:
1071 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1072 SKDEBUGCANVAS_BEVEL_JOIN);
1073 break;
1074 default: SkASSERT(false);
1075 }
1076 }
1077}
1078
1079static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1080 SkFilterQuality quality = paint.getFilterQuality();
1081 switch (quality) {
1082 case kNone_SkFilterQuality:
1083 break;
1084 case kLow_SkFilterQuality:
1085 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1086 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1087 break;
1088 case kMedium_SkFilterQuality:
1089 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1090 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1091 break;
1092 case kHigh_SkFilterQuality:
1093 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1094 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1095 break;
1096 }
1097}
1098
halcanary9d524f22016-03-29 09:03:52 -07001099static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001100 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001101 SkMaskFilter* maskFilter = paint.getMaskFilter();
1102 if (maskFilter != nullptr) {
Mike Reed80747ef2018-01-23 15:29:32 -05001103 SkMaskFilterBase::BlurRec blurRec;
1104 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001105 Json::Value blur(Json::objectValue);
1106 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1107 switch (blurRec.fStyle) {
1108 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001109 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1110 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -08001111 break;
1112 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001113 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1114 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -08001115 break;
1116 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001117 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1118 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001119 break;
1120 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001121 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1122 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001123 break;
1124 default:
1125 SkASSERT(false);
1126 }
1127 switch (blurRec.fQuality) {
1128 case SkBlurQuality::kLow_SkBlurQuality:
ethannicholas1446a9a2016-02-10 14:05:02 -08001129 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
1130 SKDEBUGCANVAS_BLURQUALITY_LOW);
ethannicholas50a8dd02016-02-10 05:40:46 -08001131 break;
1132 case SkBlurQuality::kHigh_SkBlurQuality:
ethannicholas1446a9a2016-02-10 14:05:02 -08001133 blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY] = Json::Value(
1134 SKDEBUGCANVAS_BLURQUALITY_HIGH);
ethannicholas50a8dd02016-02-10 05:40:46 -08001135 break;
1136 default:
1137 SkASSERT(false);
1138 }
1139 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1140 } else {
1141 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -07001142 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001143 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1144 }
1145 }
1146}
1147
halcanary9d524f22016-03-29 09:03:52 -07001148static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001149 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001150 SkPathEffect* pathEffect = paint.getPathEffect();
1151 if (pathEffect != nullptr) {
1152 SkPathEffect::DashInfo dashInfo;
1153 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1154 if (dashType == SkPathEffect::kDash_DashType) {
1155 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1156 pathEffect->asADash(&dashInfo);
1157 Json::Value dashing(Json::objectValue);
1158 Json::Value intervals(Json::arrayValue);
1159 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1160 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1161 }
1162 sk_free(dashInfo.fIntervals);
1163 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1164 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1165 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1166 } else {
1167 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001168 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001169 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1170 }
1171 }
1172}
halcanary9d524f22016-03-29 09:03:52 -07001173
ethannicholas50a8dd02016-02-10 05:40:46 -08001174static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1175 SkPaint::Align textAlign = paint.getTextAlign();
1176 if (textAlign != SkPaint::kLeft_Align) {
1177 switch (textAlign) {
1178 case SkPaint::kCenter_Align: {
1179 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1180 break;
1181 }
1182 case SkPaint::kRight_Align: {
1183 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1184 break;
1185 }
1186 default: SkASSERT(false);
1187 }
1188 }
1189}
1190
halcanary9d524f22016-03-29 09:03:52 -07001191static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001192 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001193 SkTypeface* typeface = paint.getTypeface();
1194 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001195 Json::Value jsonTypeface;
1196 SkDynamicMemoryWStream buffer;
1197 typeface->serialize(&buffer);
1198 void* data = sk_malloc_throw(buffer.bytesWritten());
1199 buffer.copyTo(data);
1200 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001201 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001202 &jsonData);
1203 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1204 sk_free(data);
1205 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001206 }
1207}
1208
halcanary9d524f22016-03-29 09:03:52 -07001209static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001210 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001211 SkFlattenable* shader = paint.getShader();
1212 if (shader != nullptr) {
1213 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001214 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001215 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1216 }
1217}
1218
ethannicholasf62a8b72016-02-11 10:35:21 -08001219static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1220 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001221 SkFlattenable* imageFilter = paint.getImageFilter();
1222 if (imageFilter != nullptr) {
1223 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001224 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001225 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1226 }
1227}
1228
halcanary9d524f22016-03-29 09:03:52 -07001229static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001230 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001231 SkFlattenable* colorFilter = paint.getColorFilter();
1232 if (colorFilter != nullptr) {
1233 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001234 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001235 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1236 }
1237}
1238
halcanary9d524f22016-03-29 09:03:52 -07001239static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001240 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001241 SkFlattenable* looper = paint.getLooper();
1242 if (looper != nullptr) {
1243 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001244 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001245 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1246 }
1247}
1248
brianosmanfad98562016-05-04 11:06:28 -07001249Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001250 Json::Value result(Json::objectValue);
1251 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001252 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001253 SkPaintDefaults_MiterLimit);
1254 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001255 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001256 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1257 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1258 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
1259 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT, paint.isDevKernText(), false);
1260 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1261 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1262 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1263 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1264 //kGenA8FromLCD_Flag
1265
halcanary9d524f22016-03-29 09:03:52 -07001266 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001267 SkPaintDefaults_TextSize);
1268 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1269 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001270 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001271 apply_paint_color(paint, &result);
1272 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001273 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001274 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001275 apply_paint_join(paint, &result);
1276 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001277 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001278 apply_paint_patheffect(paint, &result, urlDataManager);
1279 apply_paint_maskfilter(paint, &result, urlDataManager);
1280 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001281 apply_paint_looper(paint, &result, urlDataManager);
1282 apply_paint_imagefilter(paint, &result, urlDataManager);
1283 apply_paint_colorfilter(paint, &result, urlDataManager);
1284 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001285 return result;
1286}
1287
Stan Ilievac42aeb2017-01-12 16:20:50 -05001288Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1289 Json::Value result(Json::objectValue);
1290 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1291 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1292 if (nullptr != lattice.fBounds) {
1293 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1294 }
1295 Json::Value XDivs(Json::arrayValue);
1296 for (int i = 0; i < lattice.fXCount; i++) {
1297 XDivs.append(Json::Value(lattice.fXDivs[i]));
1298 }
1299 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1300 Json::Value YDivs(Json::arrayValue);
1301 for (int i = 0; i < lattice.fYCount; i++) {
1302 YDivs.append(Json::Value(lattice.fYDivs[i]));
1303 }
1304 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
Stan Ilievca8c0952017-12-11 13:01:58 -05001305 if (nullptr != lattice.fRectTypes) {
Stan Ilievac42aeb2017-01-12 16:20:50 -05001306 Json::Value flags(Json::arrayValue);
1307 int flagCount = 0;
1308 for (int row = 0; row < lattice.fYCount+1; row++) {
1309 Json::Value flagsRow(Json::arrayValue);
1310 for (int column = 0; column < lattice.fXCount+1; column++) {
Stan Ilievca8c0952017-12-11 13:01:58 -05001311 flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++]));
Stan Ilievac42aeb2017-01-12 16:20:50 -05001312 }
1313 flags.append(flagsRow);
1314 }
1315 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1316 }
1317 return result;
1318}
1319
ethannicholas1446a9a2016-02-10 14:05:02 -08001320static SkPoint get_json_point(Json::Value point) {
1321 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1322}
1323
1324static SkColor get_json_color(Json::Value color) {
1325 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1326}
1327
ethannicholas50a8dd02016-02-10 05:40:46 -08001328static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1329 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001330 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001331 }
1332}
1333
halcanary9d524f22016-03-29 09:03:52 -07001334static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001335 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001336 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1337 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
ethannicholasf62a8b72016-02-11 10:35:21 -08001338 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001339 if (shader != nullptr) {
reedfe630452016-03-25 09:08:00 -07001340 target->setShader(sk_ref_sp(shader));
ethannicholas50a8dd02016-02-10 05:40:46 -08001341 }
1342 }
1343}
1344
halcanary9d524f22016-03-29 09:03:52 -07001345static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001346 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001347 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1348 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
reeda4393342016-03-18 11:22:57 -07001349 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1350 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001351 if (pathEffect != nullptr) {
1352 target->setPathEffect(pathEffect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001353 }
1354 }
1355}
1356
halcanary9d524f22016-03-29 09:03:52 -07001357static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001358 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001359 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1360 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
reedefdfd512016-04-04 10:02:58 -07001361 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1362 urlDataManager));
1363 if (maskFilter) {
1364 target->setMaskFilter(std::move(maskFilter));
ethannicholas50a8dd02016-02-10 05:40:46 -08001365 }
1366 }
1367}
1368
halcanary9d524f22016-03-29 09:03:52 -07001369static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001370 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001371 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1372 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
reedd053ce92016-03-22 10:17:23 -07001373 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1374 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001375 if (colorFilter != nullptr) {
1376 target->setColorFilter(colorFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001377 }
1378 }
1379}
1380
halcanary9d524f22016-03-29 09:03:52 -07001381static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001382 SkPaint* target) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001383 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1384 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
reed7b380d02016-03-21 13:25:16 -07001385 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
ethannicholas1446a9a2016-02-10 14:05:02 -08001386 if (looper != nullptr) {
reed7b380d02016-03-21 13:25:16 -07001387 target->setLooper(std::move(looper));
ethannicholas1446a9a2016-02-10 14:05:02 -08001388 }
1389 }
1390}
1391
halcanary9d524f22016-03-29 09:03:52 -07001392static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001393 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001394 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1395 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
Mike Reed5e257172016-11-01 11:22:05 -04001396 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1397 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001398 if (imageFilter != nullptr) {
1399 target->setImageFilter(imageFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001400 }
1401 }
1402}
1403
halcanary9d524f22016-03-29 09:03:52 -07001404static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001405 SkPaint* target) {
1406 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1407 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1408 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1409 const void* data;
1410 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1411 SkMemoryStream buffer(data, length);
bungeman13b9c952016-05-12 10:09:30 -07001412 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
ethannicholasf62a8b72016-02-11 10:35:21 -08001413 }
1414}
1415
halcanaryf412f092016-08-25 11:10:41 -07001416static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1417 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1418 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1419 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1420 target->setHinting(SkPaint::kNo_Hinting);
1421 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1422 target->setHinting(SkPaint::kSlight_Hinting);
1423 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1424 target->setHinting(SkPaint::kNormal_Hinting);
1425 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1426 target->setHinting(SkPaint::kFull_Hinting);
1427 }
1428 }
1429}
1430
ethannicholas50a8dd02016-02-10 05:40:46 -08001431static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1432 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1433 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1434 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1435 target->setStyle(SkPaint::kFill_Style);
1436 }
1437 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1438 target->setStyle(SkPaint::kStroke_Style);
1439 }
1440 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1441 target->setStyle(SkPaint::kStrokeAndFill_Style);
1442 }
1443 }
1444}
1445
1446static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1447 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1448 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1449 target->setStrokeWidth(strokeWidth);
halcanary9d524f22016-03-29 09:03:52 -07001450 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001451}
1452
1453static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1454 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1455 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1456 target->setStrokeMiter(strokeMiter);
halcanary9d524f22016-03-29 09:03:52 -07001457 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001458}
1459
ethannicholas1446a9a2016-02-10 14:05:02 -08001460static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1461 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1462 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1463 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1464 target->setStrokeJoin(SkPaint::kMiter_Join);
1465 }
1466 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1467 target->setStrokeJoin(SkPaint::kRound_Join);
1468 }
1469 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1470 target->setStrokeJoin(SkPaint::kBevel_Join);
1471 }
1472 else {
1473 SkASSERT(false);
1474 }
1475 }
1476}
1477
ethannicholas50a8dd02016-02-10 05:40:46 -08001478static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1479 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1480 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1481 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1482 target->setStrokeCap(SkPaint::kButt_Cap);
1483 }
1484 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1485 target->setStrokeCap(SkPaint::kRound_Cap);
1486 }
1487 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1488 target->setStrokeCap(SkPaint::kSquare_Cap);
1489 }
1490 }
1491}
1492
ethannicholas1446a9a2016-02-10 14:05:02 -08001493static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1494 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1495 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1496 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1497 target->setFilterQuality(kNone_SkFilterQuality);
1498 }
1499 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1500 target->setFilterQuality(kLow_SkFilterQuality);
1501 }
1502 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1503 target->setFilterQuality(kMedium_SkFilterQuality);
1504 }
1505 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1506 target->setFilterQuality(kHigh_SkFilterQuality);
1507 }
1508 }
1509}
1510
ethannicholas50a8dd02016-02-10 05:40:46 -08001511static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1512 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1513 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1514 }
1515}
1516
ethannicholas1446a9a2016-02-10 14:05:02 -08001517static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1518 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1519 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1520 }
1521}
1522
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001523static void extract_json_paint_fakeboldtext(Json::Value& jsonPaint, SkPaint* target) {
1524 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT)) {
1525 target->setFakeBoldText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT].asBool());
1526 }
1527}
1528
1529static void extract_json_paint_lineartext(Json::Value& jsonPaint, SkPaint* target) {
1530 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT)) {
1531 target->setLinearText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT].asBool());
1532 }
1533}
1534
1535static void extract_json_paint_subpixeltext(Json::Value& jsonPaint, SkPaint* target) {
1536 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT)) {
1537 target->setSubpixelText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT].asBool());
1538 }
1539}
1540
1541static void extract_json_paint_devkerntext(Json::Value& jsonPaint, SkPaint* target) {
1542 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT)) {
1543 target->setDevKernText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT].asBool());
1544 }
1545}
1546
1547static void extract_json_paint_lcdrendertext(Json::Value& jsonPaint, SkPaint* target) {
1548 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT)) {
1549 target->setLCDRenderText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT].asBool());
1550 }
1551}
1552
1553static void extract_json_paint_embeddedbitmaptext(Json::Value& jsonPaint, SkPaint* target) {
1554 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT)) {
1555 target->setEmbeddedBitmapText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT].asBool());
1556 }
1557}
1558
1559static void extract_json_paint_autohinting(Json::Value& jsonPaint, SkPaint* target) {
1560 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING)) {
1561 target->setAutohinted(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING].asBool());
1562 }
1563}
1564
1565static void extract_json_paint_verticaltext(Json::Value& jsonPaint, SkPaint* target) {
1566 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT)) {
1567 target->setVerticalText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT].asBool());
1568 }
1569}
1570
ethannicholas50a8dd02016-02-10 05:40:46 -08001571static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1572 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1573 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1574 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1575 SkBlurStyle style;
1576 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1577 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1578 style = SkBlurStyle::kNormal_SkBlurStyle;
1579 }
1580 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1581 style = SkBlurStyle::kSolid_SkBlurStyle;
1582 }
1583 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1584 style = SkBlurStyle::kOuter_SkBlurStyle;
1585 }
1586 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1587 style = SkBlurStyle::kInner_SkBlurStyle;
1588 }
1589 else {
1590 SkASSERT(false);
1591 style = SkBlurStyle::kNormal_SkBlurStyle;
1592 }
1593 SkBlurMaskFilter::BlurFlags flags;
1594 const char* jsonQuality = blur[SKDEBUGCANVAS_ATTRIBUTE_QUALITY].asCString();
1595 if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_LOW)) {
1596 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1597 }
1598 else if (!strcmp(jsonQuality, SKDEBUGCANVAS_BLURQUALITY_HIGH)) {
1599 flags = SkBlurMaskFilter::BlurFlags::kHighQuality_BlurFlag;
1600 }
1601 else {
1602 SkASSERT(false);
1603 flags = SkBlurMaskFilter::BlurFlags::kNone_BlurFlag;
1604 }
reedefdfd512016-04-04 10:02:58 -07001605 target->setMaskFilter(SkBlurMaskFilter::Make(style, sigma, flags));
ethannicholas50a8dd02016-02-10 05:40:46 -08001606 }
1607}
1608
1609static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1610 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1611 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1612 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1613 Json::ArrayIndex count = jsonIntervals.size();
1614 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1615 for (Json::ArrayIndex i = 0; i < count; i++) {
1616 intervals[i] = jsonIntervals[i].asFloat();
1617 }
1618 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
reeda4393342016-03-18 11:22:57 -07001619 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
ethannicholas50a8dd02016-02-10 05:40:46 -08001620 sk_free(intervals);
1621 }
1622}
1623
1624static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1625 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1626 SkPaint::Align textAlign;
1627 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1628 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1629 textAlign = SkPaint::kLeft_Align;
1630 }
1631 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1632 textAlign = SkPaint::kCenter_Align;
1633 }
1634 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1635 textAlign = SkPaint::kRight_Align;
1636 }
1637 else {
1638 SkASSERT(false);
1639 textAlign = SkPaint::kLeft_Align;
1640 }
1641 target->setTextAlign(textAlign);
1642 }
1643}
1644
1645static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1646 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1647 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1648 target->setTextSize(textSize);
1649 }
1650}
1651
1652static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1653 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1654 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1655 target->setTextScaleX(textScaleX);
1656 }
1657}
1658
1659static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1660 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1661 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1662 target->setTextSkewX(textSkewX);
1663 }
1664}
1665
halcanary9d524f22016-03-29 09:03:52 -07001666static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001667 SkPaint* result) {
halcanaryf412f092016-08-25 11:10:41 -07001668 extract_json_paint_hinting(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001669 extract_json_paint_color(paint, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001670 extract_json_paint_shader(paint, urlDataManager, result);
1671 extract_json_paint_patheffect(paint, urlDataManager, result);
1672 extract_json_paint_maskfilter(paint, urlDataManager, result);
1673 extract_json_paint_colorfilter(paint, urlDataManager, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001674 extract_json_paint_looper(paint, urlDataManager, result);
1675 extract_json_paint_imagefilter(paint, urlDataManager, result);
1676 extract_json_paint_typeface(paint, urlDataManager, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001677 extract_json_paint_style(paint, result);
Florin Malita82d80872017-06-06 16:58:40 -04001678 extract_json_paint_blend_mode(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001679 extract_json_paint_strokewidth(paint, result);
1680 extract_json_paint_strokemiter(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001681 extract_json_paint_strokejoin(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001682 extract_json_paint_cap(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001683 extract_json_paint_filterquality(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001684 extract_json_paint_antialias(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001685 extract_json_paint_dither(paint, result);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001686 extract_json_paint_fakeboldtext(paint, result);
1687 extract_json_paint_lineartext(paint, result);
1688 extract_json_paint_subpixeltext(paint, result);
1689 extract_json_paint_devkerntext(paint, result);
1690 extract_json_paint_lcdrendertext(paint, result);
1691 extract_json_paint_embeddedbitmaptext(paint, result);
1692 extract_json_paint_autohinting(paint, result);
1693 extract_json_paint_verticaltext(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001694 extract_json_paint_blur(paint, result);
1695 extract_json_paint_dashing(paint, result);
1696 extract_json_paint_textalign(paint, result);
1697 extract_json_paint_textsize(paint, result);
1698 extract_json_paint_textscalex(paint, result);
1699 extract_json_paint_textskewx(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001700}
1701
1702static void extract_json_rect(Json::Value& rect, SkRect* result) {
1703 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1704}
1705
1706static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1707 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1708}
1709
1710static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1711 SkVector radii[4] = {
halcanary9d524f22016-03-29 09:03:52 -07001712 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1713 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1714 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
ethannicholas50a8dd02016-02-10 05:40:46 -08001715 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1716 };
halcanary9d524f22016-03-29 09:03:52 -07001717 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1718 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
ethannicholas50a8dd02016-02-10 05:40:46 -08001719 radii);
1720}
1721
1722static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
halcanary9d524f22016-03-29 09:03:52 -07001723 SkScalar values[] = {
ethannicholas50a8dd02016-02-10 05:40:46 -08001724 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1725 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
halcanary9d524f22016-03-29 09:03:52 -07001726 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
ethannicholas50a8dd02016-02-10 05:40:46 -08001727 };
1728 result->set9(values);
1729}
1730
1731static void extract_json_path(Json::Value& path, SkPath* result) {
1732 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1733 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1734 result->setFillType(SkPath::kWinding_FillType);
1735 }
1736 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1737 result->setFillType(SkPath::kEvenOdd_FillType);
1738 }
1739 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1740 result->setFillType(SkPath::kInverseWinding_FillType);
1741 }
1742 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1743 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1744 }
1745 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1746 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1747 Json::Value verb = verbs[i];
1748 if (verb.isString()) {
1749 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1750 result->close();
1751 }
1752 else {
1753 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1754 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1755 result->moveTo(move[0].asFloat(), move[1].asFloat());
1756 }
1757 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1758 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1759 result->lineTo(line[0].asFloat(), line[1].asFloat());
1760 }
1761 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1762 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1763 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1764 quad[1][0].asFloat(), quad[1][1].asFloat());
1765 }
1766 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1767 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1768 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1769 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1770 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1771 }
1772 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1773 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1774 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1775 conic[1][0].asFloat(), conic[1][1].asFloat(),
1776 conic[2].asFloat());
1777 }
1778 else {
1779 SkASSERT(false);
1780 }
1781 }
1782 }
1783}
1784
Brian Osmanc25e2692018-03-12 10:57:28 -04001785static void extract_json_region(Json::Value& region, SkRegion* result) {
1786 SkPath path;
1787 extract_json_path(region, &path);
1788 result->setPath(path, SkRegion(path.getBounds().roundOut()));
1789}
1790
Mike Reedc1f77742016-12-09 09:00:50 -05001791SkClipOp get_json_clipop(Json::Value& jsonOp) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001792 const char* op = jsonOp.asCString();
1793 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001794 return kDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001795 }
1796 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001797 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001798 }
1799 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001800 return kUnion_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001801 }
1802 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001803 return kXOR_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001804 }
1805 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001806 return kReverseDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001807 }
1808 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001809 return kReplace_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001810 }
1811 SkASSERT(false);
Mike Reedc1f77742016-12-09 09:00:50 -05001812 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001813}
1814
Brian Osmanc25e2692018-03-12 10:57:28 -04001815SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001816 fColor = color;
1817 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
1818}
1819
1820void SkClearCommand::execute(SkCanvas* canvas) const {
1821 canvas->clear(fColor);
1822}
1823
ethannicholasf62a8b72016-02-11 10:35:21 -08001824Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1825 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001826 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001827 return result;
1828}
1829
ethannicholasf62a8b72016-02-11 10:35:21 -08001830 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001831 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1832 return new SkClearCommand(get_json_color(color));
1833}
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001834
Mike Reedc1f77742016-12-09 09:00:50 -05001835SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001836 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001837 fPath = path;
1838 fOp = op;
1839 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001840
robertphillips@google.com91217d02013-03-17 18:33:46 +00001841 fInfo.push(SkObjectParser::PathToString(path));
reed73603f32016-09-20 08:42:38 -07001842 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.com91217d02013-03-17 18:33:46 +00001843 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001844}
1845
fmalita8c89c522014-11-08 16:18:56 -08001846void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001847 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001848}
1849
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001850bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001851 render_path(canvas, fPath);
1852 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001853}
1854
ethannicholasf62a8b72016-02-11 10:35:21 -08001855Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1856 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001857 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001858 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1859 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1860 return result;
1861}
1862
halcanary9d524f22016-03-29 09:03:52 -07001863SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001864 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001865 SkPath path;
1866 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
reed73603f32016-09-20 08:42:38 -07001867 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001868 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1869}
1870
Mike Reedc1f77742016-12-09 09:00:50 -05001871SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001872 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001873 fRegion = region;
1874 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001875
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001876 fInfo.push(SkObjectParser::RegionToString(region));
reed73603f32016-09-20 08:42:38 -07001877 fInfo.push(SkObjectParser::ClipOpToString(op));
chudy@google.com902ebe52012-06-29 14:21:22 +00001878}
1879
fmalita8c89c522014-11-08 16:18:56 -08001880void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001881 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001882}
1883
ethannicholasf62a8b72016-02-11 10:35:21 -08001884Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1885 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001886 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001887 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1888 return result;
1889}
1890
halcanary9d524f22016-03-29 09:03:52 -07001891SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001892 UrlDataManager& urlDataManager) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001893 SkRegion region;
1894 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
1895 return new SkClipRegionCommand(region,
1896 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001897}
1898
Mike Reedc1f77742016-12-09 09:00:50 -05001899SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001900 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001901 fRect = rect;
1902 fOp = op;
1903 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001904
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001905 fInfo.push(SkObjectParser::RectToString(rect));
reed73603f32016-09-20 08:42:38 -07001906 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001907 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001908}
1909
fmalita8c89c522014-11-08 16:18:56 -08001910void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001911 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001912}
1913
ethannicholasf62a8b72016-02-11 10:35:21 -08001914Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1915 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001916 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001917 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1918 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001919
1920 SkString desc;
1921 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1922
ethannicholas50a8dd02016-02-10 05:40:46 -08001923 return result;
1924}
1925
halcanary9d524f22016-03-29 09:03:52 -07001926SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001927 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001928 SkRect rect;
1929 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
reed73603f32016-09-20 08:42:38 -07001930 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001931 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1932}
1933
Mike Reedc1f77742016-12-09 09:00:50 -05001934SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001935 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001936 fRRect = rrect;
1937 fOp = op;
1938 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001939
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001940 fInfo.push(SkObjectParser::RRectToString(rrect));
reed73603f32016-09-20 08:42:38 -07001941 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001942 fInfo.push(SkObjectParser::BoolToString(doAA));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001943}
1944
fmalita8c89c522014-11-08 16:18:56 -08001945void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001946 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001947}
1948
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001949bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001950 render_rrect(canvas, fRRect);
1951 return true;
1952}
1953
ethannicholasf62a8b72016-02-11 10:35:21 -08001954Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1955 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001956 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1957 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1958 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1959 return result;
1960}
1961
halcanary9d524f22016-03-29 09:03:52 -07001962SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001963 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001964 SkRRect rrect;
1965 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
halcanary9d524f22016-03-29 09:03:52 -07001966 return new SkClipRRectCommand(rrect,
reed73603f32016-09-20 08:42:38 -07001967 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001968 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1969}
1970
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001971SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001972 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001973 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001974
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001975 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00001976}
1977
fmalita8c89c522014-11-08 16:18:56 -08001978void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001979 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001980}
1981
ethannicholasf62a8b72016-02-11 10:35:21 -08001982Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1983 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001984 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001985 return result;
1986}
1987
ethannicholasf62a8b72016-02-11 10:35:21 -08001988SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001989 SkMatrix matrix;
1990 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1991 return new SkConcatCommand(matrix);
1992}
1993
reed97660cc2016-06-28 18:54:19 -07001994////
1995
1996SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1997 sk_sp<SkData> value)
1998 : INHERITED(kDrawAnnotation_OpType)
1999 , fRect(rect)
2000 , fKey(key)
2001 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07002002{
2003 SkString str;
2004 str.appendf("Key: %s Value: ", key);
2005 if (fValue && fValue->size()) {
2006 str.append((const char*) fValue->bytes(), fValue->size());
2007 } else {
2008 str.appendf("no value");
2009 }
2010 str.appendf("\n");
2011 fInfo.push(new SkString(str));
2012}
reed97660cc2016-06-28 18:54:19 -07002013
2014void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
2015 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
2016}
2017
2018Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
2019 Json::Value result = INHERITED::toJSON(urlDataManager);
2020
2021 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
2022 result["key"] = Json::Value(fKey.c_str());
2023 if (fValue.get()) {
2024 // TODO: dump out the "value"
2025 }
reed67f62fa2016-06-29 11:36:34 -07002026
2027 SkString desc;
2028 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
2029 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
2030
reed97660cc2016-06-28 18:54:19 -07002031 return result;
2032}
2033
2034SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
2035 UrlDataManager& urlDataManager) {
2036 SkRect rect;
2037 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
2038 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
2039 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
2040}
2041
2042////
2043
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002044SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07002045 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002046 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002047 fBitmap = bitmap;
2048 fLeft = left;
2049 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07002050 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002051 fPaint = *paint;
2052 fPaintPtr = &fPaint;
2053 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002054 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002055 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002056
2057 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2058 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
2059 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
bsalomon49f085d2014-09-05 13:34:00 -07002060 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002061 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002062 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002063}
2064
fmalita8c89c522014-11-08 16:18:56 -08002065void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002066 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002067}
2068
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002069bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002070 render_bitmap(canvas, fBitmap);
2071 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002072}
2073
ethannicholasf62a8b72016-02-11 10:35:21 -08002074Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
2075 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002076 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002077 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002078 Json::Value command(Json::objectValue);
2079 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002080 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002081 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002082 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002083 }
2084 }
2085 return result;
2086}
2087
halcanary9d524f22016-03-29 09:03:52 -07002088SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002089 UrlDataManager& urlDataManager) {
2090 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002091 if (bitmap == nullptr) {
2092 return nullptr;
2093 }
2094 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2095 SkPaint* paintPtr;
2096 SkPaint paint;
2097 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002098 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002099 paintPtr = &paint;
2100 }
2101 else {
2102 paintPtr = nullptr;
2103 }
halcanary9d524f22016-03-29 09:03:52 -07002104 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002105 point[1].asFloat(), paintPtr);
2106 delete bitmap;
2107 return result;
2108}
2109
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002110SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00002111 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002112 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002113 fBitmap = bitmap;
2114 fCenter = center;
2115 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07002116 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002117 fPaint = *paint;
2118 fPaintPtr = &fPaint;
2119 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002120 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002121 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002122
2123 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2124 fInfo.push(SkObjectParser::IRectToString(center));
2125 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07002126 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002127 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002128 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002129}
2130
fmalita8c89c522014-11-08 16:18:56 -08002131void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002132 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002133}
2134
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002135bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08002136 SkRect tmp = SkRect::Make(fCenter);
2137 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002138 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002139}
2140
ethannicholasf62a8b72016-02-11 10:35:21 -08002141Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2142 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002143 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002144 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002145 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08002146 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07002147 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002148 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002149 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002150 }
2151 }
2152 return result;
2153}
2154
halcanary9d524f22016-03-29 09:03:52 -07002155SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002156 UrlDataManager& urlDataManager) {
2157 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002158 if (bitmap == nullptr) {
2159 return nullptr;
2160 }
2161 SkIRect center;
2162 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2163 SkRect dst;
2164 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2165 SkPaint* paintPtr;
2166 SkPaint paint;
2167 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002168 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002169 paintPtr = &paint;
2170 }
2171 else {
2172 paintPtr = nullptr;
2173 }
2174 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2175 delete bitmap;
2176 return result;
2177}
2178
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002179SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002180 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002181 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08002182 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002183 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07002184 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002185 fSrc = *src;
2186 } else {
2187 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002188 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00002189 fDst = dst;
2190
bsalomon49f085d2014-09-05 13:34:00 -07002191 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002192 fPaint = *paint;
2193 fPaintPtr = &fPaint;
2194 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002195 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00002196 }
reeda5517e22015-07-14 10:54:12 -07002197 fConstraint = constraint;
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002198
robertphillips@google.com91217d02013-03-17 18:33:46 +00002199 fInfo.push(SkObjectParser::BitmapToString(bitmap));
bsalomon49f085d2014-09-05 13:34:00 -07002200 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002201 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2202 }
2203 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07002204 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002205 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002206 }
reeda5517e22015-07-14 10:54:12 -07002207 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
chudy@google.com902ebe52012-06-29 14:21:22 +00002208}
2209
fmalita8c89c522014-11-08 16:18:56 -08002210void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07002211 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002212}
2213
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002214bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002215 render_bitmap(canvas, fBitmap, this->srcRect());
2216 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002217}
2218
ethannicholasf62a8b72016-02-11 10:35:21 -08002219Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2220 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002221 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002222 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002223 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2224 if (!fSrc.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07002225 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
ethannicholas50a8dd02016-02-10 05:40:46 -08002226 }
brianosmanfad98562016-05-04 11:06:28 -07002227 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002228 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002229 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002230 }
2231 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2232 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2233 }
2234 }
reed67f62fa2016-06-29 11:36:34 -07002235
2236 SkString desc;
2237 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2238
ethannicholas50a8dd02016-02-10 05:40:46 -08002239 return result;
2240}
2241
halcanary9d524f22016-03-29 09:03:52 -07002242SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002243 UrlDataManager& urlDataManager) {
2244 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002245 if (bitmap == nullptr) {
2246 return nullptr;
2247 }
2248 SkRect dst;
2249 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2250 SkPaint* paintPtr;
2251 SkPaint paint;
2252 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002253 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002254 paintPtr = &paint;
2255 }
2256 else {
2257 paintPtr = nullptr;
2258 }
2259 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002260 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002261 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2262 constraint = SkCanvas::kStrict_SrcRectConstraint;
2263 }
2264 else {
2265 constraint = SkCanvas::kFast_SrcRectConstraint;
2266 }
2267 SkRect* srcPtr;
2268 SkRect src;
2269 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2270 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2271 srcPtr = &src;
2272 }
2273 else {
2274 srcPtr = nullptr;
2275 }
2276 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2277 constraint);
2278 delete bitmap;
2279 return result;
2280}
2281
fmalita651c9202015-07-22 10:23:01 -07002282SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2283 const SkPaint* paint)
2284 : INHERITED(kDrawImage_OpType)
2285 , fImage(SkRef(image))
2286 , fLeft(left)
2287 , fTop(top) {
2288
fmalita7361bf02015-10-29 12:13:48 -07002289 fInfo.push(SkObjectParser::ImageToString(image));
2290 fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
2291 fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));
2292
fmalita651c9202015-07-22 10:23:01 -07002293 if (paint) {
2294 fPaint.set(*paint);
fmalita7361bf02015-10-29 12:13:48 -07002295 fInfo.push(SkObjectParser::PaintToString(*paint));
fmalita651c9202015-07-22 10:23:01 -07002296 }
2297}
2298
2299void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002300 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07002301}
2302
2303bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2304 SkAutoCanvasRestore acr(canvas, true);
2305 canvas->clear(0xFFFFFFFF);
2306
2307 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2308 SkIntToScalar(fImage->width()),
2309 SkIntToScalar(fImage->height())));
2310 this->execute(canvas);
2311 return true;
2312}
2313
ethannicholasf62a8b72016-02-11 10:35:21 -08002314Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2315 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002316 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002317 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002318 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002319 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002320 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002321 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002322 }
msarett0ac1bec2016-08-29 09:15:33 -07002323
2324 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2325 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2326 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2327 switch (fImage->alphaType()) {
2328 case kOpaque_SkAlphaType:
2329 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2330 break;
2331 case kPremul_SkAlphaType:
2332 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2333 break;
2334 case kUnpremul_SkAlphaType:
2335 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2336 break;
2337 default:
2338 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2339 break;
2340 }
ethannicholas50a8dd02016-02-10 05:40:46 -08002341 }
2342 return result;
2343}
2344
halcanary9d524f22016-03-29 09:03:52 -07002345SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002346 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002347 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002348 if (image == nullptr) {
2349 return nullptr;
2350 }
2351 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2352 SkPaint* paintPtr;
2353 SkPaint paint;
2354 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002355 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002356 paintPtr = &paint;
2357 }
2358 else {
2359 paintPtr = nullptr;
2360 }
reed9ce9d672016-03-17 10:51:11 -07002361 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002362 point[1].asFloat(), paintPtr);
ethannicholas50a8dd02016-02-10 05:40:46 -08002363 return result;
2364}
2365
Stan Ilievac42aeb2017-01-12 16:20:50 -05002366SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2367 const SkCanvas::Lattice& lattice,
2368 const SkRect& dst, const SkPaint* paint)
2369 : INHERITED(kDrawImageLattice_OpType)
2370 , fImage(SkRef(image))
2371 , fLattice(lattice)
2372 , fDst(dst) {
2373
2374 fInfo.push(SkObjectParser::ImageToString(image));
2375 fInfo.push(SkObjectParser::LatticeToString(lattice));
2376 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2377 if (paint) {
2378 fPaint.set(*paint);
2379 fInfo.push(SkObjectParser::PaintToString(*paint));
2380 }
2381}
2382
2383void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
2384 SkLatticeIter iter(fLattice, fDst);
2385 SkRect srcR, dstR;
2386 while (iter.next(&srcR, &dstR)) {
2387 canvas->legacy_drawImageRect(fImage.get(), &srcR, dstR,
2388 fPaint.getMaybeNull(), SkCanvas::kStrict_SrcRectConstraint);
2389 }
2390}
2391
2392bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2393 SkAutoCanvasRestore acr(canvas, true);
2394 canvas->clear(0xFFFFFFFF);
2395
2396 xlate_and_scale_to_bounds(canvas, fDst);
2397
2398 this->execute(canvas);
2399 return true;
2400}
2401
2402Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2403 Json::Value result = INHERITED::toJSON(urlDataManager);
2404 Json::Value encoded;
2405 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002406 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
Stan Ilievac42aeb2017-01-12 16:20:50 -05002407 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2408 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2409 if (fPaint.isValid()) {
2410 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2411 }
2412 }
2413
2414 SkString desc;
2415 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2416
2417 return result;
2418}
2419
Brian Osmanc25e2692018-03-12 10:57:28 -04002420SkDrawImageLatticeCommand* SkDrawImageLatticeCommand::fromJSON(Json::Value& command,
2421 UrlDataManager& urlDataManager) {
2422 SkDEBUGFAIL("Not implemented yet.");
2423 return nullptr;
2424}
2425
fmalita651c9202015-07-22 10:23:01 -07002426SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2427 const SkRect& dst, const SkPaint* paint,
2428 SkCanvas::SrcRectConstraint constraint)
2429 : INHERITED(kDrawImageRect_OpType)
2430 , fImage(SkRef(image))
2431 , fDst(dst)
2432 , fConstraint(constraint) {
2433
2434 if (src) {
2435 fSrc.set(*src);
2436 }
2437
2438 if (paint) {
2439 fPaint.set(*paint);
2440 }
robertphillips80af6452015-08-24 08:27:38 -07002441
2442 fInfo.push(SkObjectParser::ImageToString(image));
2443 if (src) {
2444 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2445 }
2446 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2447 if (paint) {
2448 fInfo.push(SkObjectParser::PaintToString(*paint));
2449 }
2450 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
fmalita651c9202015-07-22 10:23:01 -07002451}
2452
2453void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002454 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2455 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07002456}
2457
2458bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2459 SkAutoCanvasRestore acr(canvas, true);
2460 canvas->clear(0xFFFFFFFF);
2461
2462 xlate_and_scale_to_bounds(canvas, fDst);
2463
2464 this->execute(canvas);
2465 return true;
2466}
2467
ethannicholasf62a8b72016-02-11 10:35:21 -08002468Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2469 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002470 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002471 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002472 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
ethannicholas50a8dd02016-02-10 05:40:46 -08002473 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002474 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002475 }
brianosmanfad98562016-05-04 11:06:28 -07002476 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002477 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002478 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002479 }
2480 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2481 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2482 }
2483 }
reed67f62fa2016-06-29 11:36:34 -07002484
2485 SkString desc;
2486 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2487
ethannicholas50a8dd02016-02-10 05:40:46 -08002488 return result;
2489}
2490
halcanary9d524f22016-03-29 09:03:52 -07002491SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002492 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002493 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002494 if (image == nullptr) {
2495 return nullptr;
2496 }
2497 SkRect dst;
2498 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2499 SkPaint* paintPtr;
2500 SkPaint paint;
2501 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002502 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002503 paintPtr = &paint;
2504 }
2505 else {
2506 paintPtr = nullptr;
2507 }
2508 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002509 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002510 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2511 constraint = SkCanvas::kStrict_SrcRectConstraint;
2512 }
2513 else {
2514 constraint = SkCanvas::kFast_SrcRectConstraint;
2515 }
2516 SkRect* srcPtr;
2517 SkRect src;
2518 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2519 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2520 srcPtr = &src;
2521 }
2522 else {
2523 srcPtr = nullptr;
2524 }
reed9ce9d672016-03-17 10:51:11 -07002525 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
ethannicholas50a8dd02016-02-10 05:40:46 -08002526 constraint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002527 return result;
2528}
2529
Brian Osmanc25e2692018-03-12 10:57:28 -04002530SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
2531 const SkRect& dst, const SkPaint* paint)
2532 : INHERITED(kDrawImageNine_OpType)
2533 , fImage(SkRef(image))
2534 , fCenter(center)
2535 , fDst(dst) {
2536 if (paint) {
2537 fPaint = *paint;
2538 fPaintPtr = &fPaint;
2539 } else {
2540 fPaintPtr = nullptr;
2541 }
2542
2543 fInfo.push(SkObjectParser::ImageToString(image));
2544 fInfo.push(SkObjectParser::IRectToString(center));
2545 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2546 if (paint) {
2547 fInfo.push(SkObjectParser::PaintToString(*paint));
2548 }
2549}
2550
2551void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
2552 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaintPtr);
2553}
2554
2555bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
2556 SkAutoCanvasRestore acr(canvas, true);
2557 canvas->clear(0xFFFFFFFF);
2558
2559 xlate_and_scale_to_bounds(canvas, fDst);
2560
2561 this->execute(canvas);
2562 return true;
2563}
2564
2565Json::Value SkDrawImageNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2566 Json::Value result = INHERITED::toJSON(urlDataManager);
2567 Json::Value encoded;
2568 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2569 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
2570 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
2571 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2572 if (fPaintPtr != nullptr) {
2573 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2574 }
2575 }
2576 return result;
2577}
2578
2579SkDrawImageNineCommand* SkDrawImageNineCommand::fromJSON(Json::Value& command,
2580 UrlDataManager& urlDataManager) {
2581 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2582 if (image == nullptr) {
2583 return nullptr;
2584 }
2585 SkIRect center;
2586 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2587 SkRect dst;
2588 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2589 SkPaint* paintPtr;
2590 SkPaint paint;
2591 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2592 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2593 paintPtr = &paint;
2594 } else {
2595 paintPtr = nullptr;
2596 }
2597 SkDrawImageNineCommand* result = new SkDrawImageNineCommand(image.get(), center, dst, paintPtr);
2598 return result;
2599}
2600
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002601SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002602 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002603 fOval = oval;
2604 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002605
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002606 fInfo.push(SkObjectParser::RectToString(oval));
2607 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00002608}
2609
fmalita8c89c522014-11-08 16:18:56 -08002610void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002611 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002612}
2613
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002614bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002615 canvas->clear(0xFFFFFFFF);
2616 canvas->save();
2617
2618 xlate_and_scale_to_bounds(canvas, fOval);
2619
2620 SkPaint p;
2621 p.setColor(SK_ColorBLACK);
2622 p.setStyle(SkPaint::kStroke_Style);
2623
2624 canvas->drawOval(fOval, p);
2625 canvas->restore();
2626
2627 return true;
2628}
2629
ethannicholasf62a8b72016-02-11 10:35:21 -08002630Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2631 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002632 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2633 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002634 return result;
2635}
2636
halcanary9d524f22016-03-29 09:03:52 -07002637SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002638 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002639 SkRect coords;
2640 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2641 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002642 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002643 return new SkDrawOvalCommand(coords, paint);
2644}
2645
bsalomonac3aa242016-08-19 11:25:19 -07002646SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2647 bool useCenter, const SkPaint& paint)
Brian Osmanc25e2692018-03-12 10:57:28 -04002648 : INHERITED(kDrawArc_OpType) {
bsalomonac3aa242016-08-19 11:25:19 -07002649 fOval = oval;
2650 fStartAngle = startAngle;
2651 fSweepAngle = sweepAngle;
2652 fUseCenter = useCenter;
2653 fPaint = paint;
2654
2655 fInfo.push(SkObjectParser::RectToString(oval));
2656 fInfo.push(SkObjectParser::ScalarToString(startAngle, "StartAngle: "));
2657 fInfo.push(SkObjectParser::ScalarToString(sweepAngle, "SweepAngle: "));
2658 fInfo.push(SkObjectParser::BoolToString(useCenter));
2659 fInfo.push(SkObjectParser::PaintToString(paint));
2660}
2661
2662void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2663 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2664}
2665
2666bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2667 canvas->clear(0xFFFFFFFF);
2668 canvas->save();
2669
2670 xlate_and_scale_to_bounds(canvas, fOval);
2671
2672 SkPaint p;
2673 p.setColor(SK_ColorBLACK);
2674 p.setStyle(SkPaint::kStroke_Style);
2675
2676 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2677 canvas->restore();
2678
2679 return true;
2680}
2681
2682Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2683 Json::Value result = INHERITED::toJSON(urlDataManager);
2684 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2685 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2686 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2687 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2688 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2689 return result;
2690}
2691
2692SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2693 UrlDataManager& urlDataManager) {
2694 SkRect coords;
2695 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2696 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2697 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2698 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2699 SkPaint paint;
2700 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2701 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2702}
2703
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002704SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002705 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002706 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002707
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002708 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002709}
2710
fmalita8c89c522014-11-08 16:18:56 -08002711void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002712 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002713}
2714
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002715bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002716 canvas->clear(0xFFFFFFFF);
2717 canvas->drawPaint(fPaint);
2718 return true;
2719}
2720
ethannicholasf62a8b72016-02-11 10:35:21 -08002721Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2722 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002723 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002724 return result;
2725}
2726
halcanary9d524f22016-03-29 09:03:52 -07002727SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002728 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002729 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002730 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002731 return new SkDrawPaintCommand(paint);
2732}
2733
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002734SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002735 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002736 fPath = path;
2737 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002738
robertphillips@google.com91217d02013-03-17 18:33:46 +00002739 fInfo.push(SkObjectParser::PathToString(path));
2740 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002741}
2742
fmalita8c89c522014-11-08 16:18:56 -08002743void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002744 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002745}
2746
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002747bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002748 render_path(canvas, fPath);
2749 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002750}
2751
ethannicholasf62a8b72016-02-11 10:35:21 -08002752Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2753 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002754 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2755 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002756 return result;
2757}
2758
halcanary9d524f22016-03-29 09:03:52 -07002759SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002760 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002761 SkPath path;
2762 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2763 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002764 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002765 return new SkDrawPathCommand(path, paint);
2766}
2767
Brian Osmanc25e2692018-03-12 10:57:28 -04002768SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
2769 : INHERITED(kDrawRegion_OpType) {
2770 fRegion = region;
2771 fPaint = paint;
2772
2773 fInfo.push(SkObjectParser::RegionToString(region));
2774 fInfo.push(SkObjectParser::PaintToString(paint));
2775}
2776
2777void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
2778 canvas->drawRegion(fRegion, fPaint);
2779}
2780
2781bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
2782 render_region(canvas, fRegion);
2783 return true;
2784}
2785
2786Json::Value SkDrawRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
2787 Json::Value result = INHERITED::toJSON(urlDataManager);
2788 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
2789 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2790 return result;
2791}
2792
2793SkDrawRegionCommand* SkDrawRegionCommand::fromJSON(Json::Value& command,
2794 UrlDataManager& urlDataManager) {
2795 SkRegion region;
2796 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
2797 SkPaint paint;
2798 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2799 return new SkDrawRegionCommand(region, paint);
2800}
2801
fmalita160ebb22015-04-01 20:58:37 -07002802SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2803 const SkMatrix* matrix,
2804 const SkPaint* paint)
2805 : INHERITED(kBeginDrawPicture_OpType)
2806 , fPicture(SkRef(picture)) {
2807
2808 SkString* str = new SkString;
2809 str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
2810 picture->cullRect().fLeft, picture->cullRect().fTop,
2811 picture->cullRect().fRight, picture->cullRect().fBottom);
2812 fInfo.push(str);
robertphillipsb3f319f2014-08-13 10:46:23 -07002813
bsalomon49f085d2014-09-05 13:34:00 -07002814 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002815 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002816 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2817 }
fmalita160ebb22015-04-01 20:58:37 -07002818
bsalomon49f085d2014-09-05 13:34:00 -07002819 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002820 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002821 fInfo.push(SkObjectParser::PaintToString(*paint));
2822 }
fmalita160ebb22015-04-01 20:58:37 -07002823
2824}
2825
2826void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2827 if (fPaint.isValid()) {
2828 SkRect bounds = fPicture->cullRect();
2829 if (fMatrix.isValid()) {
2830 fMatrix.get()->mapRect(&bounds);
2831 }
2832 canvas->saveLayer(&bounds, fPaint.get());
2833 }
2834
2835 if (fMatrix.isValid()) {
2836 if (!fPaint.isValid()) {
2837 canvas->save();
2838 }
2839 canvas->concat(*fMatrix.get());
2840 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002841}
2842
fmalita160ebb22015-04-01 20:58:37 -07002843bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002844 canvas->clear(0xFFFFFFFF);
2845 canvas->save();
2846
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002847 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002848
robertphillips9b14f262014-06-04 05:40:44 -07002849 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002850
2851 canvas->restore();
2852
2853 return true;
2854}
2855
fmalita160ebb22015-04-01 20:58:37 -07002856SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2857 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2858
2859void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2860 if (fRestore) {
2861 canvas->restore();
2862 }
2863}
2864
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002865SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002866 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002867 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002868 fMode = mode;
2869 fCount = count;
2870 fPts = new SkPoint[count];
2871 memcpy(fPts, pts, count * sizeof(SkPoint));
2872 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002873
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002874 fInfo.push(SkObjectParser::PointsToString(pts, count));
2875 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
2876 "Points: "));
2877 fInfo.push(SkObjectParser::PointModeToString(mode));
2878 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002879}
2880
fmalita8c89c522014-11-08 16:18:56 -08002881void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002882 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002883}
2884
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002885bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002886 canvas->clear(0xFFFFFFFF);
2887 canvas->save();
2888
2889 SkRect bounds;
2890
2891 bounds.setEmpty();
2892 for (unsigned int i = 0; i < fCount; ++i) {
Mike Reed185ffe92018-01-08 17:09:54 -05002893 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002894 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002895
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002896 xlate_and_scale_to_bounds(canvas, bounds);
2897
2898 SkPaint p;
2899 p.setColor(SK_ColorBLACK);
2900 p.setStyle(SkPaint::kStroke_Style);
2901
2902 canvas->drawPoints(fMode, fCount, fPts, p);
2903 canvas->restore();
2904
2905 return true;
2906}
2907
ethannicholasf62a8b72016-02-11 10:35:21 -08002908Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2909 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002910 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2911 Json::Value points(Json::arrayValue);
2912 for (size_t i = 0; i < fCount; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002913 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002914 }
2915 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07002916 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002917 return result;
2918}
2919
halcanary9d524f22016-03-29 09:03:52 -07002920SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002921 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002922 SkCanvas::PointMode mode;
2923 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2924 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2925 mode = SkCanvas::kPoints_PointMode;
2926 }
2927 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2928 mode = SkCanvas::kLines_PointMode;
2929 }
2930 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2931 mode = SkCanvas::kPolygon_PointMode;
2932 }
2933 else {
2934 SkASSERT(false);
2935 return nullptr;
2936 }
2937 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2938 int count = (int) jsonPoints.size();
2939 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2940 for (int i = 0; i < count; i++) {
2941 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2942 }
2943 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002944 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002945 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2946 sk_free(points);
2947 return result;
2948}
2949
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002950SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002951 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002952 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002953 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002954
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002955 fText = new char[byteLength];
2956 memcpy(fText, text, byteLength);
2957 fByteLength = byteLength;
2958
2959 fPos = new SkPoint[numPts];
2960 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2961
2962 fPaint = paint;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002963
2964 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
chudy@google.com902ebe52012-06-29 14:21:22 +00002965 // TODO(chudy): Test that this works.
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002966 fInfo.push(SkObjectParser::PointsToString(pos, 1));
2967 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002968}
2969
fmalita8c89c522014-11-08 16:18:56 -08002970void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002971 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002972}
2973
ethannicholasf62a8b72016-02-11 10:35:21 -08002974Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2975 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002976 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002977 ((const char*) fText) + fByteLength);
2978 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08002979 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2980 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002981 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002982 }
2983 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07002984 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002985 return result;
2986}
2987
halcanary9d524f22016-03-29 09:03:52 -07002988SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002989 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002990 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2991 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002992 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002993 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2994 int count = (int) coords.size();
2995 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2996 for (int i = 0; i < count; i++) {
2997 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2998 }
2999 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
3000}
chudy@google.com902ebe52012-06-29 14:21:22 +00003001
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003002SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
3003 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003004 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003005 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00003006 size_t numPts = paint.countText(text, byteLength);
3007
3008 fText = new char[byteLength];
3009 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00003010 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00003011
3012 fXpos = new SkScalar[numPts];
3013 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
3014
robertphillips@google.com91217d02013-03-17 18:33:46 +00003015 fConstY = constY;
3016 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003017
robertphillips@google.com91217d02013-03-17 18:33:46 +00003018 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3019 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
3020 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
3021 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003022}
3023
fmalita8c89c522014-11-08 16:18:56 -08003024void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003025 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003026}
3027
bungeman51190df2016-03-09 07:42:54 -08003028Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
3029 Json::Value result = INHERITED::toJSON(urlDataManager);
3030 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3031 ((const char*) fText) + fByteLength);
3032 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
3033 Json::Value xpos(Json::arrayValue);
3034 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
3035 for (size_t i = 0; i < numXpos; i++) {
3036 xpos.append(Json::Value(fXpos[i]));
3037 }
3038 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07003039 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08003040 return result;
3041}
3042
3043SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
3044 UrlDataManager& urlDataManager) {
3045 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3046 SkPaint paint;
3047 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3048 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3049 int count = (int) jsonXpos.size();
3050 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
3051 for (int i = 0; i < count; i++) {
3052 xpos[i] = jsonXpos[i].asFloat();
3053 }
3054 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3055 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
3056}
3057
fmalita0d48e412016-01-04 08:08:04 -08003058static const char* gPositioningLabels[] = {
3059 "kDefault_Positioning",
3060 "kHorizontal_Positioning",
3061 "kFull_Positioning",
3062};
3063
fmalita37283c22016-09-13 10:00:23 -07003064SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07003065 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003066 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07003067 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07003068 , fXPos(x)
3069 , fYPos(y)
3070 , fPaint(paint) {
3071
Ben Wagner145dbcd2016-11-03 14:40:50 -04003072 std::unique_ptr<SkString> runsStr(new SkString);
fmalitab7425172014-08-26 07:56:44 -07003073 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
fmalitaff3106c2014-12-09 05:28:20 -08003074 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
3075 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
Ben Wagner145dbcd2016-11-03 14:40:50 -04003076 fInfo.push(runsStr.get());
fmalitab7425172014-08-26 07:56:44 -07003077 fInfo.push(SkObjectParser::PaintToString(paint));
fmalitae77f2da2015-12-08 18:59:18 -08003078
3079 unsigned runs = 0;
3080 SkPaint runPaint(paint);
fmalita02526bd2016-09-14 14:55:59 -07003081 SkTextBlobRunIterator iter(fBlob.get());
fmalitae77f2da2015-12-08 18:59:18 -08003082 while (!iter.done()) {
Ben Wagner145dbcd2016-11-03 14:40:50 -04003083 std::unique_ptr<SkString> tmpStr(new SkString);
fmalita0d48e412016-01-04 08:08:04 -08003084 tmpStr->printf("==== Run [%d] ====", runs++);
3085 fInfo.push(tmpStr.release());
fmalitae77f2da2015-12-08 18:59:18 -08003086
3087 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
fmalita0d48e412016-01-04 08:08:04 -08003088 tmpStr.reset(new SkString("GlyphPositioning: "));
3089 tmpStr->append(gPositioningLabels[iter.positioning()]);
3090 fInfo.push(tmpStr.release());
3091
fmalitae77f2da2015-12-08 18:59:18 -08003092 iter.applyFontToPaint(&runPaint);
3093 fInfo.push(SkObjectParser::PaintToString(runPaint));
3094
3095 iter.next();
3096 }
3097
3098 runsStr->printf("Runs: %d", runs);
3099 // runStr is owned by fInfo at this point.
3100 runsStr.release();
fmalitab7425172014-08-26 07:56:44 -07003101}
3102
fmalita8c89c522014-11-08 16:18:56 -08003103void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07003104 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
3105}
3106
fmalita55773872014-08-29 15:08:20 -07003107bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
3108 canvas->clear(SK_ColorWHITE);
3109 canvas->save();
3110
3111 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
3112 xlate_and_scale_to_bounds(canvas, bounds);
3113
fmalita37283c22016-09-13 10:00:23 -07003114 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07003115
3116 canvas->restore();
3117
3118 return true;
3119}
3120
ethannicholasf62a8b72016-02-11 10:35:21 -08003121Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
3122 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003123 Json::Value runs(Json::arrayValue);
3124 SkTextBlobRunIterator iter(fBlob.get());
3125 while (!iter.done()) {
3126 Json::Value run(Json::objectValue);
3127 Json::Value jsonPositions(Json::arrayValue);
3128 Json::Value jsonGlyphs(Json::arrayValue);
3129 const SkScalar* iterPositions = iter.pos();
3130 const uint16_t* iterGlyphs = iter.glyphs();
3131 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
3132 switch (iter.positioning()) {
3133 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07003134 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
3135 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08003136 break;
3137 case SkTextBlob::kHorizontal_Positioning:
3138 jsonPositions.append(Json::Value(iterPositions[i]));
3139 break;
3140 case SkTextBlob::kDefault_Positioning:
3141 break;
3142 }
3143 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
3144 }
3145 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
3146 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
3147 }
3148 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
3149 SkPaint fontPaint;
3150 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07003151 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
3152 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08003153 runs.append(run);
3154 iter.next();
3155 }
reed6d2c3e72016-07-07 14:10:14 -07003156 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08003157 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
3158 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
3159 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07003160 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07003161 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07003162
3163 SkString desc;
3164 // make the bounds local by applying the x,y
3165 bounds.offset(fXPos, fYPos);
3166 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
3167
ethannicholas50a8dd02016-02-10 05:40:46 -08003168 return result;
3169}
3170
halcanary9d524f22016-03-29 09:03:52 -07003171SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003172 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003173 SkTextBlobBuilder builder;
3174 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
3175 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
3176 Json::Value run = runs[i];
3177 SkPaint font;
3178 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
ethannicholasf62a8b72016-02-11 10:35:21 -08003179 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
ethannicholas50a8dd02016-02-10 05:40:46 -08003180 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
3181 int count = glyphs.size();
3182 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3183 SkScalar x = coords[0].asFloat();
3184 SkScalar y = coords[1].asFloat();
reed6d2c3e72016-07-07 14:10:14 -07003185 SkRect bounds;
3186 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
3187
ethannicholas50a8dd02016-02-10 05:40:46 -08003188 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
3189 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3190 if (positions.size() > 0 && positions[0].isNumeric()) {
reed6d2c3e72016-07-07 14:10:14 -07003191 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003192 for (int j = 0; j < count; j++) {
3193 buffer.glyphs[j] = glyphs[j].asUInt();
3194 buffer.pos[j] = positions[j].asFloat();
3195 }
3196 }
3197 else {
reed6d2c3e72016-07-07 14:10:14 -07003198 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003199 for (int j = 0; j < count; j++) {
3200 buffer.glyphs[j] = glyphs[j].asUInt();
3201 buffer.pos[j * 2] = positions[j][0].asFloat();
3202 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
3203 }
3204 }
3205 }
3206 else {
reed6d2c3e72016-07-07 14:10:14 -07003207 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003208 for (int j = 0; j < count; j++) {
3209 buffer.glyphs[j] = glyphs[j].asUInt();
3210 }
3211 }
3212 }
3213 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
3214 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3215 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003216 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
fmalita37283c22016-09-13 10:00:23 -07003217 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003218}
3219
robertphillips9bafc302015-02-13 11:13:00 -08003220SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04003221 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08003222 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003223 : INHERITED(kDrawPatch_OpType)
3224 , fBlendMode(bmode)
3225{
robertphillips9bafc302015-02-13 11:13:00 -08003226 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08003227 if (colors != nullptr) {
3228 memcpy(fColors, colors, sizeof(fColors));
3229 fColorsPtr = fColors;
3230 } else {
3231 fColorsPtr = nullptr;
3232 }
3233 if (texCoords != nullptr) {
3234 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3235 fTexCoordsPtr = fTexCoords;
3236 } else {
3237 fTexCoordsPtr = nullptr;
3238 }
robertphillips9bafc302015-02-13 11:13:00 -08003239 fPaint = paint;
3240
3241 fInfo.push(SkObjectParser::PaintToString(paint));
3242}
3243
3244void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04003245 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08003246}
3247
ethannicholasf62a8b72016-02-11 10:35:21 -08003248Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3249 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08003250 Json::Value cubics = Json::Value(Json::arrayValue);
3251 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003252 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003253 }
3254 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3255 if (fColorsPtr != nullptr) {
3256 Json::Value colors = Json::Value(Json::arrayValue);
3257 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003258 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003259 }
3260 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3261 }
3262 if (fTexCoordsPtr != nullptr) {
3263 Json::Value texCoords = Json::Value(Json::arrayValue);
3264 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003265 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003266 }
3267 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3268 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003269 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08003270 return result;
3271}
3272
halcanary9d524f22016-03-29 09:03:52 -07003273SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003274 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08003275 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3276 SkPoint cubics[12];
3277 for (int i = 0; i < 12; i++) {
3278 cubics[i] = get_json_point(jsonCubics[i]);
3279 }
3280 SkColor* colorsPtr;
3281 SkColor colors[4];
3282 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3283 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3284 for (int i = 0; i < 4; i++) {
3285 colors[i] = get_json_color(jsonColors[i]);
3286 }
3287 colorsPtr = colors;
3288 }
3289 else {
3290 colorsPtr = nullptr;
3291 }
3292 SkPoint* texCoordsPtr;
3293 SkPoint texCoords[4];
3294 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3295 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3296 for (int i = 0; i < 4; i++) {
3297 texCoords[i] = get_json_point(jsonTexCoords[i]);
3298 }
3299 texCoordsPtr = texCoords;
3300 }
3301 else {
3302 texCoordsPtr = nullptr;
3303 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003304
3305 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3306
ethannicholas1446a9a2016-02-10 14:05:02 -08003307 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003308 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04003309 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
robertphillips9bafc302015-02-13 11:13:00 -08003310}
3311
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003312SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003313 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003314 fRect = rect;
3315 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003316
robertphillips@google.com91217d02013-03-17 18:33:46 +00003317 fInfo.push(SkObjectParser::RectToString(rect));
3318 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003319}
3320
fmalita8c89c522014-11-08 16:18:56 -08003321void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003322 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003323}
3324
ethannicholasf62a8b72016-02-11 10:35:21 -08003325Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3326 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07003327 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3328 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07003329
3330 SkString desc;
3331 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3332
ethannicholas50a8dd02016-02-10 05:40:46 -08003333 return result;
3334}
3335
halcanary9d524f22016-03-29 09:03:52 -07003336SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003337 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003338 SkRect coords;
3339 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3340 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003341 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003342 return new SkDrawRectCommand(coords, paint);
3343}
3344
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003345SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003346 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003347 fRRect = rrect;
3348 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00003349
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003350 fInfo.push(SkObjectParser::RRectToString(rrect));
3351 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00003352}
3353
fmalita8c89c522014-11-08 16:18:56 -08003354void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00003355 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00003356}
3357
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003358bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00003359 render_rrect(canvas, fRRect);
3360 return true;
3361}
3362
ethannicholasf62a8b72016-02-11 10:35:21 -08003363Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3364 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003365 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07003366 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003367 return result;
3368}
3369
halcanary9d524f22016-03-29 09:03:52 -07003370SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003371 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003372 SkRRect coords;
3373 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3374 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003375 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003376 return new SkDrawRRectCommand(coords, paint);
3377}
3378
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00003379SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003380 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003381 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003382 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003383 fOuter = outer;
3384 fInner = inner;
3385 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003386
3387 fInfo.push(SkObjectParser::RRectToString(outer));
3388 fInfo.push(SkObjectParser::RRectToString(inner));
3389 fInfo.push(SkObjectParser::PaintToString(paint));
3390}
3391
fmalita8c89c522014-11-08 16:18:56 -08003392void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003393 canvas->drawDRRect(fOuter, fInner, fPaint);
3394}
3395
3396bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3397 render_drrect(canvas, fOuter, fInner);
3398 return true;
3399}
3400
ethannicholasf62a8b72016-02-11 10:35:21 -08003401Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3402 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003403 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3404 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07003405 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003406 return result;
3407}
3408
halcanary9d524f22016-03-29 09:03:52 -07003409SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003410 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003411 SkRRect outer;
3412 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3413 SkRRect inner;
3414 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3415 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003416 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003417 return new SkDrawDRRectCommand(outer, inner, paint);
3418}
3419
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003420SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003421 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003422 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003423 fText = new char[byteLength];
3424 memcpy(fText, text, byteLength);
3425 fByteLength = byteLength;
3426 fX = x;
3427 fY = y;
3428 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003429
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003430 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3431 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
3432 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
3433 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003434}
3435
fmalita8c89c522014-11-08 16:18:56 -08003436void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003437 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003438}
3439
ethannicholasf62a8b72016-02-11 10:35:21 -08003440Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3441 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003442 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003443 ((const char*) fText) + fByteLength);
3444 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003445 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3446 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003447 return result;
3448}
3449
halcanary9d524f22016-03-29 09:03:52 -07003450SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003451 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003452 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3453 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003454 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003455 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
halcanary9d524f22016-03-29 09:03:52 -07003456 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08003457 paint);
3458}
3459
reed45561a02016-07-07 12:47:17 -07003460///////////////////////////////////////////////////////////////////////////////////////////////////
3461
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003462SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3463 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003464 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003465 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003466 fText = new char[byteLength];
3467 memcpy(fText, text, byteLength);
3468 fByteLength = byteLength;
3469 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07003470 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003471 fMatrix = *matrix;
3472 } else {
3473 fMatrix.setIdentity();
3474 }
3475 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003476
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003477 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3478 fInfo.push(SkObjectParser::PathToString(path));
bsalomon49f085d2014-09-05 13:34:00 -07003479 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003480 fInfo.push(SkObjectParser::MatrixToString(*matrix));
3481 }
3482 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003483}
3484
fmalita8c89c522014-11-08 16:18:56 -08003485void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003486 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07003487 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003488 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003489}
3490
ethannicholasf62a8b72016-02-11 10:35:21 -08003491Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3492 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003493 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003494 ((const char*) fText) + fByteLength);
3495 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003496 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08003497 if (!fMatrix.isIdentity()) {
joshualittbd724132016-03-03 11:39:38 -08003498 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003499 }
brianosmanfad98562016-05-04 11:06:28 -07003500 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003501 return result;
3502}
3503
halcanary9d524f22016-03-29 09:03:52 -07003504SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003505 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003506 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3507 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003508 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003509 SkPath path;
3510 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3511 SkMatrix* matrixPtr;
3512 SkMatrix matrix;
3513 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3514 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3515 matrixPtr = &matrix;
3516 }
3517 else {
3518 matrixPtr = nullptr;
3519 }
3520 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3521}
3522
reed45561a02016-07-07 12:47:17 -07003523///////////////////////////////////////////////////////////////////////////////////////////////////
3524
3525SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3526 const SkRSXform xform[], const SkRect* cull,
3527 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07003528 : INHERITED(kDrawTextRSXform_OpType)
reed45561a02016-07-07 12:47:17 -07003529{
3530 fText = new char[byteLength];
3531 memcpy(fText, text, byteLength);
3532 fByteLength = byteLength;
3533 int count = paint.countText(text, byteLength);
3534 fXform = new SkRSXform[count];
3535 memcpy(fXform, xform, count * sizeof(SkRSXform));
3536 if (cull) {
3537 fCullStorage = *cull;
3538 fCull = &fCullStorage;
3539 } else {
3540 fCull = nullptr;
3541 }
3542 fPaint = paint;
3543
3544 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3545 fInfo.push(SkObjectParser::PaintToString(paint));
3546}
3547
3548void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3549 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3550}
3551
3552Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3553 Json::Value result = INHERITED::toJSON(urlDataManager);
3554 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3555 ((const char*) fText) + fByteLength);
3556 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3557 return result;
3558}
3559
3560SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3561 UrlDataManager& urlDataManager) {
3562 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3563 size_t byteLength = strlen(text);
3564 SkPaint paint;
3565 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3566
3567 // TODO: handle xform and cull
3568 int count = paint.countText(text, byteLength);
3569 SkAutoTArray<SkRSXform> xform(count);
3570 for (int i = 0; i < count; ++i) {
3571 xform[i].fSCos = 1;
3572 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3573 }
3574 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3575}
3576
3577///////////////////////////////////////////////////////////////////////////////////////////////////
3578
Mike Reedfed9cfd2017-03-17 12:09:04 -04003579SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003580 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003581 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003582 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04003583 , fBlendMode(bmode)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003584 , fPaint(paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003585{
chudy@google.com902ebe52012-06-29 14:21:22 +00003586 // TODO(chudy)
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003587 fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
3588 fInfo.push(SkObjectParser::PaintToString(paint));
3589}
3590
fmalita8c89c522014-11-08 16:18:56 -08003591void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04003592 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003593}
3594
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003595SkRestoreCommand::SkRestoreCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003596 : INHERITED(kRestore_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003597 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
chudy@google.com902ebe52012-06-29 14:21:22 +00003598}
3599
fmalita8c89c522014-11-08 16:18:56 -08003600void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00003601 canvas->restore();
3602}
3603
ethannicholasf62a8b72016-02-11 10:35:21 -08003604SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003605 return new SkRestoreCommand();
3606}
3607
Florin Malita5f6102d2014-06-30 10:13:28 -04003608SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003609 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00003610}
3611
fmalita8c89c522014-11-08 16:18:56 -08003612void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04003613 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00003614}
3615
ethannicholasf62a8b72016-02-11 10:35:21 -08003616SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003617 return new SkSaveCommand();
3618}
3619
reed4960eee2015-12-18 07:09:18 -08003620SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08003621 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08003622 if (rec.fBounds) {
3623 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003624 } else {
3625 fBounds.setEmpty();
3626 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003627
reed4960eee2015-12-18 07:09:18 -08003628 if (rec.fPaint) {
3629 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003630 fPaintPtr = &fPaint;
3631 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07003632 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003633 }
reed4960eee2015-12-18 07:09:18 -08003634 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003635
ethannicholas50a8dd02016-02-10 05:40:46 -08003636 if (rec.fBackdrop) {
3637 fBackdrop = rec.fBackdrop;
3638 fBackdrop->ref();
3639 } else {
3640 fBackdrop = nullptr;
3641 }
3642
reed4960eee2015-12-18 07:09:18 -08003643 if (rec.fBounds) {
3644 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003645 }
reed4960eee2015-12-18 07:09:18 -08003646 if (rec.fPaint) {
3647 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003648 }
reed4960eee2015-12-18 07:09:18 -08003649 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003650}
3651
ethannicholas50a8dd02016-02-10 05:40:46 -08003652SkSaveLayerCommand::~SkSaveLayerCommand() {
3653 if (fBackdrop != nullptr) {
3654 fBackdrop->unref();
3655 }
3656}
3657
fmalita8c89c522014-11-08 16:18:56 -08003658void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08003659 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3660 fPaintPtr,
3661 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003662}
3663
fmalita8c89c522014-11-08 16:18:56 -08003664void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
commit-bot@chromium.org1643b2c2014-03-03 23:25:41 +00003665 canvas->save();
3666}
3667
ethannicholasf62a8b72016-02-11 10:35:21 -08003668Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3669 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003670 if (!fBounds.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07003671 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003672 }
3673 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07003674 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
ethannicholasf62a8b72016-02-11 10:35:21 -08003675 urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003676 }
3677 if (fBackdrop != nullptr) {
3678 Json::Value jsonBackdrop;
ethannicholasf62a8b72016-02-11 10:35:21 -08003679 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003680 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3681 }
3682 if (fSaveLayerFlags != 0) {
3683 SkDebugf("unsupported: saveLayer flags\n");
3684 SkASSERT(false);
3685 }
3686 return result;
3687}
3688
halcanary9d524f22016-03-29 09:03:52 -07003689SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003690 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003691 SkCanvas::SaveLayerRec rec;
3692 SkRect bounds;
3693 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3694 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3695 rec.fBounds = &bounds;
3696 }
3697 SkPaint paint;
3698 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08003699 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003700 rec.fPaint = &paint;
3701 }
3702 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3703 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
ethannicholasf62a8b72016-02-11 10:35:21 -08003704 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003705 }
3706 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3707 if (rec.fBackdrop != nullptr) {
3708 rec.fBackdrop->unref();
3709 }
3710 return result;
3711}
3712
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003713SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08003714 : INHERITED(kSetMatrix_OpType) {
robertphillips70171682014-10-16 14:28:28 -07003715 fUserMatrix.reset();
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003716 fMatrix = matrix;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003717 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00003718}
3719
robertphillips70171682014-10-16 14:28:28 -07003720void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
3721 fUserMatrix = userMatrix;
3722}
3723
fmalita8c89c522014-11-08 16:18:56 -08003724void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
robertphillips70171682014-10-16 14:28:28 -07003725 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
3726 canvas->setMatrix(temp);
chudy@google.com902ebe52012-06-29 14:21:22 +00003727}
3728
ethannicholasf62a8b72016-02-11 10:35:21 -08003729Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3730 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08003731 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003732 return result;
3733}
3734
halcanary9d524f22016-03-29 09:03:52 -07003735SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003736 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003737 SkMatrix matrix;
3738 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3739 return new SkSetMatrixCommand(matrix);
3740}