blob: 2dc11f4ef5b350d72922dfdd32bc2210456cd86d [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 "SkColorFilter.h"
14#include "SkDashPathEffect.h"
15#include "SkImageFilter.h"
brianosmanfad98562016-05-04 11:06:28 -070016#include "SkJsonWriteBuffer.h"
Mike Reed80747ef2018-01-23 15:29:32 -050017#include "SkMaskFilterBase.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080018#include "SkPaintDefaults.h"
19#include "SkPathEffect.h"
robertphillips9bafc302015-02-13 11:13:00 -080020#include "SkPicture.h"
Mike Reedfadbfcd2017-12-06 16:09:20 -050021#include "SkReadBuffer.h"
Mike Reed185ffe92018-01-08 17:09:54 -050022#include "SkRectPriv.h"
fmalitab7425172014-08-26 07:56:44 -070023#include "SkTextBlob.h"
fmalitae77f2da2015-12-08 18:59:18 -080024#include "SkTextBlobRunIterator.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080025#include "SkTHash.h"
26#include "SkTypeface.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080027#include "SkWriteBuffer.h"
msaretta5cf4f42016-06-30 10:06:51 -070028#include "picture_utils.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050029#include "SkClipOpPriv.h"
Stan Ilievac42aeb2017-01-12 16:20:50 -050030#include <SkLatticeIter.h>
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -040031#include <SkShadowFlags.h>
ethannicholas50a8dd02016-02-10 05:40:46 -080032
ethannicholas50a8dd02016-02-10 05:40:46 -080033#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
ethannicholas807dcab2016-02-23 06:53:37 -080034#define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
ethannicholas50a8dd02016-02-10 05:40:46 -080035#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
vjiaoblacke5de1302016-07-13 14:05:28 -070036#define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
ethannicholas50a8dd02016-02-10 05:40:46 -080037#define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
halcanaryf412f092016-08-25 11:10:41 -070038#define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
ethannicholas50a8dd02016-02-10 05:40:46 -080039#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
40#define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
41#define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
42#define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
43#define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
44#define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
45#define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
46#define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
47#define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
48#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Florin Malita82d80872017-06-06 16:58:40 -040049#define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
ethannicholas50a8dd02016-02-10 05:40:46 -080050#define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
51#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
52#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
ethannicholas1446a9a2016-02-10 14:05:02 -080053#define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
ethannicholas50a8dd02016-02-10 05:40:46 -080054#define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
55#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
ethannicholas1446a9a2016-02-10 14:05:02 -080056#define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
Ben Wagner78f1f5a2017-06-23 14:35:07 -040057#define SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
58#define SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
59#define SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
60#define SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
61#define SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
62#define SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
63#define SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
64#define SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT "verticalText"
ethannicholas50a8dd02016-02-10 05:40:46 -080065#define SKDEBUGCANVAS_ATTRIBUTE_REGION "region"
66#define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
67#define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
68#define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
69#define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur"
70#define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
71#define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
72#define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign"
73#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
74#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
75#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
76#define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
77#define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
78#define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
79#define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
80#define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
81#define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
ethannicholasf62a8b72016-02-11 10:35:21 -080082#define SKDEBUGCANVAS_ATTRIBUTE_DATA "data"
brianosmanfad98562016-05-04 11:06:28 -070083#define SKDEBUGCANVAS_ATTRIBUTE_VALUES "values"
ethannicholas50a8dd02016-02-10 05:40:46 -080084#define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
85#define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
86#define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
87#define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
ethannicholas1446a9a2016-02-10 14:05:02 -080088#define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
ethannicholas50a8dd02016-02-10 05:40:46 -080089#define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
90#define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
91#define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
92#define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
93#define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
94#define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
95#define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
96#define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
97#define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
98#define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
99#define SKDEBUGCANVAS_ATTRIBUTE_X "x"
100#define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
101#define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
102#define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
103#define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
104#define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
105#define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
ethannicholas1446a9a2016-02-10 14:05:02 -0800106#define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
107#define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors"
108#define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
109#define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
bsalomonac3aa242016-08-19 11:25:19 -0700110#define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
111#define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
112#define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
jcgregorioee0c5552016-06-30 09:18:27 -0700113#define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
msarett0ac1bec2016-08-29 09:15:33 -0700114#define SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
115#define SKDEBUGCANVAS_ATTRIBUTE_WIDTH "width"
116#define SKDEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
117#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Stan Ilievac42aeb2017-01-12 16:20:50 -0500118#define SKDEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
119#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
120#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
121#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
122#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
123#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400124#define SKDEBUGCANVAS_ATTRIBUTE_ZPLANE "zPlane"
125#define SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION "lightPositions"
126#define SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR "ambientColor"
127#define SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR "spotColor"
128#define SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS "lightRadius"
reed67f62fa2016-06-29 11:36:34 -0700129
ethannicholas50a8dd02016-02-10 05:40:46 -0800130#define SKDEBUGCANVAS_VERB_MOVE "move"
131#define SKDEBUGCANVAS_VERB_LINE "line"
132#define SKDEBUGCANVAS_VERB_QUAD "quad"
133#define SKDEBUGCANVAS_VERB_CUBIC "cubic"
134#define SKDEBUGCANVAS_VERB_CONIC "conic"
135#define SKDEBUGCANVAS_VERB_CLOSE "close"
136
137#define SKDEBUGCANVAS_STYLE_FILL "fill"
138#define SKDEBUGCANVAS_STYLE_STROKE "stroke"
139#define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
140
141#define SKDEBUGCANVAS_POINTMODE_POINTS "points"
142#define SKDEBUGCANVAS_POINTMODE_LINES "lines"
143#define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
144
145#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
146#define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
147#define SKDEBUGCANVAS_REGIONOP_UNION "union"
148#define SKDEBUGCANVAS_REGIONOP_XOR "xor"
149#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
150#define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
151
152#define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
153#define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
154#define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
155#define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
156
157#define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
158#define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
159
160#define SKDEBUGCANVAS_ALIGN_LEFT "left"
161#define SKDEBUGCANVAS_ALIGN_CENTER "center"
162#define SKDEBUGCANVAS_ALIGN_RIGHT "right"
163
164#define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
165#define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
166#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
167#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
168
169#define SKDEBUGCANVAS_CAP_BUTT "butt"
170#define SKDEBUGCANVAS_CAP_ROUND "round"
171#define SKDEBUGCANVAS_CAP_SQUARE "square"
172
ethannicholas1446a9a2016-02-10 14:05:02 -0800173#define SKDEBUGCANVAS_MITER_JOIN "miter"
174#define SKDEBUGCANVAS_ROUND_JOIN "round"
175#define SKDEBUGCANVAS_BEVEL_JOIN "bevel"
176
ethannicholas50a8dd02016-02-10 05:40:46 -0800177#define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
178#define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
179#define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
180#define SKDEBUGCANVAS_COLORTYPE_565 "565"
181#define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
182#define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
183#define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
184
185#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
186#define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
187#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
msarett0ac1bec2016-08-29 09:15:33 -0700188#define SKDEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
ethannicholas50a8dd02016-02-10 05:40:46 -0800189
ethannicholas1446a9a2016-02-10 14:05:02 -0800190#define SKDEBUGCANVAS_FILTERQUALITY_NONE "none"
191#define SKDEBUGCANVAS_FILTERQUALITY_LOW "low"
192#define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
193#define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high"
194
halcanaryf412f092016-08-25 11:10:41 -0700195#define SKDEBUGCANVAS_HINTING_NONE "none"
196#define SKDEBUGCANVAS_HINTING_SLIGHT "slight"
197#define SKDEBUGCANVAS_HINTING_NORMAL "normal"
198#define SKDEBUGCANVAS_HINTING_FULL "full"
199
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400200#define SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC "transparentOccluder"
201#define SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY "geometricOnly"
202
ethannicholasf62a8b72016-02-11 10:35:21 -0800203typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&);
fmalitab7425172014-08-26 07:56:44 -0700204
reed67f62fa2016-06-29 11:36:34 -0700205static SkString* str_append(SkString* str, const SkRect& r) {
206 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
207 return str;
208}
209
chudy@google.com902ebe52012-06-29 14:21:22 +0000210// TODO(chudy): Refactor into non subclass model.
211
robertphillips9bafc302015-02-13 11:13:00 -0800212SkDrawCommand::SkDrawCommand(OpType type)
213 : fOpType(type)
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000214 , fVisible(true) {
215}
216
robertphillips9bafc302015-02-13 11:13:00 -0800217const char* SkDrawCommand::GetCommandString(OpType type) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000218 switch (type) {
fmalita160ebb22015-04-01 20:58:37 -0700219 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
Brian Osmanc25e2692018-03-12 10:57:28 -0400220 case kClear_OpType: return "DrawClear";
robertphillips9bafc302015-02-13 11:13:00 -0800221 case kClipPath_OpType: return "ClipPath";
222 case kClipRegion_OpType: return "ClipRegion";
223 case kClipRect_OpType: return "ClipRect";
224 case kClipRRect_OpType: return "ClipRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800225 case kConcat_OpType: return "Concat";
robertphillipsfb409232016-06-29 10:28:11 -0700226 case kDrawAnnotation_OpType: return "DrawAnnotation";
robertphillips9bafc302015-02-13 11:13:00 -0800227 case kDrawBitmap_OpType: return "DrawBitmap";
Brian Osman78a76482018-05-18 16:59:13 -0400228 case kDrawBitmapLattice_OpType: return "DrawBitmapLattice";
robertphillips9bafc302015-02-13 11:13:00 -0800229 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
230 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
robertphillips9bafc302015-02-13 11:13:00 -0800231 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700232 case kDrawImage_OpType: return "DrawImage";
Stan Ilievac42aeb2017-01-12 16:20:50 -0500233 case kDrawImageLattice_OpType: return "DrawImageLattice";
Brian Osmanc25e2692018-03-12 10:57:28 -0400234 case kDrawImageNine_OpType: return "DrawImageNine";
fmalita651c9202015-07-22 10:23:01 -0700235 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800236 case kDrawOval_OpType: return "DrawOval";
237 case kDrawPaint_OpType: return "DrawPaint";
238 case kDrawPatch_OpType: return "DrawPatch";
239 case kDrawPath_OpType: return "DrawPath";
Brian Osmanc25e2692018-03-12 10:57:28 -0400240 case kDrawArc_OpType: return "DrawArc";
robertphillips9bafc302015-02-13 11:13:00 -0800241 case kDrawPoints_OpType: return "DrawPoints";
242 case kDrawPosText_OpType: return "DrawPosText";
243 case kDrawPosTextH_OpType: return "DrawPosTextH";
244 case kDrawRect_OpType: return "DrawRect";
245 case kDrawRRect_OpType: return "DrawRRect";
Brian Osmanc25e2692018-03-12 10:57:28 -0400246 case kDrawRegion_OpType: return "DrawRegion";
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400247 case kDrawShadow_OpType: return "DrawShadow";
robertphillips9bafc302015-02-13 11:13:00 -0800248 case kDrawText_OpType: return "DrawText";
249 case kDrawTextBlob_OpType: return "DrawTextBlob";
250 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
reed63f30d92016-07-07 16:32:51 -0700251 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
robertphillips9bafc302015-02-13 11:13:00 -0800252 case kDrawVertices_OpType: return "DrawVertices";
fmalita160ebb22015-04-01 20:58:37 -0700253 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800254 case kRestore_OpType: return "Restore";
255 case kSave_OpType: return "Save";
256 case kSaveLayer_OpType: return "SaveLayer";
257 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000258 default:
robertphillips9bafc302015-02-13 11:13:00 -0800259 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000260 SkASSERT(0);
261 break;
262 }
263 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700264 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000265}
266
ethannicholasf62a8b72016-02-11 10:35:21 -0800267Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800268 Json::Value result;
269 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800270 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800271 return result;
272}
273
274#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
275 (FROM_JSON) Sk ## name ## Command::fromJSON)
ethannicholasf62a8b72016-02-11 10:35:21 -0800276SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800277 static SkTHashMap<SkString, FROM_JSON> factories;
278 static bool initialized = false;
279 if (!initialized) {
280 initialized = true;
281 INSTALL_FACTORY(Restore);
Brian Osmanc25e2692018-03-12 10:57:28 -0400282 INSTALL_FACTORY(Clear);
ethannicholas50a8dd02016-02-10 05:40:46 -0800283 INSTALL_FACTORY(ClipPath);
284 INSTALL_FACTORY(ClipRegion);
285 INSTALL_FACTORY(ClipRect);
286 INSTALL_FACTORY(ClipRRect);
287 INSTALL_FACTORY(Concat);
reed97660cc2016-06-28 18:54:19 -0700288 INSTALL_FACTORY(DrawAnnotation);
ethannicholas50a8dd02016-02-10 05:40:46 -0800289 INSTALL_FACTORY(DrawBitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800290 INSTALL_FACTORY(DrawBitmapNine);
Brian Osmanc25e2692018-03-12 10:57:28 -0400291 INSTALL_FACTORY(DrawBitmapRect);
ethannicholas50a8dd02016-02-10 05:40:46 -0800292 INSTALL_FACTORY(DrawImage);
Brian Osmanc25e2692018-03-12 10:57:28 -0400293 INSTALL_FACTORY(DrawImageLattice);
294 INSTALL_FACTORY(DrawImageNine);
ethannicholas50a8dd02016-02-10 05:40:46 -0800295 INSTALL_FACTORY(DrawImageRect);
296 INSTALL_FACTORY(DrawOval);
Brian Osmanc25e2692018-03-12 10:57:28 -0400297 INSTALL_FACTORY(DrawArc);
ethannicholas50a8dd02016-02-10 05:40:46 -0800298 INSTALL_FACTORY(DrawPaint);
299 INSTALL_FACTORY(DrawPath);
300 INSTALL_FACTORY(DrawPoints);
Brian Osmanc25e2692018-03-12 10:57:28 -0400301 INSTALL_FACTORY(DrawRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -0800302 INSTALL_FACTORY(DrawText);
303 INSTALL_FACTORY(DrawPosText);
bungeman51190df2016-03-09 07:42:54 -0800304 INSTALL_FACTORY(DrawPosTextH);
ethannicholas50a8dd02016-02-10 05:40:46 -0800305 INSTALL_FACTORY(DrawTextOnPath);
reed45561a02016-07-07 12:47:17 -0700306 INSTALL_FACTORY(DrawTextRSXform);
ethannicholas50a8dd02016-02-10 05:40:46 -0800307 INSTALL_FACTORY(DrawTextBlob);
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400308 INSTALL_FACTORY(DrawShadow);
ethannicholas50a8dd02016-02-10 05:40:46 -0800309 INSTALL_FACTORY(DrawRect);
310 INSTALL_FACTORY(DrawRRect);
311 INSTALL_FACTORY(DrawDRRect);
ethannicholas1446a9a2016-02-10 14:05:02 -0800312 INSTALL_FACTORY(DrawPatch);
ethannicholas50a8dd02016-02-10 05:40:46 -0800313 INSTALL_FACTORY(Save);
314 INSTALL_FACTORY(SaveLayer);
315 INSTALL_FACTORY(SetMatrix);
316 }
317 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
318 FROM_JSON* factory = factories.find(name);
319 if (factory == nullptr) {
320 SkDebugf("no JSON factory for '%s'\n", name.c_str());
321 return nullptr;
322 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800323 return (*factory)(command, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800324}
325
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000326namespace {
327
328void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500329 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000330
331 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
332
333 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
334 if (bounds.width() > bounds.height()) {
335 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
336 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
337 } else {
338 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
339 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
340 }
341 canvas->translate(-bounds.centerX(), -bounds.centerY());
342}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000343
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000344
345void render_path(SkCanvas* canvas, const SkPath& path) {
346 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000347
348 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700349 if (bounds.isEmpty()) {
350 return;
351 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000352
fmalitab0cd8b72015-10-06 07:24:03 -0700353 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000354 xlate_and_scale_to_bounds(canvas, bounds);
355
356 SkPaint p;
357 p.setColor(SK_ColorBLACK);
358 p.setStyle(SkPaint::kStroke_Style);
359
360 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000361}
362
Brian Osmanc25e2692018-03-12 10:57:28 -0400363void render_region(SkCanvas* canvas, const SkRegion& region) {
364 canvas->clear(0xFFFFFFFF);
365
366 const SkIRect& bounds = region.getBounds();
367 if (bounds.isEmpty()) {
368 return;
369 }
370
371 SkAutoCanvasRestore acr(canvas, true);
Brian Osman99b63402018-03-13 10:19:27 -0400372 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
Brian Osmanc25e2692018-03-12 10:57:28 -0400373
374 SkPaint p;
375 p.setColor(SK_ColorBLACK);
376 p.setStyle(SkPaint::kStroke_Style);
377
378 canvas->drawRegion(region, p);
379}
380
halcanary96fcdcc2015-08-27 07:41:13 -0700381void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500382 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000383
384 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
385 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
386
387 if (input.width() > input.height()) {
388 yScale *= input.height() / (float) input.width();
389 } else {
390 xScale *= input.width() / (float) input.height();
391 }
392
393 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
394 xScale * input.width(),
395 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000396
robertphillips96a5cff2015-09-24 06:56:27 -0700397 static const int kNumBlocks = 8;
398
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000399 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700400 SkISize block = {
401 canvas->imageInfo().width()/kNumBlocks,
402 canvas->imageInfo().height()/kNumBlocks
403 };
404 for (int y = 0; y < kNumBlocks; ++y) {
405 for (int x = 0; x < kNumBlocks; ++x) {
406 SkPaint paint;
407 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
408 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
409 SkIntToScalar(y*block.height()),
410 SkIntToScalar(block.width()),
411 SkIntToScalar(block.height()));
412 canvas->drawRect(r, paint);
413 }
414 }
415
reede47829b2015-08-06 10:02:53 -0700416 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000417
bsalomon49f085d2014-09-05 13:34:00 -0700418 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000419 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
420 srcRect->fTop * yScale + SK_Scalar1,
421 srcRect->fRight * xScale + SK_Scalar1,
422 srcRect->fBottom * yScale + SK_Scalar1);
423 SkPaint p;
424 p.setColor(SK_ColorRED);
425 p.setStyle(SkPaint::kStroke_Style);
426
427 canvas->drawRect(r, p);
428 }
429}
430
431void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
432 canvas->clear(0xFFFFFFFF);
433 canvas->save();
434
435 const SkRect& bounds = rrect.getBounds();
436
437 xlate_and_scale_to_bounds(canvas, bounds);
438
439 SkPaint p;
440 p.setColor(SK_ColorBLACK);
441 p.setStyle(SkPaint::kStroke_Style);
442
443 canvas->drawRRect(rrect, p);
444 canvas->restore();
445}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000446
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000447void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
448 canvas->clear(0xFFFFFFFF);
449 canvas->save();
450
451 const SkRect& bounds = outer.getBounds();
452
453 xlate_and_scale_to_bounds(canvas, bounds);
454
455 SkPaint p;
456 p.setColor(SK_ColorBLACK);
457 p.setStyle(SkPaint::kStroke_Style);
458
459 canvas->drawDRRect(outer, inner, p);
460 canvas->restore();
461}
462
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400463void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
464 canvas->clear(0xFFFFFFFF);
465
466 const SkRect& bounds = path.getBounds();
467 if (bounds.isEmpty()) {
468 return;
469 }
470
471 SkAutoCanvasRestore acr(canvas, true);
472 xlate_and_scale_to_bounds(canvas, bounds);
473
474 rec.fAmbientColor = SK_ColorBLACK;
475 rec.fSpotColor = SK_ColorBLACK;
476 canvas->private_draw_shadow_rec(path, rec);
477}
478
Florin Malita82d80872017-06-06 16:58:40 -0400479static const char* const gBlendModeMap[] = {
480 "clear",
481 "src",
482 "dst",
483 "srcOver",
484 "dstOver",
485 "srcIn",
486 "dstIn",
487 "srcOut",
488 "dstOut",
489 "srcATop",
490 "dstATop",
491 "xor",
492 "plus",
493 "modulate",
494
495 "screen",
496
497 "overlay",
498 "darken",
499 "lighten",
500 "colorDodge",
501 "colorBurn",
502 "hardLight",
503 "softLight",
504 "difference",
505 "exclusion",
506 "multiply",
507
508 "hue",
509 "saturation",
510 "color",
511 "luminosity",
512};
513
514static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
515 "blendMode mismatch");
516static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
517 "blendMode mismatch");
518
519void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
520 const auto mode = paint.getBlendMode();
521 if (mode != SkBlendMode::kSrcOver) {
522 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
523 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
524 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
525 }
526}
527
528void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
529 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
530 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
531
532 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
533 if (!strcmp(mode, gBlendModeMap[i])) {
534 target->setBlendMode(static_cast<SkBlendMode>(i));
535 break;
536 }
537 }
538 }
539}
540
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000541};
542
brianosmanfad98562016-05-04 11:06:28 -0700543Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800544 Json::Value result(Json::arrayValue);
545 result.append(Json::Value(SkColorGetA(color)));
546 result.append(Json::Value(SkColorGetR(color)));
547 result.append(Json::Value(SkColorGetG(color)));
548 result.append(Json::Value(SkColorGetB(color)));
549 return result;
550}
551
brianosman97bbf822016-09-25 13:15:58 -0700552Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
553 Json::Value result(Json::arrayValue);
554 result.append(Json::Value(color.fA));
555 result.append(Json::Value(color.fR));
556 result.append(Json::Value(color.fG));
557 result.append(Json::Value(color.fB));
558 return result;
559}
560
brianosmanfad98562016-05-04 11:06:28 -0700561Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800562 Json::Value result(Json::arrayValue);
563 result.append(Json::Value(point.x()));
564 result.append(Json::Value(point.y()));
565 return result;
566}
567
brianosmanfad98562016-05-04 11:06:28 -0700568Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800569 Json::Value result(Json::arrayValue);
570 result.append(Json::Value(x));
571 result.append(Json::Value(y));
572 return result;
573}
574
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400575Json::Value SkDrawCommand::MakeJsonPoint3(const SkPoint3& point) {
576 Json::Value result(Json::arrayValue);
577 result.append(Json::Value(point.x()));
578 result.append(Json::Value(point.y()));
579 result.append(Json::Value(point.z()));
580 return result;
581}
582
brianosmanfad98562016-05-04 11:06:28 -0700583Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800584 Json::Value result(Json::arrayValue);
585 result.append(Json::Value(rect.left()));
586 result.append(Json::Value(rect.top()));
587 result.append(Json::Value(rect.right()));
588 result.append(Json::Value(rect.bottom()));
589 return result;
590}
591
joshualittbd724132016-03-03 11:39:38 -0800592Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800593 Json::Value result(Json::arrayValue);
594 result.append(Json::Value(rect.left()));
595 result.append(Json::Value(rect.top()));
596 result.append(Json::Value(rect.right()));
597 result.append(Json::Value(rect.bottom()));
598 return result;
599}
600
601static Json::Value make_json_rrect(const SkRRect& rrect) {
602 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700603 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
604 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
605 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
606 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
607 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800608 return result;
609}
610
joshualittbd724132016-03-03 11:39:38 -0800611Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800612 Json::Value result(Json::arrayValue);
613 Json::Value row1(Json::arrayValue);
614 row1.append(Json::Value(matrix[0]));
615 row1.append(Json::Value(matrix[1]));
616 row1.append(Json::Value(matrix[2]));
617 result.append(row1);
618 Json::Value row2(Json::arrayValue);
619 row2.append(Json::Value(matrix[3]));
620 row2.append(Json::Value(matrix[4]));
621 row2.append(Json::Value(matrix[5]));
622 result.append(row2);
623 Json::Value row3(Json::arrayValue);
624 row3.append(Json::Value(matrix[6]));
625 row3.append(Json::Value(matrix[7]));
626 row3.append(Json::Value(matrix[8]));
627 result.append(row3);
628 return result;
629}
ethannicholas1446a9a2016-02-10 14:05:02 -0800630
vjiaoblacke5de1302016-07-13 14:05:28 -0700631Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
632 Json::Value result(z);
633 return result;
634}
635
brianosmanfad98562016-05-04 11:06:28 -0700636Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800637 Json::Value result(Json::objectValue);
638 switch (path.getFillType()) {
639 case SkPath::kWinding_FillType:
640 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
641 break;
642 case SkPath::kEvenOdd_FillType:
643 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
644 break;
645 case SkPath::kInverseWinding_FillType:
646 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
647 break;
648 case SkPath::kInverseEvenOdd_FillType:
649 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
650 break;
halcanary9d524f22016-03-29 09:03:52 -0700651 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800652 Json::Value verbs(Json::arrayValue);
653 SkPath::Iter iter(path, false);
654 SkPoint pts[4];
655 SkPath::Verb verb;
656 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
657 switch (verb) {
658 case SkPath::kLine_Verb: {
659 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700660 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800661 verbs.append(line);
662 break;
663 }
664 case SkPath::kQuad_Verb: {
665 Json::Value quad(Json::objectValue);
666 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700667 coords.append(MakeJsonPoint(pts[1]));
668 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800669 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
670 verbs.append(quad);
671 break;
672 }
673 case SkPath::kCubic_Verb: {
674 Json::Value cubic(Json::objectValue);
675 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700676 coords.append(MakeJsonPoint(pts[1]));
677 coords.append(MakeJsonPoint(pts[2]));
678 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800679 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
680 verbs.append(cubic);
681 break;
682 }
683 case SkPath::kConic_Verb: {
684 Json::Value conic(Json::objectValue);
685 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700686 coords.append(MakeJsonPoint(pts[1]));
687 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800688 coords.append(Json::Value(iter.conicWeight()));
689 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
690 verbs.append(conic);
691 break;
692 }
693 case SkPath::kMove_Verb: {
694 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700695 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800696 verbs.append(move);
697 break;
698 }
699 case SkPath::kClose_Verb:
700 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
701 break;
702 case SkPath::kDone_Verb:
703 break;
704 }
705 }
706 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
707 return result;
708}
709
brianosmanfad98562016-05-04 11:06:28 -0700710Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
Brian Osmanc25e2692018-03-12 10:57:28 -0400711 // TODO: Actually serialize the rectangles, rather than just devolving to path
712 SkPath path;
713 region.getBoundaryPath(&path);
714 return MakeJsonPath(path);
ethannicholas50a8dd02016-02-10 05:40:46 -0800715}
716
Mike Reedc1f77742016-12-09 09:00:50 -0500717static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800718 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500719 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800720 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500721 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800722 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500723 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800724 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500725 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800726 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500727 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800728 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500729 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800730 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
731 default:
732 SkASSERT(false);
733 return Json::Value("<invalid region op>");
734 };
735}
736
737static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
738 switch (mode) {
739 case SkCanvas::kPoints_PointMode:
740 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
741 case SkCanvas::kLines_PointMode:
742 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700743 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800744 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
745 default:
746 SkASSERT(false);
747 return Json::Value("<invalid point mode>");
748 };
749}
750
halcanary9d524f22016-03-29 09:03:52 -0700751static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800752 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800753 if (value != defaultValue) {
754 (*target)[key] = Json::Value(value);
755 }
756}
757
ethannicholasbd3dae82016-02-10 12:10:00 -0800758static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800759 if (value != defaultValue) {
760 (*target)[key] = Json::Value(value);
761 }
762}
763
halcanary9d524f22016-03-29 09:03:52 -0700764static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800765 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700766 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
767 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800768 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800769}
770
brianosmanfad98562016-05-04 11:06:28 -0700771void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
772 UrlDataManager& urlDataManager) {
773 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800774 flattenable->flatten(buffer);
775 void* data = sk_malloc_throw(buffer.bytesWritten());
776 buffer.writeToMemory(data);
777 Json::Value jsonData;
778 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
779 Json::Value jsonFlattenable;
780 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
781 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700782
783 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
784 flattenable->flatten(jsonBuffer);
785 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
786
ethannicholasf62a8b72016-02-11 10:35:21 -0800787 (*target) = jsonFlattenable;
788 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800789}
790
ethannicholasf67531f2016-03-21 10:19:39 -0700791static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
792 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
793 out->write(data, length);
794}
795
halcanarya73d76a2016-10-17 13:19:02 -0700796void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700797 SkWStream& out, bool isOpaque) {
Ben Wagnera93a14a2017-08-28 10:34:05 -0400798 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700799 SkASSERT(png != nullptr);
800 png_infop info_ptr = png_create_info_struct(png);
801 SkASSERT(info_ptr != nullptr);
802 if (setjmp(png_jmpbuf(png))) {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400803 SK_ABORT("png encode error");
ethannicholasf67531f2016-03-21 10:19:39 -0700804 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400805 png_set_write_fn(png, &out, write_png_callback, nullptr);
msaretta5cf4f42016-06-30 10:06:51 -0700806 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
807 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700808 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
809 png_set_compression_level(png, 1);
810 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700811 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700812 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700813 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700814 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700815 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700816 rows[y][x * 4] = src[x * 4];
817 rows[y][x * 4 + 1] = src[x * 4 + 1];
818 rows[y][x * 4 + 2] = src[x * 4 + 2];
819 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700820 }
821 }
msaretta5cf4f42016-06-30 10:06:51 -0700822 png_write_info(png, info_ptr);
823 if (isOpaque) {
824 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
825 }
ethannicholasf67531f2016-03-21 10:19:39 -0700826 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700827 png_write_image(png, &rows[0]);
Ben Wagnera93a14a2017-08-28 10:34:05 -0400828 png_destroy_write_struct(&png, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700829 sk_free(rows);
830 sk_free(pixels);
831}
832
brianosmanfad98562016-05-04 11:06:28 -0700833bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
834 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700835 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500836 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700837 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700838 kN32_SkColorType, kPremul_SkAlphaType);
839 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
840 SkDebugf("readPixels failed\n");
841 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800842 }
msaretta5cf4f42016-06-30 10:06:51 -0700843
844 SkBitmap bm;
845 bm.installPixels(dstInfo, buffer.get(), rowBytes);
846 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
847
ethannicholasf67531f2016-03-21 10:19:39 -0700848 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700849 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700850 out, false);
reed42943c82016-09-12 12:01:44 -0700851 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800852 Json::Value jsonData;
853 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
854 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800855 return true;
856}
857
858static const char* color_type_name(SkColorType colorType) {
859 switch (colorType) {
860 case kARGB_4444_SkColorType:
861 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
862 case kRGBA_8888_SkColorType:
863 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
864 case kBGRA_8888_SkColorType:
865 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
866 case kRGB_565_SkColorType:
867 return SKDEBUGCANVAS_COLORTYPE_565;
868 case kGray_8_SkColorType:
869 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
ethannicholas50a8dd02016-02-10 05:40:46 -0800870 case kAlpha_8_SkColorType:
871 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
872 default:
873 SkASSERT(false);
874 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
875 }
876}
877
878static const char* alpha_type_name(SkAlphaType alphaType) {
879 switch (alphaType) {
880 case kOpaque_SkAlphaType:
881 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
882 case kPremul_SkAlphaType:
883 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
884 case kUnpremul_SkAlphaType:
885 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
886 default:
887 SkASSERT(false);
888 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
889 }
890}
891
halcanary9d524f22016-03-29 09:03:52 -0700892static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -0800893 const void** target) {
894 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
895 if (urlData == nullptr) {
896 SkASSERT(false);
897 *target = nullptr;
898 return 0;
ethannicholas50a8dd02016-02-10 05:40:46 -0800899 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800900 *target = urlData->fData->data();
901 // cast should be safe for any reasonably-sized object...
902 return (Json::ArrayIndex) urlData->fData->size();
ethannicholas50a8dd02016-02-10 05:40:46 -0800903}
904
halcanary9d524f22016-03-29 09:03:52 -0700905static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
ethannicholasf62a8b72016-02-11 10:35:21 -0800906 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800907 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
908 return nullptr;
909 }
910 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
911 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
912 if (factory == nullptr) {
913 SkDebugf("no factory for loading '%s'\n", name);
914 return nullptr;
915 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800916 const void* data;
917 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
Mike Reedfadbfcd2017-12-06 16:09:20 -0500918 SkReadBuffer buffer(data, size);
reed60c9b582016-04-03 09:11:13 -0700919 sk_sp<SkFlattenable> result = factory(buffer);
ethannicholas50a8dd02016-02-10 05:40:46 -0800920 if (!buffer.isValid()) {
921 SkDebugf("invalid buffer loading flattenable\n");
922 return nullptr;
923 }
reed60c9b582016-04-03 09:11:13 -0700924 return result.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800925}
926
927static SkColorType colortype_from_name(const char* name) {
928 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
929 return kARGB_4444_SkColorType;
930 }
931 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
932 return kRGBA_8888_SkColorType;
933 }
934 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
935 return kBGRA_8888_SkColorType;
936 }
937 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
938 return kRGB_565_SkColorType;
939 }
940 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
941 return kGray_8_SkColorType;
942 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800943 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
944 return kAlpha_8_SkColorType;
945 }
946 SkASSERT(false);
947 return kN32_SkColorType;
948}
949
950static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
951 if (bitmap->colorType() == colorType ) {
952 return bitmap;
953 }
954 SkBitmap* dst = new SkBitmap();
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400955 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
956 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
957 {
ethannicholas50a8dd02016-02-10 05:40:46 -0800958 delete bitmap;
959 return dst;
960 }
961 SkASSERT(false);
962 delete dst;
963 return bitmap;
964}
965
966// caller is responsible for freeing return value
ethannicholasf62a8b72016-02-11 10:35:21 -0800967static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
968 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800969 SkDebugf("invalid bitmap\n");
970 return nullptr;
971 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800972 const void* data;
973 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
bungeman38d909e2016-08-02 14:40:46 -0700974 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
reed9ce9d672016-03-17 10:51:11 -0700975 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
msarett790f99a2016-03-09 06:16:55 -0800976
Ben Wagner145dbcd2016-11-03 14:40:50 -0400977 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
msarett790f99a2016-03-09 06:16:55 -0800978 if (nullptr != image) {
Cary Clark4f5a79c2018-02-07 15:51:00 -0500979 if (!image->asLegacyBitmap(bitmap.get())) {
msarett790f99a2016-03-09 06:16:55 -0800980 SkDebugf("image decode failed\n");
981 return nullptr;
982 }
983
ethannicholas50a8dd02016-02-10 05:40:46 -0800984 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
985 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
986 SkColorType ct = colortype_from_name(ctName);
Mike Reed304a07c2017-07-12 15:10:28 -0400987 bitmap.reset(convert_colortype(bitmap.release(), ct));
ethannicholas50a8dd02016-02-10 05:40:46 -0800988 }
mtklein18300a32016-03-16 13:53:35 -0700989 return bitmap.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800990 }
991 SkDebugf("image decode failed\n");
ethannicholas50a8dd02016-02-10 05:40:46 -0800992 return nullptr;
993}
994
reed9ce9d672016-03-17 10:51:11 -0700995static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
ethannicholasf62a8b72016-02-11 10:35:21 -0800996 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800997 if (bitmap == nullptr) {
998 return nullptr;
999 }
reed9ce9d672016-03-17 10:51:11 -07001000 auto result = SkImage::MakeFromBitmap(*bitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -08001001 delete bitmap;
1002 return result;
1003}
1004
brianosmanfad98562016-05-04 11:06:28 -07001005bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
1006 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07001007 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -08001008 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
1009 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -08001010 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001011 return success;
1012}
1013
halcanaryf412f092016-08-25 11:10:41 -07001014static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
1015 SkPaint::Hinting hinting = paint.getHinting();
1016 if (hinting != SkPaintDefaults_Hinting) {
1017 switch (hinting) {
1018 case SkPaint::kNo_Hinting:
1019 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
1020 break;
1021 case SkPaint::kSlight_Hinting:
1022 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
1023 break;
1024 case SkPaint::kNormal_Hinting:
1025 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
1026 break;
1027 case SkPaint::kFull_Hinting:
1028 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
1029 break;
1030 }
1031 }
1032}
1033
ethannicholas50a8dd02016-02-10 05:40:46 -08001034static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
1035 SkColor color = paint.getColor();
1036 if (color != SK_ColorBLACK) {
1037 Json::Value colorValue(Json::arrayValue);
1038 colorValue.append(Json::Value(SkColorGetA(color)));
1039 colorValue.append(Json::Value(SkColorGetR(color)));
1040 colorValue.append(Json::Value(SkColorGetG(color)));
1041 colorValue.append(Json::Value(SkColorGetB(color)));
1042 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
1043 }
1044}
1045
1046static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
1047 SkPaint::Style style = paint.getStyle();
1048 if (style != SkPaint::kFill_Style) {
1049 switch (style) {
1050 case SkPaint::kStroke_Style: {
1051 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
1052 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
1053 break;
1054 }
1055 case SkPaint::kStrokeAndFill_Style: {
1056 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1057 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1058 break;
1059 }
1060 default: SkASSERT(false);
1061 }
1062 }
1063}
1064
1065static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1066 SkPaint::Cap cap = paint.getStrokeCap();
1067 if (cap != SkPaint::kDefault_Cap) {
1068 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001069 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001070 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1071 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001072 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001073 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1074 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001075 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001076 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1077 break;
ethannicholas50a8dd02016-02-10 05:40:46 -08001078 default: SkASSERT(false);
1079 }
1080 }
1081}
ethannicholas1446a9a2016-02-10 14:05:02 -08001082
1083static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1084 SkPaint::Join join = paint.getStrokeJoin();
1085 if (join != SkPaint::kDefault_Join) {
1086 switch (join) {
1087 case SkPaint::kMiter_Join:
1088 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1089 SKDEBUGCANVAS_MITER_JOIN);
1090 break;
1091 case SkPaint::kRound_Join:
1092 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1093 SKDEBUGCANVAS_ROUND_JOIN);
1094 break;
1095 case SkPaint::kBevel_Join:
1096 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1097 SKDEBUGCANVAS_BEVEL_JOIN);
1098 break;
1099 default: SkASSERT(false);
1100 }
1101 }
1102}
1103
1104static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1105 SkFilterQuality quality = paint.getFilterQuality();
1106 switch (quality) {
1107 case kNone_SkFilterQuality:
1108 break;
1109 case kLow_SkFilterQuality:
1110 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1111 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1112 break;
1113 case kMedium_SkFilterQuality:
1114 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1115 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1116 break;
1117 case kHigh_SkFilterQuality:
1118 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1119 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1120 break;
1121 }
1122}
1123
halcanary9d524f22016-03-29 09:03:52 -07001124static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001125 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001126 SkMaskFilter* maskFilter = paint.getMaskFilter();
1127 if (maskFilter != nullptr) {
Mike Reed80747ef2018-01-23 15:29:32 -05001128 SkMaskFilterBase::BlurRec blurRec;
1129 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001130 Json::Value blur(Json::objectValue);
1131 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1132 switch (blurRec.fStyle) {
1133 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001134 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1135 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -08001136 break;
1137 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001138 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1139 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -08001140 break;
1141 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001142 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1143 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001144 break;
1145 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001146 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1147 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001148 break;
1149 default:
1150 SkASSERT(false);
1151 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001152 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1153 } else {
1154 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -07001155 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001156 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1157 }
1158 }
1159}
1160
halcanary9d524f22016-03-29 09:03:52 -07001161static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001162 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001163 SkPathEffect* pathEffect = paint.getPathEffect();
1164 if (pathEffect != nullptr) {
1165 SkPathEffect::DashInfo dashInfo;
1166 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1167 if (dashType == SkPathEffect::kDash_DashType) {
1168 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1169 pathEffect->asADash(&dashInfo);
1170 Json::Value dashing(Json::objectValue);
1171 Json::Value intervals(Json::arrayValue);
1172 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1173 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1174 }
1175 sk_free(dashInfo.fIntervals);
1176 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1177 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1178 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1179 } else {
1180 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001181 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001182 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1183 }
1184 }
1185}
halcanary9d524f22016-03-29 09:03:52 -07001186
ethannicholas50a8dd02016-02-10 05:40:46 -08001187static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1188 SkPaint::Align textAlign = paint.getTextAlign();
1189 if (textAlign != SkPaint::kLeft_Align) {
1190 switch (textAlign) {
1191 case SkPaint::kCenter_Align: {
1192 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1193 break;
1194 }
1195 case SkPaint::kRight_Align: {
1196 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1197 break;
1198 }
1199 default: SkASSERT(false);
1200 }
1201 }
1202}
1203
halcanary9d524f22016-03-29 09:03:52 -07001204static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001205 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001206 SkTypeface* typeface = paint.getTypeface();
1207 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001208 Json::Value jsonTypeface;
1209 SkDynamicMemoryWStream buffer;
1210 typeface->serialize(&buffer);
1211 void* data = sk_malloc_throw(buffer.bytesWritten());
1212 buffer.copyTo(data);
1213 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001214 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001215 &jsonData);
1216 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1217 sk_free(data);
1218 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001219 }
1220}
1221
halcanary9d524f22016-03-29 09:03:52 -07001222static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001223 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001224 SkFlattenable* shader = paint.getShader();
1225 if (shader != nullptr) {
1226 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001227 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001228 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1229 }
1230}
1231
ethannicholasf62a8b72016-02-11 10:35:21 -08001232static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1233 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001234 SkFlattenable* imageFilter = paint.getImageFilter();
1235 if (imageFilter != nullptr) {
1236 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001237 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001238 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1239 }
1240}
1241
halcanary9d524f22016-03-29 09:03:52 -07001242static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001243 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001244 SkFlattenable* colorFilter = paint.getColorFilter();
1245 if (colorFilter != nullptr) {
1246 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001247 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001248 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1249 }
1250}
1251
halcanary9d524f22016-03-29 09:03:52 -07001252static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001253 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001254 SkFlattenable* looper = paint.getLooper();
1255 if (looper != nullptr) {
1256 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001257 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001258 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1259 }
1260}
1261
brianosmanfad98562016-05-04 11:06:28 -07001262Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001263 Json::Value result(Json::objectValue);
1264 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001265 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001266 SkPaintDefaults_MiterLimit);
1267 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001268 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001269 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1270 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1271 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001272 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1273 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1274 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1275 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1276 //kGenA8FromLCD_Flag
1277
halcanary9d524f22016-03-29 09:03:52 -07001278 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001279 SkPaintDefaults_TextSize);
1280 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1281 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001282 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001283 apply_paint_color(paint, &result);
1284 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001285 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001286 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001287 apply_paint_join(paint, &result);
1288 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001289 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001290 apply_paint_patheffect(paint, &result, urlDataManager);
1291 apply_paint_maskfilter(paint, &result, urlDataManager);
1292 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001293 apply_paint_looper(paint, &result, urlDataManager);
1294 apply_paint_imagefilter(paint, &result, urlDataManager);
1295 apply_paint_colorfilter(paint, &result, urlDataManager);
1296 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001297 return result;
1298}
1299
Stan Ilievac42aeb2017-01-12 16:20:50 -05001300Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1301 Json::Value result(Json::objectValue);
1302 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1303 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1304 if (nullptr != lattice.fBounds) {
1305 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1306 }
1307 Json::Value XDivs(Json::arrayValue);
1308 for (int i = 0; i < lattice.fXCount; i++) {
1309 XDivs.append(Json::Value(lattice.fXDivs[i]));
1310 }
1311 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1312 Json::Value YDivs(Json::arrayValue);
1313 for (int i = 0; i < lattice.fYCount; i++) {
1314 YDivs.append(Json::Value(lattice.fYDivs[i]));
1315 }
1316 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
Stan Ilievca8c0952017-12-11 13:01:58 -05001317 if (nullptr != lattice.fRectTypes) {
Stan Ilievac42aeb2017-01-12 16:20:50 -05001318 Json::Value flags(Json::arrayValue);
1319 int flagCount = 0;
1320 for (int row = 0; row < lattice.fYCount+1; row++) {
1321 Json::Value flagsRow(Json::arrayValue);
1322 for (int column = 0; column < lattice.fXCount+1; column++) {
Stan Ilievca8c0952017-12-11 13:01:58 -05001323 flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++]));
Stan Ilievac42aeb2017-01-12 16:20:50 -05001324 }
1325 flags.append(flagsRow);
1326 }
1327 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1328 }
1329 return result;
1330}
1331
ethannicholas1446a9a2016-02-10 14:05:02 -08001332static SkPoint get_json_point(Json::Value point) {
1333 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1334}
1335
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04001336static SkPoint3 get_json_point3(Json::Value point) {
1337 return SkPoint3::Make(point[0].asFloat(), point[1].asFloat(), point[2].asFloat());
1338}
1339
ethannicholas1446a9a2016-02-10 14:05:02 -08001340static SkColor get_json_color(Json::Value color) {
1341 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1342}
1343
ethannicholas50a8dd02016-02-10 05:40:46 -08001344static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1345 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001346 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001347 }
1348}
1349
halcanary9d524f22016-03-29 09:03:52 -07001350static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001351 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001352 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1353 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
ethannicholasf62a8b72016-02-11 10:35:21 -08001354 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001355 if (shader != nullptr) {
reedfe630452016-03-25 09:08:00 -07001356 target->setShader(sk_ref_sp(shader));
ethannicholas50a8dd02016-02-10 05:40:46 -08001357 }
1358 }
1359}
1360
halcanary9d524f22016-03-29 09:03:52 -07001361static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001362 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001363 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1364 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
reeda4393342016-03-18 11:22:57 -07001365 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1366 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001367 if (pathEffect != nullptr) {
1368 target->setPathEffect(pathEffect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001369 }
1370 }
1371}
1372
halcanary9d524f22016-03-29 09:03:52 -07001373static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001374 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001375 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1376 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
reedefdfd512016-04-04 10:02:58 -07001377 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1378 urlDataManager));
1379 if (maskFilter) {
1380 target->setMaskFilter(std::move(maskFilter));
ethannicholas50a8dd02016-02-10 05:40:46 -08001381 }
1382 }
1383}
1384
halcanary9d524f22016-03-29 09:03:52 -07001385static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001386 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001387 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1388 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
reedd053ce92016-03-22 10:17:23 -07001389 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1390 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001391 if (colorFilter != nullptr) {
1392 target->setColorFilter(colorFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001393 }
1394 }
1395}
1396
halcanary9d524f22016-03-29 09:03:52 -07001397static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001398 SkPaint* target) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001399 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1400 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
reed7b380d02016-03-21 13:25:16 -07001401 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
ethannicholas1446a9a2016-02-10 14:05:02 -08001402 if (looper != nullptr) {
reed7b380d02016-03-21 13:25:16 -07001403 target->setLooper(std::move(looper));
ethannicholas1446a9a2016-02-10 14:05:02 -08001404 }
1405 }
1406}
1407
halcanary9d524f22016-03-29 09:03:52 -07001408static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001409 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001410 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1411 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
Mike Reed5e257172016-11-01 11:22:05 -04001412 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1413 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001414 if (imageFilter != nullptr) {
1415 target->setImageFilter(imageFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001416 }
1417 }
1418}
1419
halcanary9d524f22016-03-29 09:03:52 -07001420static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001421 SkPaint* target) {
1422 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1423 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1424 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1425 const void* data;
1426 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1427 SkMemoryStream buffer(data, length);
bungeman13b9c952016-05-12 10:09:30 -07001428 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
ethannicholasf62a8b72016-02-11 10:35:21 -08001429 }
1430}
1431
halcanaryf412f092016-08-25 11:10:41 -07001432static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1433 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1434 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1435 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1436 target->setHinting(SkPaint::kNo_Hinting);
1437 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1438 target->setHinting(SkPaint::kSlight_Hinting);
1439 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1440 target->setHinting(SkPaint::kNormal_Hinting);
1441 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1442 target->setHinting(SkPaint::kFull_Hinting);
1443 }
1444 }
1445}
1446
ethannicholas50a8dd02016-02-10 05:40:46 -08001447static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1448 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1449 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1450 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1451 target->setStyle(SkPaint::kFill_Style);
1452 }
1453 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1454 target->setStyle(SkPaint::kStroke_Style);
1455 }
1456 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1457 target->setStyle(SkPaint::kStrokeAndFill_Style);
1458 }
1459 }
1460}
1461
1462static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1463 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1464 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1465 target->setStrokeWidth(strokeWidth);
halcanary9d524f22016-03-29 09:03:52 -07001466 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001467}
1468
1469static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1470 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1471 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1472 target->setStrokeMiter(strokeMiter);
halcanary9d524f22016-03-29 09:03:52 -07001473 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001474}
1475
ethannicholas1446a9a2016-02-10 14:05:02 -08001476static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1477 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1478 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1479 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1480 target->setStrokeJoin(SkPaint::kMiter_Join);
1481 }
1482 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1483 target->setStrokeJoin(SkPaint::kRound_Join);
1484 }
1485 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1486 target->setStrokeJoin(SkPaint::kBevel_Join);
1487 }
1488 else {
1489 SkASSERT(false);
1490 }
1491 }
1492}
1493
ethannicholas50a8dd02016-02-10 05:40:46 -08001494static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1495 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1496 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1497 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1498 target->setStrokeCap(SkPaint::kButt_Cap);
1499 }
1500 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1501 target->setStrokeCap(SkPaint::kRound_Cap);
1502 }
1503 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1504 target->setStrokeCap(SkPaint::kSquare_Cap);
1505 }
1506 }
1507}
1508
ethannicholas1446a9a2016-02-10 14:05:02 -08001509static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1510 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1511 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1512 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1513 target->setFilterQuality(kNone_SkFilterQuality);
1514 }
1515 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1516 target->setFilterQuality(kLow_SkFilterQuality);
1517 }
1518 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1519 target->setFilterQuality(kMedium_SkFilterQuality);
1520 }
1521 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1522 target->setFilterQuality(kHigh_SkFilterQuality);
1523 }
1524 }
1525}
1526
ethannicholas50a8dd02016-02-10 05:40:46 -08001527static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1528 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1529 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1530 }
1531}
1532
ethannicholas1446a9a2016-02-10 14:05:02 -08001533static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1534 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1535 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1536 }
1537}
1538
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001539static void extract_json_paint_fakeboldtext(Json::Value& jsonPaint, SkPaint* target) {
1540 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT)) {
1541 target->setFakeBoldText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT].asBool());
1542 }
1543}
1544
1545static void extract_json_paint_lineartext(Json::Value& jsonPaint, SkPaint* target) {
1546 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT)) {
1547 target->setLinearText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT].asBool());
1548 }
1549}
1550
1551static void extract_json_paint_subpixeltext(Json::Value& jsonPaint, SkPaint* target) {
1552 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT)) {
1553 target->setSubpixelText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT].asBool());
1554 }
1555}
1556
1557static void extract_json_paint_devkerntext(Json::Value& jsonPaint, SkPaint* target) {
1558 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT)) {
1559 target->setDevKernText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT].asBool());
1560 }
1561}
1562
1563static void extract_json_paint_lcdrendertext(Json::Value& jsonPaint, SkPaint* target) {
1564 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT)) {
1565 target->setLCDRenderText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT].asBool());
1566 }
1567}
1568
1569static void extract_json_paint_embeddedbitmaptext(Json::Value& jsonPaint, SkPaint* target) {
1570 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT)) {
1571 target->setEmbeddedBitmapText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT].asBool());
1572 }
1573}
1574
1575static void extract_json_paint_autohinting(Json::Value& jsonPaint, SkPaint* target) {
1576 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING)) {
1577 target->setAutohinted(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING].asBool());
1578 }
1579}
1580
1581static void extract_json_paint_verticaltext(Json::Value& jsonPaint, SkPaint* target) {
1582 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT)) {
1583 target->setVerticalText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT].asBool());
1584 }
1585}
1586
ethannicholas50a8dd02016-02-10 05:40:46 -08001587static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1588 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1589 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1590 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1591 SkBlurStyle style;
1592 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1593 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1594 style = SkBlurStyle::kNormal_SkBlurStyle;
1595 }
1596 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1597 style = SkBlurStyle::kSolid_SkBlurStyle;
1598 }
1599 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1600 style = SkBlurStyle::kOuter_SkBlurStyle;
1601 }
1602 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1603 style = SkBlurStyle::kInner_SkBlurStyle;
1604 }
1605 else {
1606 SkASSERT(false);
1607 style = SkBlurStyle::kNormal_SkBlurStyle;
1608 }
Mike Reed1be1f8d2018-03-14 13:01:17 -04001609 target->setMaskFilter(SkMaskFilter::MakeBlur(style, sigma));
ethannicholas50a8dd02016-02-10 05:40:46 -08001610 }
1611}
1612
1613static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1614 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1615 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1616 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1617 Json::ArrayIndex count = jsonIntervals.size();
1618 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1619 for (Json::ArrayIndex i = 0; i < count; i++) {
1620 intervals[i] = jsonIntervals[i].asFloat();
1621 }
1622 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
reeda4393342016-03-18 11:22:57 -07001623 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
ethannicholas50a8dd02016-02-10 05:40:46 -08001624 sk_free(intervals);
1625 }
1626}
1627
1628static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1629 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1630 SkPaint::Align textAlign;
1631 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1632 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1633 textAlign = SkPaint::kLeft_Align;
1634 }
1635 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1636 textAlign = SkPaint::kCenter_Align;
1637 }
1638 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1639 textAlign = SkPaint::kRight_Align;
1640 }
1641 else {
1642 SkASSERT(false);
1643 textAlign = SkPaint::kLeft_Align;
1644 }
1645 target->setTextAlign(textAlign);
1646 }
1647}
1648
1649static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1650 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1651 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1652 target->setTextSize(textSize);
1653 }
1654}
1655
1656static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1657 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1658 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1659 target->setTextScaleX(textScaleX);
1660 }
1661}
1662
1663static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1664 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1665 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1666 target->setTextSkewX(textSkewX);
1667 }
1668}
1669
halcanary9d524f22016-03-29 09:03:52 -07001670static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001671 SkPaint* result) {
halcanaryf412f092016-08-25 11:10:41 -07001672 extract_json_paint_hinting(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001673 extract_json_paint_color(paint, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001674 extract_json_paint_shader(paint, urlDataManager, result);
1675 extract_json_paint_patheffect(paint, urlDataManager, result);
1676 extract_json_paint_maskfilter(paint, urlDataManager, result);
1677 extract_json_paint_colorfilter(paint, urlDataManager, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001678 extract_json_paint_looper(paint, urlDataManager, result);
1679 extract_json_paint_imagefilter(paint, urlDataManager, result);
1680 extract_json_paint_typeface(paint, urlDataManager, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001681 extract_json_paint_style(paint, result);
Florin Malita82d80872017-06-06 16:58:40 -04001682 extract_json_paint_blend_mode(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001683 extract_json_paint_strokewidth(paint, result);
1684 extract_json_paint_strokemiter(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001685 extract_json_paint_strokejoin(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001686 extract_json_paint_cap(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001687 extract_json_paint_filterquality(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001688 extract_json_paint_antialias(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001689 extract_json_paint_dither(paint, result);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001690 extract_json_paint_fakeboldtext(paint, result);
1691 extract_json_paint_lineartext(paint, result);
1692 extract_json_paint_subpixeltext(paint, result);
1693 extract_json_paint_devkerntext(paint, result);
1694 extract_json_paint_lcdrendertext(paint, result);
1695 extract_json_paint_embeddedbitmaptext(paint, result);
1696 extract_json_paint_autohinting(paint, result);
1697 extract_json_paint_verticaltext(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001698 extract_json_paint_blur(paint, result);
1699 extract_json_paint_dashing(paint, result);
1700 extract_json_paint_textalign(paint, result);
1701 extract_json_paint_textsize(paint, result);
1702 extract_json_paint_textscalex(paint, result);
1703 extract_json_paint_textskewx(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001704}
1705
1706static void extract_json_rect(Json::Value& rect, SkRect* result) {
1707 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1708}
1709
1710static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1711 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1712}
1713
1714static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1715 SkVector radii[4] = {
halcanary9d524f22016-03-29 09:03:52 -07001716 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1717 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1718 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
ethannicholas50a8dd02016-02-10 05:40:46 -08001719 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1720 };
halcanary9d524f22016-03-29 09:03:52 -07001721 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1722 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
ethannicholas50a8dd02016-02-10 05:40:46 -08001723 radii);
1724}
1725
1726static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
halcanary9d524f22016-03-29 09:03:52 -07001727 SkScalar values[] = {
ethannicholas50a8dd02016-02-10 05:40:46 -08001728 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1729 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
halcanary9d524f22016-03-29 09:03:52 -07001730 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
ethannicholas50a8dd02016-02-10 05:40:46 -08001731 };
1732 result->set9(values);
1733}
1734
1735static void extract_json_path(Json::Value& path, SkPath* result) {
1736 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1737 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1738 result->setFillType(SkPath::kWinding_FillType);
1739 }
1740 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1741 result->setFillType(SkPath::kEvenOdd_FillType);
1742 }
1743 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1744 result->setFillType(SkPath::kInverseWinding_FillType);
1745 }
1746 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1747 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1748 }
1749 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1750 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1751 Json::Value verb = verbs[i];
1752 if (verb.isString()) {
1753 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1754 result->close();
1755 }
1756 else {
1757 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1758 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1759 result->moveTo(move[0].asFloat(), move[1].asFloat());
1760 }
1761 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1762 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1763 result->lineTo(line[0].asFloat(), line[1].asFloat());
1764 }
1765 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1766 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1767 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1768 quad[1][0].asFloat(), quad[1][1].asFloat());
1769 }
1770 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1771 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1772 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1773 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1774 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1775 }
1776 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1777 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1778 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1779 conic[1][0].asFloat(), conic[1][1].asFloat(),
1780 conic[2].asFloat());
1781 }
1782 else {
1783 SkASSERT(false);
1784 }
1785 }
1786 }
1787}
1788
Brian Osmanc25e2692018-03-12 10:57:28 -04001789static void extract_json_region(Json::Value& region, SkRegion* result) {
1790 SkPath path;
1791 extract_json_path(region, &path);
1792 result->setPath(path, SkRegion(path.getBounds().roundOut()));
1793}
1794
Mike Reedc1f77742016-12-09 09:00:50 -05001795SkClipOp get_json_clipop(Json::Value& jsonOp) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001796 const char* op = jsonOp.asCString();
1797 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001798 return kDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001799 }
1800 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001801 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001802 }
1803 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001804 return kUnion_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001805 }
1806 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001807 return kXOR_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001808 }
1809 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001810 return kReverseDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001811 }
1812 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001813 return kReplace_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001814 }
1815 SkASSERT(false);
Mike Reedc1f77742016-12-09 09:00:50 -05001816 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001817}
1818
Brian Osmanc25e2692018-03-12 10:57:28 -04001819SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001820 fColor = color;
ethannicholas1446a9a2016-02-10 14:05:02 -08001821}
1822
1823void SkClearCommand::execute(SkCanvas* canvas) const {
1824 canvas->clear(fColor);
1825}
1826
ethannicholasf62a8b72016-02-11 10:35:21 -08001827Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1828 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001829 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001830 return result;
1831}
1832
ethannicholasf62a8b72016-02-11 10:35:21 -08001833 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001834 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1835 return new SkClearCommand(get_json_color(color));
1836}
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001837
Mike Reedc1f77742016-12-09 09:00:50 -05001838SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001839 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001840 fPath = path;
1841 fOp = op;
1842 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001843}
1844
fmalita8c89c522014-11-08 16:18:56 -08001845void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001846 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001847}
1848
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001849bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001850 render_path(canvas, fPath);
1851 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001852}
1853
ethannicholasf62a8b72016-02-11 10:35:21 -08001854Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1855 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001856 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001857 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1858 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1859 return result;
1860}
1861
halcanary9d524f22016-03-29 09:03:52 -07001862SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001863 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001864 SkPath path;
1865 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
reed73603f32016-09-20 08:42:38 -07001866 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001867 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1868}
1869
Mike Reedc1f77742016-12-09 09:00:50 -05001870SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001871 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001872 fRegion = region;
1873 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001874}
1875
fmalita8c89c522014-11-08 16:18:56 -08001876void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001877 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001878}
1879
ethannicholasf62a8b72016-02-11 10:35:21 -08001880Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1881 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001882 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001883 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1884 return result;
1885}
1886
halcanary9d524f22016-03-29 09:03:52 -07001887SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001888 UrlDataManager& urlDataManager) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001889 SkRegion region;
1890 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
1891 return new SkClipRegionCommand(region,
1892 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001893}
1894
Mike Reedc1f77742016-12-09 09:00:50 -05001895SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001896 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001897 fRect = rect;
1898 fOp = op;
1899 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001900}
1901
fmalita8c89c522014-11-08 16:18:56 -08001902void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001903 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001904}
1905
ethannicholasf62a8b72016-02-11 10:35:21 -08001906Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1907 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001908 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001909 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1910 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001911
1912 SkString desc;
1913 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1914
ethannicholas50a8dd02016-02-10 05:40:46 -08001915 return result;
1916}
1917
halcanary9d524f22016-03-29 09:03:52 -07001918SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001919 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001920 SkRect rect;
1921 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
reed73603f32016-09-20 08:42:38 -07001922 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001923 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1924}
1925
Mike Reedc1f77742016-12-09 09:00:50 -05001926SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001927 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001928 fRRect = rrect;
1929 fOp = op;
1930 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001931}
1932
fmalita8c89c522014-11-08 16:18:56 -08001933void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001934 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001935}
1936
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001937bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001938 render_rrect(canvas, fRRect);
1939 return true;
1940}
1941
ethannicholasf62a8b72016-02-11 10:35:21 -08001942Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1943 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001944 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1945 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1946 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1947 return result;
1948}
1949
halcanary9d524f22016-03-29 09:03:52 -07001950SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001951 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001952 SkRRect rrect;
1953 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
halcanary9d524f22016-03-29 09:03:52 -07001954 return new SkClipRRectCommand(rrect,
reed73603f32016-09-20 08:42:38 -07001955 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001956 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1957}
1958
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001959SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001960 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001961 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001962}
1963
fmalita8c89c522014-11-08 16:18:56 -08001964void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001965 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001966}
1967
ethannicholasf62a8b72016-02-11 10:35:21 -08001968Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1969 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001970 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001971 return result;
1972}
1973
ethannicholasf62a8b72016-02-11 10:35:21 -08001974SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001975 SkMatrix matrix;
1976 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1977 return new SkConcatCommand(matrix);
1978}
1979
reed97660cc2016-06-28 18:54:19 -07001980////
1981
1982SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1983 sk_sp<SkData> value)
1984 : INHERITED(kDrawAnnotation_OpType)
1985 , fRect(rect)
1986 , fKey(key)
1987 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07001988{
robertphillipsfb409232016-06-29 10:28:11 -07001989}
reed97660cc2016-06-28 18:54:19 -07001990
1991void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1992 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1993}
1994
1995Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1996 Json::Value result = INHERITED::toJSON(urlDataManager);
1997
1998 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1999 result["key"] = Json::Value(fKey.c_str());
2000 if (fValue.get()) {
2001 // TODO: dump out the "value"
2002 }
reed67f62fa2016-06-29 11:36:34 -07002003
2004 SkString desc;
2005 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
2006 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
2007
reed97660cc2016-06-28 18:54:19 -07002008 return result;
2009}
2010
2011SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
2012 UrlDataManager& urlDataManager) {
2013 SkRect rect;
2014 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
2015 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
2016 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
2017}
2018
2019////
2020
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002021SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07002022 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002023 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002024 fBitmap = bitmap;
2025 fLeft = left;
2026 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07002027 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002028 fPaint = *paint;
2029 fPaintPtr = &fPaint;
2030 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002031 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002032 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002033}
2034
fmalita8c89c522014-11-08 16:18:56 -08002035void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002036 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002037}
2038
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002039bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002040 render_bitmap(canvas, fBitmap);
2041 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002042}
2043
ethannicholasf62a8b72016-02-11 10:35:21 -08002044Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
2045 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002046 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002047 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002048 Json::Value command(Json::objectValue);
2049 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002050 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002051 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002052 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002053 }
2054 }
2055 return result;
2056}
2057
halcanary9d524f22016-03-29 09:03:52 -07002058SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002059 UrlDataManager& urlDataManager) {
2060 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002061 if (bitmap == nullptr) {
2062 return nullptr;
2063 }
2064 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2065 SkPaint* paintPtr;
2066 SkPaint paint;
2067 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002068 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002069 paintPtr = &paint;
2070 }
2071 else {
2072 paintPtr = nullptr;
2073 }
halcanary9d524f22016-03-29 09:03:52 -07002074 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002075 point[1].asFloat(), paintPtr);
2076 delete bitmap;
2077 return result;
2078}
2079
Brian Osman78a76482018-05-18 16:59:13 -04002080SkDrawBitmapLatticeCommand::SkDrawBitmapLatticeCommand(const SkBitmap& bitmap,
2081 const SkCanvas::Lattice& lattice,
2082 const SkRect& dst, const SkPaint* paint)
2083 : INHERITED(kDrawBitmapLattice_OpType)
2084 , fBitmap(bitmap)
2085 , fLattice(lattice)
2086 , fDst(dst) {
2087
2088 if (paint) {
2089 fPaint.set(*paint);
2090 }
2091}
2092
2093void SkDrawBitmapLatticeCommand::execute(SkCanvas* canvas) const {
2094 canvas->drawBitmapLattice(fBitmap, fLattice, fDst, fPaint.getMaybeNull());
2095}
2096
2097bool SkDrawBitmapLatticeCommand::render(SkCanvas* canvas) const {
2098 SkAutoCanvasRestore acr(canvas, true);
2099 canvas->clear(0xFFFFFFFF);
2100
2101 xlate_and_scale_to_bounds(canvas, fDst);
2102
2103 this->execute(canvas);
2104 return true;
2105}
2106
2107Json::Value SkDrawBitmapLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2108 Json::Value result = INHERITED::toJSON(urlDataManager);
2109 Json::Value encoded;
2110 if (flatten(fBitmap, &encoded, urlDataManager)) {
2111 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2112 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2113 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2114 if (fPaint.isValid()) {
2115 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2116 }
2117 }
2118
2119 SkString desc;
2120 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2121
2122 return result;
2123}
2124
2125SkDrawBitmapLatticeCommand* SkDrawBitmapLatticeCommand::fromJSON(Json::Value& command,
2126 UrlDataManager& urlDataManager) {
2127 SkDEBUGFAIL("Not implemented yet.");
2128 return nullptr;
2129}
2130
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002131SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00002132 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002133 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002134 fBitmap = bitmap;
2135 fCenter = center;
2136 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07002137 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002138 fPaint = *paint;
2139 fPaintPtr = &fPaint;
2140 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002141 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002142 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002143}
2144
fmalita8c89c522014-11-08 16:18:56 -08002145void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002146 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002147}
2148
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002149bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08002150 SkRect tmp = SkRect::Make(fCenter);
2151 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002152 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002153}
2154
ethannicholasf62a8b72016-02-11 10:35:21 -08002155Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2156 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002157 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002158 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002159 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08002160 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07002161 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002162 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002163 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002164 }
2165 }
2166 return result;
2167}
2168
halcanary9d524f22016-03-29 09:03:52 -07002169SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002170 UrlDataManager& urlDataManager) {
2171 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002172 if (bitmap == nullptr) {
2173 return nullptr;
2174 }
2175 SkIRect center;
2176 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2177 SkRect dst;
2178 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2179 SkPaint* paintPtr;
2180 SkPaint paint;
2181 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002182 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002183 paintPtr = &paint;
2184 }
2185 else {
2186 paintPtr = nullptr;
2187 }
2188 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2189 delete bitmap;
2190 return result;
2191}
2192
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002193SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002194 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002195 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08002196 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002197 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07002198 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002199 fSrc = *src;
2200 } else {
2201 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002202 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00002203 fDst = dst;
2204
bsalomon49f085d2014-09-05 13:34:00 -07002205 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002206 fPaint = *paint;
2207 fPaintPtr = &fPaint;
2208 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002209 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00002210 }
reeda5517e22015-07-14 10:54:12 -07002211 fConstraint = constraint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002212}
2213
fmalita8c89c522014-11-08 16:18:56 -08002214void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07002215 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002216}
2217
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002218bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002219 render_bitmap(canvas, fBitmap, this->srcRect());
2220 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002221}
2222
ethannicholasf62a8b72016-02-11 10:35:21 -08002223Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2224 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002225 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002226 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002227 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2228 if (!fSrc.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07002229 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
ethannicholas50a8dd02016-02-10 05:40:46 -08002230 }
brianosmanfad98562016-05-04 11:06:28 -07002231 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002232 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002233 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002234 }
2235 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2236 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2237 }
2238 }
reed67f62fa2016-06-29 11:36:34 -07002239
2240 SkString desc;
2241 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2242
ethannicholas50a8dd02016-02-10 05:40:46 -08002243 return result;
2244}
2245
halcanary9d524f22016-03-29 09:03:52 -07002246SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002247 UrlDataManager& urlDataManager) {
2248 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002249 if (bitmap == nullptr) {
2250 return nullptr;
2251 }
2252 SkRect dst;
2253 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2254 SkPaint* paintPtr;
2255 SkPaint paint;
2256 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002257 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002258 paintPtr = &paint;
2259 }
2260 else {
2261 paintPtr = nullptr;
2262 }
2263 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002264 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002265 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2266 constraint = SkCanvas::kStrict_SrcRectConstraint;
2267 }
2268 else {
2269 constraint = SkCanvas::kFast_SrcRectConstraint;
2270 }
2271 SkRect* srcPtr;
2272 SkRect src;
2273 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2274 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2275 srcPtr = &src;
2276 }
2277 else {
2278 srcPtr = nullptr;
2279 }
2280 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2281 constraint);
2282 delete bitmap;
2283 return result;
2284}
2285
fmalita651c9202015-07-22 10:23:01 -07002286SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2287 const SkPaint* paint)
2288 : INHERITED(kDrawImage_OpType)
2289 , fImage(SkRef(image))
2290 , fLeft(left)
2291 , fTop(top) {
2292
2293 if (paint) {
2294 fPaint.set(*paint);
2295 }
2296}
2297
2298void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002299 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07002300}
2301
2302bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2303 SkAutoCanvasRestore acr(canvas, true);
2304 canvas->clear(0xFFFFFFFF);
2305
2306 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2307 SkIntToScalar(fImage->width()),
2308 SkIntToScalar(fImage->height())));
2309 this->execute(canvas);
2310 return true;
2311}
2312
ethannicholasf62a8b72016-02-11 10:35:21 -08002313Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2314 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002315 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002316 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002317 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002318 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002319 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002320 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002321 }
msarett0ac1bec2016-08-29 09:15:33 -07002322
2323 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2324 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2325 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2326 switch (fImage->alphaType()) {
2327 case kOpaque_SkAlphaType:
2328 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2329 break;
2330 case kPremul_SkAlphaType:
2331 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2332 break;
2333 case kUnpremul_SkAlphaType:
2334 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2335 break;
2336 default:
2337 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2338 break;
2339 }
ethannicholas50a8dd02016-02-10 05:40:46 -08002340 }
2341 return result;
2342}
2343
halcanary9d524f22016-03-29 09:03:52 -07002344SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002345 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002346 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002347 if (image == nullptr) {
2348 return nullptr;
2349 }
2350 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2351 SkPaint* paintPtr;
2352 SkPaint paint;
2353 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002354 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002355 paintPtr = &paint;
2356 }
2357 else {
2358 paintPtr = nullptr;
2359 }
reed9ce9d672016-03-17 10:51:11 -07002360 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002361 point[1].asFloat(), paintPtr);
ethannicholas50a8dd02016-02-10 05:40:46 -08002362 return result;
2363}
2364
Stan Ilievac42aeb2017-01-12 16:20:50 -05002365SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2366 const SkCanvas::Lattice& lattice,
2367 const SkRect& dst, const SkPaint* paint)
2368 : INHERITED(kDrawImageLattice_OpType)
2369 , fImage(SkRef(image))
2370 , fLattice(lattice)
2371 , fDst(dst) {
2372
Stan Ilievac42aeb2017-01-12 16:20:50 -05002373 if (paint) {
2374 fPaint.set(*paint);
Stan Ilievac42aeb2017-01-12 16:20:50 -05002375 }
2376}
2377
2378void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
Brian Osman78a76482018-05-18 16:59:13 -04002379 canvas->drawImageLattice(fImage.get(), fLattice, fDst, fPaint.getMaybeNull());
Stan Ilievac42aeb2017-01-12 16:20:50 -05002380}
2381
2382bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2383 SkAutoCanvasRestore acr(canvas, true);
2384 canvas->clear(0xFFFFFFFF);
2385
2386 xlate_and_scale_to_bounds(canvas, fDst);
2387
2388 this->execute(canvas);
2389 return true;
2390}
2391
2392Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2393 Json::Value result = INHERITED::toJSON(urlDataManager);
2394 Json::Value encoded;
2395 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002396 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
Stan Ilievac42aeb2017-01-12 16:20:50 -05002397 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2398 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2399 if (fPaint.isValid()) {
2400 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2401 }
2402 }
2403
2404 SkString desc;
2405 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2406
2407 return result;
2408}
2409
Brian Osmanc25e2692018-03-12 10:57:28 -04002410SkDrawImageLatticeCommand* SkDrawImageLatticeCommand::fromJSON(Json::Value& command,
2411 UrlDataManager& urlDataManager) {
2412 SkDEBUGFAIL("Not implemented yet.");
2413 return nullptr;
2414}
2415
fmalita651c9202015-07-22 10:23:01 -07002416SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2417 const SkRect& dst, const SkPaint* paint,
2418 SkCanvas::SrcRectConstraint constraint)
2419 : INHERITED(kDrawImageRect_OpType)
2420 , fImage(SkRef(image))
2421 , fDst(dst)
2422 , fConstraint(constraint) {
2423
2424 if (src) {
2425 fSrc.set(*src);
2426 }
2427
2428 if (paint) {
2429 fPaint.set(*paint);
2430 }
2431}
2432
2433void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002434 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2435 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07002436}
2437
2438bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2439 SkAutoCanvasRestore acr(canvas, true);
2440 canvas->clear(0xFFFFFFFF);
2441
2442 xlate_and_scale_to_bounds(canvas, fDst);
2443
2444 this->execute(canvas);
2445 return true;
2446}
2447
ethannicholasf62a8b72016-02-11 10:35:21 -08002448Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2449 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002450 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002451 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002452 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
ethannicholas50a8dd02016-02-10 05:40:46 -08002453 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002454 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002455 }
brianosmanfad98562016-05-04 11:06:28 -07002456 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002457 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002458 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002459 }
2460 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2461 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2462 }
2463 }
reed67f62fa2016-06-29 11:36:34 -07002464
2465 SkString desc;
2466 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2467
ethannicholas50a8dd02016-02-10 05:40:46 -08002468 return result;
2469}
2470
halcanary9d524f22016-03-29 09:03:52 -07002471SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002472 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002473 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002474 if (image == nullptr) {
2475 return nullptr;
2476 }
2477 SkRect dst;
2478 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2479 SkPaint* paintPtr;
2480 SkPaint paint;
2481 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002482 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002483 paintPtr = &paint;
2484 }
2485 else {
2486 paintPtr = nullptr;
2487 }
2488 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002489 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002490 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2491 constraint = SkCanvas::kStrict_SrcRectConstraint;
2492 }
2493 else {
2494 constraint = SkCanvas::kFast_SrcRectConstraint;
2495 }
2496 SkRect* srcPtr;
2497 SkRect src;
2498 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2499 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2500 srcPtr = &src;
2501 }
2502 else {
2503 srcPtr = nullptr;
2504 }
reed9ce9d672016-03-17 10:51:11 -07002505 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
ethannicholas50a8dd02016-02-10 05:40:46 -08002506 constraint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002507 return result;
2508}
2509
Brian Osmanc25e2692018-03-12 10:57:28 -04002510SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
2511 const SkRect& dst, const SkPaint* paint)
2512 : INHERITED(kDrawImageNine_OpType)
2513 , fImage(SkRef(image))
2514 , fCenter(center)
2515 , fDst(dst) {
2516 if (paint) {
2517 fPaint = *paint;
2518 fPaintPtr = &fPaint;
2519 } else {
2520 fPaintPtr = nullptr;
2521 }
Brian Osmanc25e2692018-03-12 10:57:28 -04002522}
2523
2524void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
2525 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaintPtr);
2526}
2527
2528bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
2529 SkAutoCanvasRestore acr(canvas, true);
2530 canvas->clear(0xFFFFFFFF);
2531
2532 xlate_and_scale_to_bounds(canvas, fDst);
2533
2534 this->execute(canvas);
2535 return true;
2536}
2537
2538Json::Value SkDrawImageNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2539 Json::Value result = INHERITED::toJSON(urlDataManager);
2540 Json::Value encoded;
2541 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2542 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
2543 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
2544 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2545 if (fPaintPtr != nullptr) {
2546 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2547 }
2548 }
2549 return result;
2550}
2551
2552SkDrawImageNineCommand* SkDrawImageNineCommand::fromJSON(Json::Value& command,
2553 UrlDataManager& urlDataManager) {
2554 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2555 if (image == nullptr) {
2556 return nullptr;
2557 }
2558 SkIRect center;
2559 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2560 SkRect dst;
2561 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2562 SkPaint* paintPtr;
2563 SkPaint paint;
2564 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2565 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2566 paintPtr = &paint;
2567 } else {
2568 paintPtr = nullptr;
2569 }
2570 SkDrawImageNineCommand* result = new SkDrawImageNineCommand(image.get(), center, dst, paintPtr);
2571 return result;
2572}
2573
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002574SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002575 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002576 fOval = oval;
2577 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002578}
2579
fmalita8c89c522014-11-08 16:18:56 -08002580void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002581 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002582}
2583
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002584bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002585 canvas->clear(0xFFFFFFFF);
2586 canvas->save();
2587
2588 xlate_and_scale_to_bounds(canvas, fOval);
2589
2590 SkPaint p;
2591 p.setColor(SK_ColorBLACK);
2592 p.setStyle(SkPaint::kStroke_Style);
2593
2594 canvas->drawOval(fOval, p);
2595 canvas->restore();
2596
2597 return true;
2598}
2599
ethannicholasf62a8b72016-02-11 10:35:21 -08002600Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2601 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002602 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2603 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002604 return result;
2605}
2606
halcanary9d524f22016-03-29 09:03:52 -07002607SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002608 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002609 SkRect coords;
2610 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2611 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002612 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002613 return new SkDrawOvalCommand(coords, paint);
2614}
2615
bsalomonac3aa242016-08-19 11:25:19 -07002616SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2617 bool useCenter, const SkPaint& paint)
Brian Osmanc25e2692018-03-12 10:57:28 -04002618 : INHERITED(kDrawArc_OpType) {
bsalomonac3aa242016-08-19 11:25:19 -07002619 fOval = oval;
2620 fStartAngle = startAngle;
2621 fSweepAngle = sweepAngle;
2622 fUseCenter = useCenter;
2623 fPaint = paint;
bsalomonac3aa242016-08-19 11:25:19 -07002624}
2625
2626void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2627 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2628}
2629
2630bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2631 canvas->clear(0xFFFFFFFF);
2632 canvas->save();
2633
2634 xlate_and_scale_to_bounds(canvas, fOval);
2635
2636 SkPaint p;
2637 p.setColor(SK_ColorBLACK);
2638 p.setStyle(SkPaint::kStroke_Style);
2639
2640 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2641 canvas->restore();
2642
2643 return true;
2644}
2645
2646Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2647 Json::Value result = INHERITED::toJSON(urlDataManager);
2648 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2649 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2650 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2651 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2652 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2653 return result;
2654}
2655
2656SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2657 UrlDataManager& urlDataManager) {
2658 SkRect coords;
2659 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2660 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2661 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2662 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2663 SkPaint paint;
2664 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2665 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2666}
2667
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002668SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002669 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002670 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002671}
2672
fmalita8c89c522014-11-08 16:18:56 -08002673void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002674 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002675}
2676
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002677bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002678 canvas->clear(0xFFFFFFFF);
2679 canvas->drawPaint(fPaint);
2680 return true;
2681}
2682
ethannicholasf62a8b72016-02-11 10:35:21 -08002683Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2684 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002685 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002686 return result;
2687}
2688
halcanary9d524f22016-03-29 09:03:52 -07002689SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002690 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002691 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002692 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002693 return new SkDrawPaintCommand(paint);
2694}
2695
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002696SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002697 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002698 fPath = path;
2699 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002700}
2701
fmalita8c89c522014-11-08 16:18:56 -08002702void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002703 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002704}
2705
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002706bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002707 render_path(canvas, fPath);
2708 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002709}
2710
ethannicholasf62a8b72016-02-11 10:35:21 -08002711Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2712 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002713 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2714 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002715 return result;
2716}
2717
halcanary9d524f22016-03-29 09:03:52 -07002718SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002719 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002720 SkPath path;
2721 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2722 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002723 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002724 return new SkDrawPathCommand(path, paint);
2725}
2726
Brian Osmanc25e2692018-03-12 10:57:28 -04002727SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
2728 : INHERITED(kDrawRegion_OpType) {
2729 fRegion = region;
2730 fPaint = paint;
Brian Osmanc25e2692018-03-12 10:57:28 -04002731}
2732
2733void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
2734 canvas->drawRegion(fRegion, fPaint);
2735}
2736
2737bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
2738 render_region(canvas, fRegion);
2739 return true;
2740}
2741
2742Json::Value SkDrawRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
2743 Json::Value result = INHERITED::toJSON(urlDataManager);
2744 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
2745 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2746 return result;
2747}
2748
2749SkDrawRegionCommand* SkDrawRegionCommand::fromJSON(Json::Value& command,
2750 UrlDataManager& urlDataManager) {
2751 SkRegion region;
2752 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
2753 SkPaint paint;
2754 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2755 return new SkDrawRegionCommand(region, paint);
2756}
2757
fmalita160ebb22015-04-01 20:58:37 -07002758SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2759 const SkMatrix* matrix,
2760 const SkPaint* paint)
2761 : INHERITED(kBeginDrawPicture_OpType)
2762 , fPicture(SkRef(picture)) {
bsalomon49f085d2014-09-05 13:34:00 -07002763 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002764 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002765 }
fmalita160ebb22015-04-01 20:58:37 -07002766
bsalomon49f085d2014-09-05 13:34:00 -07002767 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002768 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002769 }
fmalita160ebb22015-04-01 20:58:37 -07002770}
2771
2772void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2773 if (fPaint.isValid()) {
2774 SkRect bounds = fPicture->cullRect();
2775 if (fMatrix.isValid()) {
2776 fMatrix.get()->mapRect(&bounds);
2777 }
2778 canvas->saveLayer(&bounds, fPaint.get());
2779 }
2780
2781 if (fMatrix.isValid()) {
2782 if (!fPaint.isValid()) {
2783 canvas->save();
2784 }
2785 canvas->concat(*fMatrix.get());
2786 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002787}
2788
fmalita160ebb22015-04-01 20:58:37 -07002789bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002790 canvas->clear(0xFFFFFFFF);
2791 canvas->save();
2792
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002793 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002794
robertphillips9b14f262014-06-04 05:40:44 -07002795 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002796
2797 canvas->restore();
2798
2799 return true;
2800}
2801
fmalita160ebb22015-04-01 20:58:37 -07002802SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2803 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2804
2805void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2806 if (fRestore) {
2807 canvas->restore();
2808 }
2809}
2810
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002811SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002812 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002813 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002814 fMode = mode;
2815 fCount = count;
2816 fPts = new SkPoint[count];
2817 memcpy(fPts, pts, count * sizeof(SkPoint));
2818 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002819}
2820
fmalita8c89c522014-11-08 16:18:56 -08002821void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002822 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002823}
2824
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002825bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002826 canvas->clear(0xFFFFFFFF);
2827 canvas->save();
2828
2829 SkRect bounds;
2830
2831 bounds.setEmpty();
2832 for (unsigned int i = 0; i < fCount; ++i) {
Mike Reed185ffe92018-01-08 17:09:54 -05002833 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002834 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002835
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002836 xlate_and_scale_to_bounds(canvas, bounds);
2837
2838 SkPaint p;
2839 p.setColor(SK_ColorBLACK);
2840 p.setStyle(SkPaint::kStroke_Style);
2841
2842 canvas->drawPoints(fMode, fCount, fPts, p);
2843 canvas->restore();
2844
2845 return true;
2846}
2847
ethannicholasf62a8b72016-02-11 10:35:21 -08002848Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2849 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002850 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2851 Json::Value points(Json::arrayValue);
2852 for (size_t i = 0; i < fCount; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002853 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002854 }
2855 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07002856 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002857 return result;
2858}
2859
halcanary9d524f22016-03-29 09:03:52 -07002860SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002861 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002862 SkCanvas::PointMode mode;
2863 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2864 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2865 mode = SkCanvas::kPoints_PointMode;
2866 }
2867 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2868 mode = SkCanvas::kLines_PointMode;
2869 }
2870 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2871 mode = SkCanvas::kPolygon_PointMode;
2872 }
2873 else {
2874 SkASSERT(false);
2875 return nullptr;
2876 }
2877 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2878 int count = (int) jsonPoints.size();
2879 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2880 for (int i = 0; i < count; i++) {
2881 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2882 }
2883 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002884 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002885 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2886 sk_free(points);
2887 return result;
2888}
2889
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002890SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002891 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002892 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002893 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002894
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002895 fText = new char[byteLength];
2896 memcpy(fText, text, byteLength);
2897 fByteLength = byteLength;
2898
2899 fPos = new SkPoint[numPts];
2900 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2901
2902 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002903}
2904
fmalita8c89c522014-11-08 16:18:56 -08002905void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002906 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002907}
2908
ethannicholasf62a8b72016-02-11 10:35:21 -08002909Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2910 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002911 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002912 ((const char*) fText) + fByteLength);
2913 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08002914 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2915 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002916 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002917 }
2918 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07002919 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002920 return result;
2921}
2922
halcanary9d524f22016-03-29 09:03:52 -07002923SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002924 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002925 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2926 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002927 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002928 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2929 int count = (int) coords.size();
2930 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2931 for (int i = 0; i < count; i++) {
2932 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2933 }
2934 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2935}
chudy@google.com902ebe52012-06-29 14:21:22 +00002936
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002937SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2938 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002939 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002940 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002941 size_t numPts = paint.countText(text, byteLength);
2942
2943 fText = new char[byteLength];
2944 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002945 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002946
2947 fXpos = new SkScalar[numPts];
2948 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2949
robertphillips@google.com91217d02013-03-17 18:33:46 +00002950 fConstY = constY;
2951 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002952}
2953
fmalita8c89c522014-11-08 16:18:56 -08002954void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002955 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002956}
2957
bungeman51190df2016-03-09 07:42:54 -08002958Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
2959 Json::Value result = INHERITED::toJSON(urlDataManager);
2960 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2961 ((const char*) fText) + fByteLength);
2962 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
2963 Json::Value xpos(Json::arrayValue);
2964 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2965 for (size_t i = 0; i < numXpos; i++) {
2966 xpos.append(Json::Value(fXpos[i]));
2967 }
2968 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07002969 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08002970 return result;
2971}
2972
2973SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
2974 UrlDataManager& urlDataManager) {
2975 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2976 SkPaint paint;
2977 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2978 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2979 int count = (int) jsonXpos.size();
2980 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
2981 for (int i = 0; i < count; i++) {
2982 xpos[i] = jsonXpos[i].asFloat();
2983 }
2984 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2985 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
2986}
2987
fmalita37283c22016-09-13 10:00:23 -07002988SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07002989 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002990 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07002991 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07002992 , fXPos(x)
2993 , fYPos(y)
Brian Osman255735e2018-04-06 14:51:42 -04002994 , fPaint(paint) {}
fmalitab7425172014-08-26 07:56:44 -07002995
fmalita8c89c522014-11-08 16:18:56 -08002996void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07002997 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2998}
2999
fmalita55773872014-08-29 15:08:20 -07003000bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
3001 canvas->clear(SK_ColorWHITE);
3002 canvas->save();
3003
3004 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
3005 xlate_and_scale_to_bounds(canvas, bounds);
3006
fmalita37283c22016-09-13 10:00:23 -07003007 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07003008
3009 canvas->restore();
3010
3011 return true;
3012}
3013
ethannicholasf62a8b72016-02-11 10:35:21 -08003014Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
3015 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003016 Json::Value runs(Json::arrayValue);
3017 SkTextBlobRunIterator iter(fBlob.get());
3018 while (!iter.done()) {
3019 Json::Value run(Json::objectValue);
3020 Json::Value jsonPositions(Json::arrayValue);
3021 Json::Value jsonGlyphs(Json::arrayValue);
3022 const SkScalar* iterPositions = iter.pos();
3023 const uint16_t* iterGlyphs = iter.glyphs();
3024 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
3025 switch (iter.positioning()) {
3026 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07003027 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
3028 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08003029 break;
3030 case SkTextBlob::kHorizontal_Positioning:
3031 jsonPositions.append(Json::Value(iterPositions[i]));
3032 break;
3033 case SkTextBlob::kDefault_Positioning:
3034 break;
3035 }
3036 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
3037 }
3038 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
3039 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
3040 }
3041 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
3042 SkPaint fontPaint;
3043 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07003044 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
3045 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08003046 runs.append(run);
3047 iter.next();
3048 }
reed6d2c3e72016-07-07 14:10:14 -07003049 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08003050 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
3051 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
3052 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07003053 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07003054 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07003055
3056 SkString desc;
3057 // make the bounds local by applying the x,y
3058 bounds.offset(fXPos, fYPos);
3059 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
3060
ethannicholas50a8dd02016-02-10 05:40:46 -08003061 return result;
3062}
3063
halcanary9d524f22016-03-29 09:03:52 -07003064SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003065 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003066 SkTextBlobBuilder builder;
3067 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
3068 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
3069 Json::Value run = runs[i];
3070 SkPaint font;
3071 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
ethannicholasf62a8b72016-02-11 10:35:21 -08003072 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
ethannicholas50a8dd02016-02-10 05:40:46 -08003073 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
3074 int count = glyphs.size();
3075 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3076 SkScalar x = coords[0].asFloat();
3077 SkScalar y = coords[1].asFloat();
reed6d2c3e72016-07-07 14:10:14 -07003078 SkRect bounds;
3079 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
3080
ethannicholas50a8dd02016-02-10 05:40:46 -08003081 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
3082 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3083 if (positions.size() > 0 && positions[0].isNumeric()) {
reed6d2c3e72016-07-07 14:10:14 -07003084 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003085 for (int j = 0; j < count; j++) {
3086 buffer.glyphs[j] = glyphs[j].asUInt();
3087 buffer.pos[j] = positions[j].asFloat();
3088 }
3089 }
3090 else {
reed6d2c3e72016-07-07 14:10:14 -07003091 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003092 for (int j = 0; j < count; j++) {
3093 buffer.glyphs[j] = glyphs[j].asUInt();
3094 buffer.pos[j * 2] = positions[j][0].asFloat();
3095 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
3096 }
3097 }
3098 }
3099 else {
reed6d2c3e72016-07-07 14:10:14 -07003100 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003101 for (int j = 0; j < count; j++) {
3102 buffer.glyphs[j] = glyphs[j].asUInt();
3103 }
3104 }
3105 }
3106 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
3107 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3108 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003109 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
fmalita37283c22016-09-13 10:00:23 -07003110 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003111}
3112
robertphillips9bafc302015-02-13 11:13:00 -08003113SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04003114 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08003115 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003116 : INHERITED(kDrawPatch_OpType)
3117 , fBlendMode(bmode)
3118{
robertphillips9bafc302015-02-13 11:13:00 -08003119 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08003120 if (colors != nullptr) {
3121 memcpy(fColors, colors, sizeof(fColors));
3122 fColorsPtr = fColors;
3123 } else {
3124 fColorsPtr = nullptr;
3125 }
3126 if (texCoords != nullptr) {
3127 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3128 fTexCoordsPtr = fTexCoords;
3129 } else {
3130 fTexCoordsPtr = nullptr;
3131 }
robertphillips9bafc302015-02-13 11:13:00 -08003132 fPaint = paint;
robertphillips9bafc302015-02-13 11:13:00 -08003133}
3134
3135void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04003136 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08003137}
3138
ethannicholasf62a8b72016-02-11 10:35:21 -08003139Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3140 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08003141 Json::Value cubics = Json::Value(Json::arrayValue);
3142 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003143 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003144 }
3145 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3146 if (fColorsPtr != nullptr) {
3147 Json::Value colors = Json::Value(Json::arrayValue);
3148 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003149 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003150 }
3151 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3152 }
3153 if (fTexCoordsPtr != nullptr) {
3154 Json::Value texCoords = Json::Value(Json::arrayValue);
3155 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003156 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003157 }
3158 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3159 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003160 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08003161 return result;
3162}
3163
halcanary9d524f22016-03-29 09:03:52 -07003164SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003165 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08003166 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3167 SkPoint cubics[12];
3168 for (int i = 0; i < 12; i++) {
3169 cubics[i] = get_json_point(jsonCubics[i]);
3170 }
3171 SkColor* colorsPtr;
3172 SkColor colors[4];
3173 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3174 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3175 for (int i = 0; i < 4; i++) {
3176 colors[i] = get_json_color(jsonColors[i]);
3177 }
3178 colorsPtr = colors;
3179 }
3180 else {
3181 colorsPtr = nullptr;
3182 }
3183 SkPoint* texCoordsPtr;
3184 SkPoint texCoords[4];
3185 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3186 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3187 for (int i = 0; i < 4; i++) {
3188 texCoords[i] = get_json_point(jsonTexCoords[i]);
3189 }
3190 texCoordsPtr = texCoords;
3191 }
3192 else {
3193 texCoordsPtr = nullptr;
3194 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003195
3196 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3197
ethannicholas1446a9a2016-02-10 14:05:02 -08003198 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003199 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04003200 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
robertphillips9bafc302015-02-13 11:13:00 -08003201}
3202
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003203SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003204 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003205 fRect = rect;
3206 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003207}
3208
fmalita8c89c522014-11-08 16:18:56 -08003209void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003210 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003211}
3212
ethannicholasf62a8b72016-02-11 10:35:21 -08003213Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3214 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07003215 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3216 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07003217
3218 SkString desc;
3219 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3220
ethannicholas50a8dd02016-02-10 05:40:46 -08003221 return result;
3222}
3223
halcanary9d524f22016-03-29 09:03:52 -07003224SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003225 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003226 SkRect coords;
3227 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3228 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003229 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003230 return new SkDrawRectCommand(coords, paint);
3231}
3232
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003233SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003234 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003235 fRRect = rrect;
3236 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00003237}
3238
fmalita8c89c522014-11-08 16:18:56 -08003239void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00003240 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00003241}
3242
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003243bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00003244 render_rrect(canvas, fRRect);
3245 return true;
3246}
3247
ethannicholasf62a8b72016-02-11 10:35:21 -08003248Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3249 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003250 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07003251 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003252 return result;
3253}
3254
halcanary9d524f22016-03-29 09:03:52 -07003255SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003256 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003257 SkRRect coords;
3258 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3259 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003260 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003261 return new SkDrawRRectCommand(coords, paint);
3262}
3263
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00003264SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003265 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003266 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003267 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003268 fOuter = outer;
3269 fInner = inner;
3270 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003271}
3272
fmalita8c89c522014-11-08 16:18:56 -08003273void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003274 canvas->drawDRRect(fOuter, fInner, fPaint);
3275}
3276
3277bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3278 render_drrect(canvas, fOuter, fInner);
3279 return true;
3280}
3281
ethannicholasf62a8b72016-02-11 10:35:21 -08003282Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3283 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003284 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3285 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07003286 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003287 return result;
3288}
3289
halcanary9d524f22016-03-29 09:03:52 -07003290SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003291 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003292 SkRRect outer;
3293 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3294 SkRRect inner;
3295 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3296 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003297 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003298 return new SkDrawDRRectCommand(outer, inner, paint);
3299}
3300
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04003301SkDrawShadowCommand::SkDrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
3302 : INHERITED(kDrawShadow_OpType) {
3303 fPath = path;
3304 fShadowRec = rec;
3305}
3306
3307void SkDrawShadowCommand::execute(SkCanvas* canvas) const {
3308 canvas->private_draw_shadow_rec(fPath, fShadowRec);
3309}
3310
3311bool SkDrawShadowCommand::render(SkCanvas* canvas) const {
3312 render_shadow(canvas, fPath, fShadowRec);
3313 return true;
3314}
3315
3316Json::Value SkDrawShadowCommand::toJSON(UrlDataManager& urlDataManager) const {
3317 Json::Value result = INHERITED::toJSON(urlDataManager);
3318 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3319
3320 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
3321 bool transparentOccluder =
3322 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
3323
3324 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3325 result[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE] = MakeJsonPoint3(fShadowRec.fZPlaneParams);
3326 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION] = MakeJsonPoint3(fShadowRec.fLightPos);
3327 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS] = MakeJsonScalar(fShadowRec.fLightRadius);
3328 result[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR] = MakeJsonColor(fShadowRec.fAmbientColor);
3329 result[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR] = MakeJsonColor(fShadowRec.fSpotColor);
3330 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
3331 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
3332 return result;
3333}
3334
3335SkDrawShadowCommand* SkDrawShadowCommand::fromJSON(Json::Value& command,
3336 UrlDataManager& urlDataManager) {
3337 SkPath path;
3338 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3339 SkDrawShadowRec rec;
3340 rec.fZPlaneParams = get_json_point3(command[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE]);
3341 rec.fLightPos = get_json_point3(command[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION]);
3342 rec.fLightRadius = command[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS].asFloat();
3343 rec.fAmbientColor = get_json_color(command[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR]);
3344 rec.fSpotColor = get_json_color(command[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR]);
3345
3346 rec.fFlags = SkShadowFlags::kNone_ShadowFlag;
3347 if (command.isMember(SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC)
3348 && command[SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC].asBool()) {
3349 rec.fFlags |= SkShadowFlags::kTransparentOccluder_ShadowFlag;
3350 }
3351 if (command.isMember(SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY)
3352 && command[SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY].asBool()) {
3353 rec.fFlags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
3354 }
3355 return new SkDrawShadowCommand(path, rec);
3356}
3357
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003358SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003359 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003360 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003361 fText = new char[byteLength];
3362 memcpy(fText, text, byteLength);
3363 fByteLength = byteLength;
3364 fX = x;
3365 fY = y;
3366 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003367}
3368
fmalita8c89c522014-11-08 16:18:56 -08003369void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003370 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003371}
3372
ethannicholasf62a8b72016-02-11 10:35:21 -08003373Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3374 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003375 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003376 ((const char*) fText) + fByteLength);
3377 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003378 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3379 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003380 return result;
3381}
3382
halcanary9d524f22016-03-29 09:03:52 -07003383SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003384 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003385 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3386 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003387 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003388 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
halcanary9d524f22016-03-29 09:03:52 -07003389 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08003390 paint);
3391}
3392
reed45561a02016-07-07 12:47:17 -07003393///////////////////////////////////////////////////////////////////////////////////////////////////
3394
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003395SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3396 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003397 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003398 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003399 fText = new char[byteLength];
3400 memcpy(fText, text, byteLength);
3401 fByteLength = byteLength;
3402 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07003403 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003404 fMatrix = *matrix;
3405 } else {
3406 fMatrix.setIdentity();
3407 }
3408 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003409}
3410
fmalita8c89c522014-11-08 16:18:56 -08003411void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003412 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07003413 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003414 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003415}
3416
ethannicholasf62a8b72016-02-11 10:35:21 -08003417Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3418 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003419 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003420 ((const char*) fText) + fByteLength);
3421 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003422 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08003423 if (!fMatrix.isIdentity()) {
joshualittbd724132016-03-03 11:39:38 -08003424 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003425 }
brianosmanfad98562016-05-04 11:06:28 -07003426 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003427 return result;
3428}
3429
halcanary9d524f22016-03-29 09:03:52 -07003430SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003431 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003432 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3433 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003434 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003435 SkPath path;
3436 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3437 SkMatrix* matrixPtr;
3438 SkMatrix matrix;
3439 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3440 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3441 matrixPtr = &matrix;
3442 }
3443 else {
3444 matrixPtr = nullptr;
3445 }
3446 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3447}
3448
reed45561a02016-07-07 12:47:17 -07003449///////////////////////////////////////////////////////////////////////////////////////////////////
3450
3451SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3452 const SkRSXform xform[], const SkRect* cull,
3453 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07003454 : INHERITED(kDrawTextRSXform_OpType)
reed45561a02016-07-07 12:47:17 -07003455{
3456 fText = new char[byteLength];
3457 memcpy(fText, text, byteLength);
3458 fByteLength = byteLength;
3459 int count = paint.countText(text, byteLength);
3460 fXform = new SkRSXform[count];
3461 memcpy(fXform, xform, count * sizeof(SkRSXform));
3462 if (cull) {
3463 fCullStorage = *cull;
3464 fCull = &fCullStorage;
3465 } else {
3466 fCull = nullptr;
3467 }
3468 fPaint = paint;
reed45561a02016-07-07 12:47:17 -07003469}
3470
3471void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3472 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3473}
3474
3475Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3476 Json::Value result = INHERITED::toJSON(urlDataManager);
3477 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3478 ((const char*) fText) + fByteLength);
3479 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3480 return result;
3481}
3482
3483SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3484 UrlDataManager& urlDataManager) {
3485 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3486 size_t byteLength = strlen(text);
3487 SkPaint paint;
3488 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3489
3490 // TODO: handle xform and cull
3491 int count = paint.countText(text, byteLength);
3492 SkAutoTArray<SkRSXform> xform(count);
3493 for (int i = 0; i < count; ++i) {
3494 xform[i].fSCos = 1;
3495 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3496 }
3497 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3498}
3499
3500///////////////////////////////////////////////////////////////////////////////////////////////////
3501
Mike Reedfed9cfd2017-03-17 12:09:04 -04003502SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003503 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003504 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003505 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04003506 , fBlendMode(bmode)
Brian Osman255735e2018-04-06 14:51:42 -04003507 , fPaint(paint) {}
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003508
fmalita8c89c522014-11-08 16:18:56 -08003509void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04003510 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003511}
3512
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003513SkRestoreCommand::SkRestoreCommand()
Brian Osman255735e2018-04-06 14:51:42 -04003514 : INHERITED(kRestore_OpType) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00003515
fmalita8c89c522014-11-08 16:18:56 -08003516void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00003517 canvas->restore();
3518}
3519
ethannicholasf62a8b72016-02-11 10:35:21 -08003520SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003521 return new SkRestoreCommand();
3522}
3523
Florin Malita5f6102d2014-06-30 10:13:28 -04003524SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003525 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00003526}
3527
fmalita8c89c522014-11-08 16:18:56 -08003528void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04003529 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00003530}
3531
ethannicholasf62a8b72016-02-11 10:35:21 -08003532SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003533 return new SkSaveCommand();
3534}
3535
reed4960eee2015-12-18 07:09:18 -08003536SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08003537 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08003538 if (rec.fBounds) {
3539 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003540 } else {
3541 fBounds.setEmpty();
3542 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003543
reed4960eee2015-12-18 07:09:18 -08003544 if (rec.fPaint) {
3545 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003546 fPaintPtr = &fPaint;
3547 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07003548 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003549 }
reed4960eee2015-12-18 07:09:18 -08003550 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003551
ethannicholas50a8dd02016-02-10 05:40:46 -08003552 if (rec.fBackdrop) {
3553 fBackdrop = rec.fBackdrop;
3554 fBackdrop->ref();
3555 } else {
3556 fBackdrop = nullptr;
3557 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003558}
3559
ethannicholas50a8dd02016-02-10 05:40:46 -08003560SkSaveLayerCommand::~SkSaveLayerCommand() {
3561 if (fBackdrop != nullptr) {
3562 fBackdrop->unref();
3563 }
3564}
3565
fmalita8c89c522014-11-08 16:18:56 -08003566void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08003567 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3568 fPaintPtr,
3569 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003570}
3571
ethannicholasf62a8b72016-02-11 10:35:21 -08003572Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3573 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003574 if (!fBounds.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07003575 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003576 }
3577 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07003578 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
ethannicholasf62a8b72016-02-11 10:35:21 -08003579 urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003580 }
3581 if (fBackdrop != nullptr) {
3582 Json::Value jsonBackdrop;
ethannicholasf62a8b72016-02-11 10:35:21 -08003583 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003584 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3585 }
3586 if (fSaveLayerFlags != 0) {
3587 SkDebugf("unsupported: saveLayer flags\n");
3588 SkASSERT(false);
3589 }
3590 return result;
3591}
3592
halcanary9d524f22016-03-29 09:03:52 -07003593SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003594 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003595 SkCanvas::SaveLayerRec rec;
3596 SkRect bounds;
3597 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3598 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3599 rec.fBounds = &bounds;
3600 }
3601 SkPaint paint;
3602 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08003603 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003604 rec.fPaint = &paint;
3605 }
3606 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3607 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
ethannicholasf62a8b72016-02-11 10:35:21 -08003608 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003609 }
3610 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3611 if (rec.fBackdrop != nullptr) {
3612 rec.fBackdrop->unref();
3613 }
3614 return result;
3615}
3616
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003617SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08003618 : INHERITED(kSetMatrix_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003619 fMatrix = matrix;
robertphillips70171682014-10-16 14:28:28 -07003620}
3621
fmalita8c89c522014-11-08 16:18:56 -08003622void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
Brian Osman255735e2018-04-06 14:51:42 -04003623 canvas->setMatrix(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00003624}
3625
ethannicholasf62a8b72016-02-11 10:35:21 -08003626Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3627 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08003628 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003629 return result;
3630}
3631
halcanary9d524f22016-03-29 09:03:52 -07003632SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003633 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003634 SkMatrix matrix;
3635 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3636 return new SkSetMatrixCommand(matrix);
3637}