blob: 4740b4bf27f90f9ac3b73762538bb1cae8ed0c0a [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";
Brian Osman616f1cb2018-05-29 11:23:35 -0400253 case kDrawAtlas_OpType: return "DrawAtlas";
fmalita160ebb22015-04-01 20:58:37 -0700254 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800255 case kRestore_OpType: return "Restore";
256 case kSave_OpType: return "Save";
257 case kSaveLayer_OpType: return "SaveLayer";
258 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000259 default:
robertphillips9bafc302015-02-13 11:13:00 -0800260 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000261 SkASSERT(0);
262 break;
263 }
264 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700265 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000266}
267
ethannicholasf62a8b72016-02-11 10:35:21 -0800268Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800269 Json::Value result;
270 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800271 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800272 return result;
273}
274
275#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
276 (FROM_JSON) Sk ## name ## Command::fromJSON)
ethannicholasf62a8b72016-02-11 10:35:21 -0800277SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800278 static SkTHashMap<SkString, FROM_JSON> factories;
279 static bool initialized = false;
280 if (!initialized) {
281 initialized = true;
282 INSTALL_FACTORY(Restore);
Brian Osmanc25e2692018-03-12 10:57:28 -0400283 INSTALL_FACTORY(Clear);
ethannicholas50a8dd02016-02-10 05:40:46 -0800284 INSTALL_FACTORY(ClipPath);
285 INSTALL_FACTORY(ClipRegion);
286 INSTALL_FACTORY(ClipRect);
287 INSTALL_FACTORY(ClipRRect);
288 INSTALL_FACTORY(Concat);
reed97660cc2016-06-28 18:54:19 -0700289 INSTALL_FACTORY(DrawAnnotation);
ethannicholas50a8dd02016-02-10 05:40:46 -0800290 INSTALL_FACTORY(DrawBitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800291 INSTALL_FACTORY(DrawBitmapNine);
Brian Osmanc25e2692018-03-12 10:57:28 -0400292 INSTALL_FACTORY(DrawBitmapRect);
ethannicholas50a8dd02016-02-10 05:40:46 -0800293 INSTALL_FACTORY(DrawImage);
Brian Osmanc25e2692018-03-12 10:57:28 -0400294 INSTALL_FACTORY(DrawImageLattice);
295 INSTALL_FACTORY(DrawImageNine);
ethannicholas50a8dd02016-02-10 05:40:46 -0800296 INSTALL_FACTORY(DrawImageRect);
297 INSTALL_FACTORY(DrawOval);
Brian Osmanc25e2692018-03-12 10:57:28 -0400298 INSTALL_FACTORY(DrawArc);
ethannicholas50a8dd02016-02-10 05:40:46 -0800299 INSTALL_FACTORY(DrawPaint);
300 INSTALL_FACTORY(DrawPath);
301 INSTALL_FACTORY(DrawPoints);
Brian Osmanc25e2692018-03-12 10:57:28 -0400302 INSTALL_FACTORY(DrawRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -0800303 INSTALL_FACTORY(DrawText);
304 INSTALL_FACTORY(DrawPosText);
bungeman51190df2016-03-09 07:42:54 -0800305 INSTALL_FACTORY(DrawPosTextH);
ethannicholas50a8dd02016-02-10 05:40:46 -0800306 INSTALL_FACTORY(DrawTextOnPath);
reed45561a02016-07-07 12:47:17 -0700307 INSTALL_FACTORY(DrawTextRSXform);
ethannicholas50a8dd02016-02-10 05:40:46 -0800308 INSTALL_FACTORY(DrawTextBlob);
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400309 INSTALL_FACTORY(DrawShadow);
ethannicholas50a8dd02016-02-10 05:40:46 -0800310 INSTALL_FACTORY(DrawRect);
311 INSTALL_FACTORY(DrawRRect);
312 INSTALL_FACTORY(DrawDRRect);
ethannicholas1446a9a2016-02-10 14:05:02 -0800313 INSTALL_FACTORY(DrawPatch);
ethannicholas50a8dd02016-02-10 05:40:46 -0800314 INSTALL_FACTORY(Save);
315 INSTALL_FACTORY(SaveLayer);
316 INSTALL_FACTORY(SetMatrix);
317 }
318 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
319 FROM_JSON* factory = factories.find(name);
320 if (factory == nullptr) {
321 SkDebugf("no JSON factory for '%s'\n", name.c_str());
322 return nullptr;
323 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800324 return (*factory)(command, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800325}
326
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000327namespace {
328
329void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500330 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000331
332 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
333
334 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
335 if (bounds.width() > bounds.height()) {
336 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
337 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
338 } else {
339 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
340 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
341 }
342 canvas->translate(-bounds.centerX(), -bounds.centerY());
343}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000344
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000345
346void render_path(SkCanvas* canvas, const SkPath& path) {
347 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000348
349 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700350 if (bounds.isEmpty()) {
351 return;
352 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000353
fmalitab0cd8b72015-10-06 07:24:03 -0700354 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000355 xlate_and_scale_to_bounds(canvas, bounds);
356
357 SkPaint p;
358 p.setColor(SK_ColorBLACK);
359 p.setStyle(SkPaint::kStroke_Style);
360
361 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000362}
363
Brian Osmanc25e2692018-03-12 10:57:28 -0400364void render_region(SkCanvas* canvas, const SkRegion& region) {
365 canvas->clear(0xFFFFFFFF);
366
367 const SkIRect& bounds = region.getBounds();
368 if (bounds.isEmpty()) {
369 return;
370 }
371
372 SkAutoCanvasRestore acr(canvas, true);
Brian Osman99b63402018-03-13 10:19:27 -0400373 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
Brian Osmanc25e2692018-03-12 10:57:28 -0400374
375 SkPaint p;
376 p.setColor(SK_ColorBLACK);
377 p.setStyle(SkPaint::kStroke_Style);
378
379 canvas->drawRegion(region, p);
380}
381
halcanary96fcdcc2015-08-27 07:41:13 -0700382void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500383 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000384
385 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
386 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
387
388 if (input.width() > input.height()) {
389 yScale *= input.height() / (float) input.width();
390 } else {
391 xScale *= input.width() / (float) input.height();
392 }
393
394 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
395 xScale * input.width(),
396 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000397
robertphillips96a5cff2015-09-24 06:56:27 -0700398 static const int kNumBlocks = 8;
399
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000400 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700401 SkISize block = {
402 canvas->imageInfo().width()/kNumBlocks,
403 canvas->imageInfo().height()/kNumBlocks
404 };
405 for (int y = 0; y < kNumBlocks; ++y) {
406 for (int x = 0; x < kNumBlocks; ++x) {
407 SkPaint paint;
408 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
409 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
410 SkIntToScalar(y*block.height()),
411 SkIntToScalar(block.width()),
412 SkIntToScalar(block.height()));
413 canvas->drawRect(r, paint);
414 }
415 }
416
reede47829b2015-08-06 10:02:53 -0700417 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000418
bsalomon49f085d2014-09-05 13:34:00 -0700419 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000420 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
421 srcRect->fTop * yScale + SK_Scalar1,
422 srcRect->fRight * xScale + SK_Scalar1,
423 srcRect->fBottom * yScale + SK_Scalar1);
424 SkPaint p;
425 p.setColor(SK_ColorRED);
426 p.setStyle(SkPaint::kStroke_Style);
427
428 canvas->drawRect(r, p);
429 }
430}
431
432void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
433 canvas->clear(0xFFFFFFFF);
434 canvas->save();
435
436 const SkRect& bounds = rrect.getBounds();
437
438 xlate_and_scale_to_bounds(canvas, bounds);
439
440 SkPaint p;
441 p.setColor(SK_ColorBLACK);
442 p.setStyle(SkPaint::kStroke_Style);
443
444 canvas->drawRRect(rrect, p);
445 canvas->restore();
446}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000447
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000448void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
449 canvas->clear(0xFFFFFFFF);
450 canvas->save();
451
452 const SkRect& bounds = outer.getBounds();
453
454 xlate_and_scale_to_bounds(canvas, bounds);
455
456 SkPaint p;
457 p.setColor(SK_ColorBLACK);
458 p.setStyle(SkPaint::kStroke_Style);
459
460 canvas->drawDRRect(outer, inner, p);
461 canvas->restore();
462}
463
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400464void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
465 canvas->clear(0xFFFFFFFF);
466
467 const SkRect& bounds = path.getBounds();
468 if (bounds.isEmpty()) {
469 return;
470 }
471
472 SkAutoCanvasRestore acr(canvas, true);
473 xlate_and_scale_to_bounds(canvas, bounds);
474
475 rec.fAmbientColor = SK_ColorBLACK;
476 rec.fSpotColor = SK_ColorBLACK;
477 canvas->private_draw_shadow_rec(path, rec);
478}
479
Florin Malita82d80872017-06-06 16:58:40 -0400480static const char* const gBlendModeMap[] = {
481 "clear",
482 "src",
483 "dst",
484 "srcOver",
485 "dstOver",
486 "srcIn",
487 "dstIn",
488 "srcOut",
489 "dstOut",
490 "srcATop",
491 "dstATop",
492 "xor",
493 "plus",
494 "modulate",
495
496 "screen",
497
498 "overlay",
499 "darken",
500 "lighten",
501 "colorDodge",
502 "colorBurn",
503 "hardLight",
504 "softLight",
505 "difference",
506 "exclusion",
507 "multiply",
508
509 "hue",
510 "saturation",
511 "color",
512 "luminosity",
513};
514
515static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
516 "blendMode mismatch");
517static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
518 "blendMode mismatch");
519
520void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
521 const auto mode = paint.getBlendMode();
522 if (mode != SkBlendMode::kSrcOver) {
523 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
524 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
525 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
526 }
527}
528
529void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
530 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
531 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
532
533 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
534 if (!strcmp(mode, gBlendModeMap[i])) {
535 target->setBlendMode(static_cast<SkBlendMode>(i));
536 break;
537 }
538 }
539 }
540}
541
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000542};
543
brianosmanfad98562016-05-04 11:06:28 -0700544Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800545 Json::Value result(Json::arrayValue);
546 result.append(Json::Value(SkColorGetA(color)));
547 result.append(Json::Value(SkColorGetR(color)));
548 result.append(Json::Value(SkColorGetG(color)));
549 result.append(Json::Value(SkColorGetB(color)));
550 return result;
551}
552
brianosman97bbf822016-09-25 13:15:58 -0700553Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
554 Json::Value result(Json::arrayValue);
555 result.append(Json::Value(color.fA));
556 result.append(Json::Value(color.fR));
557 result.append(Json::Value(color.fG));
558 result.append(Json::Value(color.fB));
559 return result;
560}
561
brianosmanfad98562016-05-04 11:06:28 -0700562Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800563 Json::Value result(Json::arrayValue);
564 result.append(Json::Value(point.x()));
565 result.append(Json::Value(point.y()));
566 return result;
567}
568
brianosmanfad98562016-05-04 11:06:28 -0700569Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800570 Json::Value result(Json::arrayValue);
571 result.append(Json::Value(x));
572 result.append(Json::Value(y));
573 return result;
574}
575
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400576Json::Value SkDrawCommand::MakeJsonPoint3(const SkPoint3& point) {
577 Json::Value result(Json::arrayValue);
578 result.append(Json::Value(point.x()));
579 result.append(Json::Value(point.y()));
580 result.append(Json::Value(point.z()));
581 return result;
582}
583
brianosmanfad98562016-05-04 11:06:28 -0700584Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800585 Json::Value result(Json::arrayValue);
586 result.append(Json::Value(rect.left()));
587 result.append(Json::Value(rect.top()));
588 result.append(Json::Value(rect.right()));
589 result.append(Json::Value(rect.bottom()));
590 return result;
591}
592
joshualittbd724132016-03-03 11:39:38 -0800593Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800594 Json::Value result(Json::arrayValue);
595 result.append(Json::Value(rect.left()));
596 result.append(Json::Value(rect.top()));
597 result.append(Json::Value(rect.right()));
598 result.append(Json::Value(rect.bottom()));
599 return result;
600}
601
602static Json::Value make_json_rrect(const SkRRect& rrect) {
603 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700604 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
605 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
606 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
607 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
608 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800609 return result;
610}
611
joshualittbd724132016-03-03 11:39:38 -0800612Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800613 Json::Value result(Json::arrayValue);
614 Json::Value row1(Json::arrayValue);
615 row1.append(Json::Value(matrix[0]));
616 row1.append(Json::Value(matrix[1]));
617 row1.append(Json::Value(matrix[2]));
618 result.append(row1);
619 Json::Value row2(Json::arrayValue);
620 row2.append(Json::Value(matrix[3]));
621 row2.append(Json::Value(matrix[4]));
622 row2.append(Json::Value(matrix[5]));
623 result.append(row2);
624 Json::Value row3(Json::arrayValue);
625 row3.append(Json::Value(matrix[6]));
626 row3.append(Json::Value(matrix[7]));
627 row3.append(Json::Value(matrix[8]));
628 result.append(row3);
629 return result;
630}
ethannicholas1446a9a2016-02-10 14:05:02 -0800631
vjiaoblacke5de1302016-07-13 14:05:28 -0700632Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
633 Json::Value result(z);
634 return result;
635}
636
brianosmanfad98562016-05-04 11:06:28 -0700637Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800638 Json::Value result(Json::objectValue);
639 switch (path.getFillType()) {
640 case SkPath::kWinding_FillType:
641 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
642 break;
643 case SkPath::kEvenOdd_FillType:
644 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
645 break;
646 case SkPath::kInverseWinding_FillType:
647 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
648 break;
649 case SkPath::kInverseEvenOdd_FillType:
650 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
651 break;
halcanary9d524f22016-03-29 09:03:52 -0700652 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800653 Json::Value verbs(Json::arrayValue);
654 SkPath::Iter iter(path, false);
655 SkPoint pts[4];
656 SkPath::Verb verb;
657 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
658 switch (verb) {
659 case SkPath::kLine_Verb: {
660 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700661 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800662 verbs.append(line);
663 break;
664 }
665 case SkPath::kQuad_Verb: {
666 Json::Value quad(Json::objectValue);
667 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700668 coords.append(MakeJsonPoint(pts[1]));
669 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800670 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
671 verbs.append(quad);
672 break;
673 }
674 case SkPath::kCubic_Verb: {
675 Json::Value cubic(Json::objectValue);
676 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700677 coords.append(MakeJsonPoint(pts[1]));
678 coords.append(MakeJsonPoint(pts[2]));
679 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800680 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
681 verbs.append(cubic);
682 break;
683 }
684 case SkPath::kConic_Verb: {
685 Json::Value conic(Json::objectValue);
686 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700687 coords.append(MakeJsonPoint(pts[1]));
688 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800689 coords.append(Json::Value(iter.conicWeight()));
690 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
691 verbs.append(conic);
692 break;
693 }
694 case SkPath::kMove_Verb: {
695 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700696 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800697 verbs.append(move);
698 break;
699 }
700 case SkPath::kClose_Verb:
701 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
702 break;
703 case SkPath::kDone_Verb:
704 break;
705 }
706 }
707 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
708 return result;
709}
710
brianosmanfad98562016-05-04 11:06:28 -0700711Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
Brian Osmanc25e2692018-03-12 10:57:28 -0400712 // TODO: Actually serialize the rectangles, rather than just devolving to path
713 SkPath path;
714 region.getBoundaryPath(&path);
715 return MakeJsonPath(path);
ethannicholas50a8dd02016-02-10 05:40:46 -0800716}
717
Mike Reedc1f77742016-12-09 09:00:50 -0500718static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800719 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500720 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800721 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500722 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800723 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500724 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800725 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500726 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800727 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500728 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800729 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500730 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800731 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
732 default:
733 SkASSERT(false);
734 return Json::Value("<invalid region op>");
735 };
736}
737
738static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
739 switch (mode) {
740 case SkCanvas::kPoints_PointMode:
741 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
742 case SkCanvas::kLines_PointMode:
743 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700744 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800745 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
746 default:
747 SkASSERT(false);
748 return Json::Value("<invalid point mode>");
749 };
750}
751
halcanary9d524f22016-03-29 09:03:52 -0700752static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800753 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800754 if (value != defaultValue) {
755 (*target)[key] = Json::Value(value);
756 }
757}
758
ethannicholasbd3dae82016-02-10 12:10:00 -0800759static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800760 if (value != defaultValue) {
761 (*target)[key] = Json::Value(value);
762 }
763}
764
halcanary9d524f22016-03-29 09:03:52 -0700765static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800766 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700767 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
768 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800769 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800770}
771
brianosmanfad98562016-05-04 11:06:28 -0700772void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
773 UrlDataManager& urlDataManager) {
774 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800775 flattenable->flatten(buffer);
776 void* data = sk_malloc_throw(buffer.bytesWritten());
777 buffer.writeToMemory(data);
778 Json::Value jsonData;
779 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
780 Json::Value jsonFlattenable;
781 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
782 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700783
784 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
785 flattenable->flatten(jsonBuffer);
786 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
787
ethannicholasf62a8b72016-02-11 10:35:21 -0800788 (*target) = jsonFlattenable;
789 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800790}
791
ethannicholasf67531f2016-03-21 10:19:39 -0700792static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
793 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
794 out->write(data, length);
795}
796
halcanarya73d76a2016-10-17 13:19:02 -0700797void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700798 SkWStream& out, bool isOpaque) {
Ben Wagnera93a14a2017-08-28 10:34:05 -0400799 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700800 SkASSERT(png != nullptr);
801 png_infop info_ptr = png_create_info_struct(png);
802 SkASSERT(info_ptr != nullptr);
803 if (setjmp(png_jmpbuf(png))) {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400804 SK_ABORT("png encode error");
ethannicholasf67531f2016-03-21 10:19:39 -0700805 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400806 png_set_write_fn(png, &out, write_png_callback, nullptr);
msaretta5cf4f42016-06-30 10:06:51 -0700807 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
808 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700809 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
810 png_set_compression_level(png, 1);
811 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700812 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700813 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700814 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700815 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700816 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700817 rows[y][x * 4] = src[x * 4];
818 rows[y][x * 4 + 1] = src[x * 4 + 1];
819 rows[y][x * 4 + 2] = src[x * 4 + 2];
820 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700821 }
822 }
msaretta5cf4f42016-06-30 10:06:51 -0700823 png_write_info(png, info_ptr);
824 if (isOpaque) {
825 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
826 }
ethannicholasf67531f2016-03-21 10:19:39 -0700827 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700828 png_write_image(png, &rows[0]);
Ben Wagnera93a14a2017-08-28 10:34:05 -0400829 png_destroy_write_struct(&png, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700830 sk_free(rows);
831 sk_free(pixels);
832}
833
brianosmanfad98562016-05-04 11:06:28 -0700834bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
835 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700836 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500837 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700838 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700839 kN32_SkColorType, kPremul_SkAlphaType);
840 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
841 SkDebugf("readPixels failed\n");
842 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800843 }
msaretta5cf4f42016-06-30 10:06:51 -0700844
845 SkBitmap bm;
846 bm.installPixels(dstInfo, buffer.get(), rowBytes);
847 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
848
ethannicholasf67531f2016-03-21 10:19:39 -0700849 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700850 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700851 out, false);
reed42943c82016-09-12 12:01:44 -0700852 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800853 Json::Value jsonData;
854 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
855 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800856 return true;
857}
858
859static const char* color_type_name(SkColorType colorType) {
860 switch (colorType) {
861 case kARGB_4444_SkColorType:
862 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
863 case kRGBA_8888_SkColorType:
864 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
865 case kBGRA_8888_SkColorType:
866 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
867 case kRGB_565_SkColorType:
868 return SKDEBUGCANVAS_COLORTYPE_565;
869 case kGray_8_SkColorType:
870 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
ethannicholas50a8dd02016-02-10 05:40:46 -0800871 case kAlpha_8_SkColorType:
872 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
873 default:
874 SkASSERT(false);
875 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
876 }
877}
878
879static const char* alpha_type_name(SkAlphaType alphaType) {
880 switch (alphaType) {
881 case kOpaque_SkAlphaType:
882 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
883 case kPremul_SkAlphaType:
884 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
885 case kUnpremul_SkAlphaType:
886 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
887 default:
888 SkASSERT(false);
889 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
890 }
891}
892
halcanary9d524f22016-03-29 09:03:52 -0700893static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -0800894 const void** target) {
895 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
896 if (urlData == nullptr) {
897 SkASSERT(false);
898 *target = nullptr;
899 return 0;
ethannicholas50a8dd02016-02-10 05:40:46 -0800900 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800901 *target = urlData->fData->data();
902 // cast should be safe for any reasonably-sized object...
903 return (Json::ArrayIndex) urlData->fData->size();
ethannicholas50a8dd02016-02-10 05:40:46 -0800904}
905
halcanary9d524f22016-03-29 09:03:52 -0700906static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
ethannicholasf62a8b72016-02-11 10:35:21 -0800907 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800908 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
909 return nullptr;
910 }
911 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
912 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
913 if (factory == nullptr) {
914 SkDebugf("no factory for loading '%s'\n", name);
915 return nullptr;
916 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800917 const void* data;
918 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
Mike Reedfadbfcd2017-12-06 16:09:20 -0500919 SkReadBuffer buffer(data, size);
reed60c9b582016-04-03 09:11:13 -0700920 sk_sp<SkFlattenable> result = factory(buffer);
ethannicholas50a8dd02016-02-10 05:40:46 -0800921 if (!buffer.isValid()) {
922 SkDebugf("invalid buffer loading flattenable\n");
923 return nullptr;
924 }
reed60c9b582016-04-03 09:11:13 -0700925 return result.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800926}
927
928static SkColorType colortype_from_name(const char* name) {
929 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
930 return kARGB_4444_SkColorType;
931 }
932 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
933 return kRGBA_8888_SkColorType;
934 }
935 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
936 return kBGRA_8888_SkColorType;
937 }
938 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
939 return kRGB_565_SkColorType;
940 }
941 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
942 return kGray_8_SkColorType;
943 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800944 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
945 return kAlpha_8_SkColorType;
946 }
947 SkASSERT(false);
948 return kN32_SkColorType;
949}
950
951static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
952 if (bitmap->colorType() == colorType ) {
953 return bitmap;
954 }
955 SkBitmap* dst = new SkBitmap();
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400956 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
957 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
958 {
ethannicholas50a8dd02016-02-10 05:40:46 -0800959 delete bitmap;
960 return dst;
961 }
962 SkASSERT(false);
963 delete dst;
964 return bitmap;
965}
966
967// caller is responsible for freeing return value
ethannicholasf62a8b72016-02-11 10:35:21 -0800968static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
969 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800970 SkDebugf("invalid bitmap\n");
971 return nullptr;
972 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800973 const void* data;
974 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
bungeman38d909e2016-08-02 14:40:46 -0700975 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
reed9ce9d672016-03-17 10:51:11 -0700976 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
msarett790f99a2016-03-09 06:16:55 -0800977
Ben Wagner145dbcd2016-11-03 14:40:50 -0400978 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
msarett790f99a2016-03-09 06:16:55 -0800979 if (nullptr != image) {
Cary Clark4f5a79c2018-02-07 15:51:00 -0500980 if (!image->asLegacyBitmap(bitmap.get())) {
msarett790f99a2016-03-09 06:16:55 -0800981 SkDebugf("image decode failed\n");
982 return nullptr;
983 }
984
ethannicholas50a8dd02016-02-10 05:40:46 -0800985 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
986 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
987 SkColorType ct = colortype_from_name(ctName);
Mike Reed304a07c2017-07-12 15:10:28 -0400988 bitmap.reset(convert_colortype(bitmap.release(), ct));
ethannicholas50a8dd02016-02-10 05:40:46 -0800989 }
mtklein18300a32016-03-16 13:53:35 -0700990 return bitmap.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800991 }
992 SkDebugf("image decode failed\n");
ethannicholas50a8dd02016-02-10 05:40:46 -0800993 return nullptr;
994}
995
reed9ce9d672016-03-17 10:51:11 -0700996static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
ethannicholasf62a8b72016-02-11 10:35:21 -0800997 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800998 if (bitmap == nullptr) {
999 return nullptr;
1000 }
reed9ce9d672016-03-17 10:51:11 -07001001 auto result = SkImage::MakeFromBitmap(*bitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -08001002 delete bitmap;
1003 return result;
1004}
1005
brianosmanfad98562016-05-04 11:06:28 -07001006bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
1007 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07001008 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -08001009 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
1010 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -08001011 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001012 return success;
1013}
1014
halcanaryf412f092016-08-25 11:10:41 -07001015static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
1016 SkPaint::Hinting hinting = paint.getHinting();
1017 if (hinting != SkPaintDefaults_Hinting) {
1018 switch (hinting) {
1019 case SkPaint::kNo_Hinting:
1020 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
1021 break;
1022 case SkPaint::kSlight_Hinting:
1023 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
1024 break;
1025 case SkPaint::kNormal_Hinting:
1026 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
1027 break;
1028 case SkPaint::kFull_Hinting:
1029 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
1030 break;
1031 }
1032 }
1033}
1034
ethannicholas50a8dd02016-02-10 05:40:46 -08001035static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
1036 SkColor color = paint.getColor();
1037 if (color != SK_ColorBLACK) {
1038 Json::Value colorValue(Json::arrayValue);
1039 colorValue.append(Json::Value(SkColorGetA(color)));
1040 colorValue.append(Json::Value(SkColorGetR(color)));
1041 colorValue.append(Json::Value(SkColorGetG(color)));
1042 colorValue.append(Json::Value(SkColorGetB(color)));
1043 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
1044 }
1045}
1046
1047static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
1048 SkPaint::Style style = paint.getStyle();
1049 if (style != SkPaint::kFill_Style) {
1050 switch (style) {
1051 case SkPaint::kStroke_Style: {
1052 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
1053 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
1054 break;
1055 }
1056 case SkPaint::kStrokeAndFill_Style: {
1057 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1058 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1059 break;
1060 }
1061 default: SkASSERT(false);
1062 }
1063 }
1064}
1065
1066static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1067 SkPaint::Cap cap = paint.getStrokeCap();
1068 if (cap != SkPaint::kDefault_Cap) {
1069 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001070 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001071 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1072 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001073 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001074 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1075 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001076 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001077 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1078 break;
ethannicholas50a8dd02016-02-10 05:40:46 -08001079 default: SkASSERT(false);
1080 }
1081 }
1082}
ethannicholas1446a9a2016-02-10 14:05:02 -08001083
1084static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1085 SkPaint::Join join = paint.getStrokeJoin();
1086 if (join != SkPaint::kDefault_Join) {
1087 switch (join) {
1088 case SkPaint::kMiter_Join:
1089 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1090 SKDEBUGCANVAS_MITER_JOIN);
1091 break;
1092 case SkPaint::kRound_Join:
1093 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1094 SKDEBUGCANVAS_ROUND_JOIN);
1095 break;
1096 case SkPaint::kBevel_Join:
1097 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1098 SKDEBUGCANVAS_BEVEL_JOIN);
1099 break;
1100 default: SkASSERT(false);
1101 }
1102 }
1103}
1104
1105static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1106 SkFilterQuality quality = paint.getFilterQuality();
1107 switch (quality) {
1108 case kNone_SkFilterQuality:
1109 break;
1110 case kLow_SkFilterQuality:
1111 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1112 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1113 break;
1114 case kMedium_SkFilterQuality:
1115 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1116 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1117 break;
1118 case kHigh_SkFilterQuality:
1119 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1120 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1121 break;
1122 }
1123}
1124
halcanary9d524f22016-03-29 09:03:52 -07001125static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001126 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001127 SkMaskFilter* maskFilter = paint.getMaskFilter();
1128 if (maskFilter != nullptr) {
Mike Reed80747ef2018-01-23 15:29:32 -05001129 SkMaskFilterBase::BlurRec blurRec;
1130 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001131 Json::Value blur(Json::objectValue);
1132 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1133 switch (blurRec.fStyle) {
1134 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001135 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1136 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -08001137 break;
1138 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001139 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1140 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -08001141 break;
1142 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001143 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1144 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001145 break;
1146 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001147 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1148 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001149 break;
1150 default:
1151 SkASSERT(false);
1152 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001153 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1154 } else {
1155 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -07001156 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001157 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1158 }
1159 }
1160}
1161
halcanary9d524f22016-03-29 09:03:52 -07001162static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001163 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001164 SkPathEffect* pathEffect = paint.getPathEffect();
1165 if (pathEffect != nullptr) {
1166 SkPathEffect::DashInfo dashInfo;
1167 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1168 if (dashType == SkPathEffect::kDash_DashType) {
1169 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1170 pathEffect->asADash(&dashInfo);
1171 Json::Value dashing(Json::objectValue);
1172 Json::Value intervals(Json::arrayValue);
1173 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1174 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1175 }
1176 sk_free(dashInfo.fIntervals);
1177 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1178 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1179 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1180 } else {
1181 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001182 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001183 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1184 }
1185 }
1186}
halcanary9d524f22016-03-29 09:03:52 -07001187
ethannicholas50a8dd02016-02-10 05:40:46 -08001188static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1189 SkPaint::Align textAlign = paint.getTextAlign();
1190 if (textAlign != SkPaint::kLeft_Align) {
1191 switch (textAlign) {
1192 case SkPaint::kCenter_Align: {
1193 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1194 break;
1195 }
1196 case SkPaint::kRight_Align: {
1197 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1198 break;
1199 }
1200 default: SkASSERT(false);
1201 }
1202 }
1203}
1204
halcanary9d524f22016-03-29 09:03:52 -07001205static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001206 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001207 SkTypeface* typeface = paint.getTypeface();
1208 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001209 Json::Value jsonTypeface;
1210 SkDynamicMemoryWStream buffer;
1211 typeface->serialize(&buffer);
1212 void* data = sk_malloc_throw(buffer.bytesWritten());
1213 buffer.copyTo(data);
1214 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001215 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001216 &jsonData);
1217 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1218 sk_free(data);
1219 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001220 }
1221}
1222
halcanary9d524f22016-03-29 09:03:52 -07001223static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001224 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001225 SkFlattenable* shader = paint.getShader();
1226 if (shader != nullptr) {
1227 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001228 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001229 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1230 }
1231}
1232
ethannicholasf62a8b72016-02-11 10:35:21 -08001233static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1234 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001235 SkFlattenable* imageFilter = paint.getImageFilter();
1236 if (imageFilter != nullptr) {
1237 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001238 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001239 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1240 }
1241}
1242
halcanary9d524f22016-03-29 09:03:52 -07001243static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001244 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001245 SkFlattenable* colorFilter = paint.getColorFilter();
1246 if (colorFilter != nullptr) {
1247 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001248 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001249 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1250 }
1251}
1252
halcanary9d524f22016-03-29 09:03:52 -07001253static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001254 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001255 SkFlattenable* looper = paint.getLooper();
1256 if (looper != nullptr) {
1257 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001258 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001259 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1260 }
1261}
1262
brianosmanfad98562016-05-04 11:06:28 -07001263Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001264 Json::Value result(Json::objectValue);
1265 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001266 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001267 SkPaintDefaults_MiterLimit);
1268 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001269 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001270 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1271 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1272 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001273 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1274 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1275 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1276 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1277 //kGenA8FromLCD_Flag
1278
halcanary9d524f22016-03-29 09:03:52 -07001279 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001280 SkPaintDefaults_TextSize);
1281 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1282 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001283 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001284 apply_paint_color(paint, &result);
1285 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001286 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001287 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001288 apply_paint_join(paint, &result);
1289 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001290 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001291 apply_paint_patheffect(paint, &result, urlDataManager);
1292 apply_paint_maskfilter(paint, &result, urlDataManager);
1293 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001294 apply_paint_looper(paint, &result, urlDataManager);
1295 apply_paint_imagefilter(paint, &result, urlDataManager);
1296 apply_paint_colorfilter(paint, &result, urlDataManager);
1297 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001298 return result;
1299}
1300
Stan Ilievac42aeb2017-01-12 16:20:50 -05001301Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1302 Json::Value result(Json::objectValue);
1303 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1304 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1305 if (nullptr != lattice.fBounds) {
1306 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1307 }
1308 Json::Value XDivs(Json::arrayValue);
1309 for (int i = 0; i < lattice.fXCount; i++) {
1310 XDivs.append(Json::Value(lattice.fXDivs[i]));
1311 }
1312 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1313 Json::Value YDivs(Json::arrayValue);
1314 for (int i = 0; i < lattice.fYCount; i++) {
1315 YDivs.append(Json::Value(lattice.fYDivs[i]));
1316 }
1317 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
Stan Ilievca8c0952017-12-11 13:01:58 -05001318 if (nullptr != lattice.fRectTypes) {
Stan Ilievac42aeb2017-01-12 16:20:50 -05001319 Json::Value flags(Json::arrayValue);
1320 int flagCount = 0;
1321 for (int row = 0; row < lattice.fYCount+1; row++) {
1322 Json::Value flagsRow(Json::arrayValue);
1323 for (int column = 0; column < lattice.fXCount+1; column++) {
Stan Ilievca8c0952017-12-11 13:01:58 -05001324 flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++]));
Stan Ilievac42aeb2017-01-12 16:20:50 -05001325 }
1326 flags.append(flagsRow);
1327 }
1328 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1329 }
1330 return result;
1331}
1332
ethannicholas1446a9a2016-02-10 14:05:02 -08001333static SkPoint get_json_point(Json::Value point) {
1334 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1335}
1336
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04001337static SkPoint3 get_json_point3(Json::Value point) {
1338 return SkPoint3::Make(point[0].asFloat(), point[1].asFloat(), point[2].asFloat());
1339}
1340
ethannicholas1446a9a2016-02-10 14:05:02 -08001341static SkColor get_json_color(Json::Value color) {
1342 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1343}
1344
ethannicholas50a8dd02016-02-10 05:40:46 -08001345static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1346 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001347 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001348 }
1349}
1350
halcanary9d524f22016-03-29 09:03:52 -07001351static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001352 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001353 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1354 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
ethannicholasf62a8b72016-02-11 10:35:21 -08001355 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001356 if (shader != nullptr) {
reedfe630452016-03-25 09:08:00 -07001357 target->setShader(sk_ref_sp(shader));
ethannicholas50a8dd02016-02-10 05:40:46 -08001358 }
1359 }
1360}
1361
halcanary9d524f22016-03-29 09:03:52 -07001362static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001363 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001364 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1365 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
reeda4393342016-03-18 11:22:57 -07001366 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1367 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001368 if (pathEffect != nullptr) {
1369 target->setPathEffect(pathEffect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001370 }
1371 }
1372}
1373
halcanary9d524f22016-03-29 09:03:52 -07001374static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001375 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001376 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1377 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
reedefdfd512016-04-04 10:02:58 -07001378 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1379 urlDataManager));
1380 if (maskFilter) {
1381 target->setMaskFilter(std::move(maskFilter));
ethannicholas50a8dd02016-02-10 05:40:46 -08001382 }
1383 }
1384}
1385
halcanary9d524f22016-03-29 09:03:52 -07001386static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001387 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001388 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1389 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
reedd053ce92016-03-22 10:17:23 -07001390 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1391 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001392 if (colorFilter != nullptr) {
1393 target->setColorFilter(colorFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001394 }
1395 }
1396}
1397
halcanary9d524f22016-03-29 09:03:52 -07001398static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001399 SkPaint* target) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001400 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1401 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
reed7b380d02016-03-21 13:25:16 -07001402 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
ethannicholas1446a9a2016-02-10 14:05:02 -08001403 if (looper != nullptr) {
reed7b380d02016-03-21 13:25:16 -07001404 target->setLooper(std::move(looper));
ethannicholas1446a9a2016-02-10 14:05:02 -08001405 }
1406 }
1407}
1408
halcanary9d524f22016-03-29 09:03:52 -07001409static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001410 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001411 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1412 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
Mike Reed5e257172016-11-01 11:22:05 -04001413 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1414 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001415 if (imageFilter != nullptr) {
1416 target->setImageFilter(imageFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001417 }
1418 }
1419}
1420
halcanary9d524f22016-03-29 09:03:52 -07001421static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001422 SkPaint* target) {
1423 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1424 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1425 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1426 const void* data;
1427 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1428 SkMemoryStream buffer(data, length);
bungeman13b9c952016-05-12 10:09:30 -07001429 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
ethannicholasf62a8b72016-02-11 10:35:21 -08001430 }
1431}
1432
halcanaryf412f092016-08-25 11:10:41 -07001433static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1434 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1435 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1436 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1437 target->setHinting(SkPaint::kNo_Hinting);
1438 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1439 target->setHinting(SkPaint::kSlight_Hinting);
1440 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1441 target->setHinting(SkPaint::kNormal_Hinting);
1442 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1443 target->setHinting(SkPaint::kFull_Hinting);
1444 }
1445 }
1446}
1447
ethannicholas50a8dd02016-02-10 05:40:46 -08001448static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1449 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1450 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1451 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1452 target->setStyle(SkPaint::kFill_Style);
1453 }
1454 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1455 target->setStyle(SkPaint::kStroke_Style);
1456 }
1457 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1458 target->setStyle(SkPaint::kStrokeAndFill_Style);
1459 }
1460 }
1461}
1462
1463static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1464 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1465 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1466 target->setStrokeWidth(strokeWidth);
halcanary9d524f22016-03-29 09:03:52 -07001467 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001468}
1469
1470static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1471 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1472 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1473 target->setStrokeMiter(strokeMiter);
halcanary9d524f22016-03-29 09:03:52 -07001474 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001475}
1476
ethannicholas1446a9a2016-02-10 14:05:02 -08001477static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1478 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1479 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1480 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1481 target->setStrokeJoin(SkPaint::kMiter_Join);
1482 }
1483 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1484 target->setStrokeJoin(SkPaint::kRound_Join);
1485 }
1486 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1487 target->setStrokeJoin(SkPaint::kBevel_Join);
1488 }
1489 else {
1490 SkASSERT(false);
1491 }
1492 }
1493}
1494
ethannicholas50a8dd02016-02-10 05:40:46 -08001495static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1496 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1497 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1498 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1499 target->setStrokeCap(SkPaint::kButt_Cap);
1500 }
1501 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1502 target->setStrokeCap(SkPaint::kRound_Cap);
1503 }
1504 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1505 target->setStrokeCap(SkPaint::kSquare_Cap);
1506 }
1507 }
1508}
1509
ethannicholas1446a9a2016-02-10 14:05:02 -08001510static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1511 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1512 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1513 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1514 target->setFilterQuality(kNone_SkFilterQuality);
1515 }
1516 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1517 target->setFilterQuality(kLow_SkFilterQuality);
1518 }
1519 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1520 target->setFilterQuality(kMedium_SkFilterQuality);
1521 }
1522 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1523 target->setFilterQuality(kHigh_SkFilterQuality);
1524 }
1525 }
1526}
1527
ethannicholas50a8dd02016-02-10 05:40:46 -08001528static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1529 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1530 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1531 }
1532}
1533
ethannicholas1446a9a2016-02-10 14:05:02 -08001534static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1535 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1536 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1537 }
1538}
1539
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001540static void extract_json_paint_fakeboldtext(Json::Value& jsonPaint, SkPaint* target) {
1541 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT)) {
1542 target->setFakeBoldText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT].asBool());
1543 }
1544}
1545
1546static void extract_json_paint_lineartext(Json::Value& jsonPaint, SkPaint* target) {
1547 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT)) {
1548 target->setLinearText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT].asBool());
1549 }
1550}
1551
1552static void extract_json_paint_subpixeltext(Json::Value& jsonPaint, SkPaint* target) {
1553 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT)) {
1554 target->setSubpixelText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT].asBool());
1555 }
1556}
1557
1558static void extract_json_paint_devkerntext(Json::Value& jsonPaint, SkPaint* target) {
1559 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT)) {
1560 target->setDevKernText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT].asBool());
1561 }
1562}
1563
1564static void extract_json_paint_lcdrendertext(Json::Value& jsonPaint, SkPaint* target) {
1565 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT)) {
1566 target->setLCDRenderText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT].asBool());
1567 }
1568}
1569
1570static void extract_json_paint_embeddedbitmaptext(Json::Value& jsonPaint, SkPaint* target) {
1571 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT)) {
1572 target->setEmbeddedBitmapText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT].asBool());
1573 }
1574}
1575
1576static void extract_json_paint_autohinting(Json::Value& jsonPaint, SkPaint* target) {
1577 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING)) {
1578 target->setAutohinted(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING].asBool());
1579 }
1580}
1581
1582static void extract_json_paint_verticaltext(Json::Value& jsonPaint, SkPaint* target) {
1583 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT)) {
1584 target->setVerticalText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT].asBool());
1585 }
1586}
1587
ethannicholas50a8dd02016-02-10 05:40:46 -08001588static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1589 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1590 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1591 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1592 SkBlurStyle style;
1593 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1594 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1595 style = SkBlurStyle::kNormal_SkBlurStyle;
1596 }
1597 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1598 style = SkBlurStyle::kSolid_SkBlurStyle;
1599 }
1600 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1601 style = SkBlurStyle::kOuter_SkBlurStyle;
1602 }
1603 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1604 style = SkBlurStyle::kInner_SkBlurStyle;
1605 }
1606 else {
1607 SkASSERT(false);
1608 style = SkBlurStyle::kNormal_SkBlurStyle;
1609 }
Mike Reed1be1f8d2018-03-14 13:01:17 -04001610 target->setMaskFilter(SkMaskFilter::MakeBlur(style, sigma));
ethannicholas50a8dd02016-02-10 05:40:46 -08001611 }
1612}
1613
1614static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1615 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1616 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1617 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1618 Json::ArrayIndex count = jsonIntervals.size();
1619 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1620 for (Json::ArrayIndex i = 0; i < count; i++) {
1621 intervals[i] = jsonIntervals[i].asFloat();
1622 }
1623 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
reeda4393342016-03-18 11:22:57 -07001624 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
ethannicholas50a8dd02016-02-10 05:40:46 -08001625 sk_free(intervals);
1626 }
1627}
1628
1629static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1630 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1631 SkPaint::Align textAlign;
1632 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1633 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1634 textAlign = SkPaint::kLeft_Align;
1635 }
1636 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1637 textAlign = SkPaint::kCenter_Align;
1638 }
1639 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1640 textAlign = SkPaint::kRight_Align;
1641 }
1642 else {
1643 SkASSERT(false);
1644 textAlign = SkPaint::kLeft_Align;
1645 }
1646 target->setTextAlign(textAlign);
1647 }
1648}
1649
1650static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1651 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1652 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1653 target->setTextSize(textSize);
1654 }
1655}
1656
1657static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1658 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1659 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1660 target->setTextScaleX(textScaleX);
1661 }
1662}
1663
1664static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1665 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1666 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1667 target->setTextSkewX(textSkewX);
1668 }
1669}
1670
halcanary9d524f22016-03-29 09:03:52 -07001671static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001672 SkPaint* result) {
halcanaryf412f092016-08-25 11:10:41 -07001673 extract_json_paint_hinting(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001674 extract_json_paint_color(paint, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001675 extract_json_paint_shader(paint, urlDataManager, result);
1676 extract_json_paint_patheffect(paint, urlDataManager, result);
1677 extract_json_paint_maskfilter(paint, urlDataManager, result);
1678 extract_json_paint_colorfilter(paint, urlDataManager, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001679 extract_json_paint_looper(paint, urlDataManager, result);
1680 extract_json_paint_imagefilter(paint, urlDataManager, result);
1681 extract_json_paint_typeface(paint, urlDataManager, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001682 extract_json_paint_style(paint, result);
Florin Malita82d80872017-06-06 16:58:40 -04001683 extract_json_paint_blend_mode(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001684 extract_json_paint_strokewidth(paint, result);
1685 extract_json_paint_strokemiter(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001686 extract_json_paint_strokejoin(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001687 extract_json_paint_cap(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001688 extract_json_paint_filterquality(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001689 extract_json_paint_antialias(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001690 extract_json_paint_dither(paint, result);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001691 extract_json_paint_fakeboldtext(paint, result);
1692 extract_json_paint_lineartext(paint, result);
1693 extract_json_paint_subpixeltext(paint, result);
1694 extract_json_paint_devkerntext(paint, result);
1695 extract_json_paint_lcdrendertext(paint, result);
1696 extract_json_paint_embeddedbitmaptext(paint, result);
1697 extract_json_paint_autohinting(paint, result);
1698 extract_json_paint_verticaltext(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001699 extract_json_paint_blur(paint, result);
1700 extract_json_paint_dashing(paint, result);
1701 extract_json_paint_textalign(paint, result);
1702 extract_json_paint_textsize(paint, result);
1703 extract_json_paint_textscalex(paint, result);
1704 extract_json_paint_textskewx(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001705}
1706
1707static void extract_json_rect(Json::Value& rect, SkRect* result) {
1708 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1709}
1710
1711static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1712 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1713}
1714
1715static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1716 SkVector radii[4] = {
halcanary9d524f22016-03-29 09:03:52 -07001717 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1718 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1719 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
ethannicholas50a8dd02016-02-10 05:40:46 -08001720 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1721 };
halcanary9d524f22016-03-29 09:03:52 -07001722 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1723 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
ethannicholas50a8dd02016-02-10 05:40:46 -08001724 radii);
1725}
1726
1727static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
halcanary9d524f22016-03-29 09:03:52 -07001728 SkScalar values[] = {
ethannicholas50a8dd02016-02-10 05:40:46 -08001729 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1730 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
halcanary9d524f22016-03-29 09:03:52 -07001731 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
ethannicholas50a8dd02016-02-10 05:40:46 -08001732 };
1733 result->set9(values);
1734}
1735
1736static void extract_json_path(Json::Value& path, SkPath* result) {
1737 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1738 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1739 result->setFillType(SkPath::kWinding_FillType);
1740 }
1741 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1742 result->setFillType(SkPath::kEvenOdd_FillType);
1743 }
1744 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1745 result->setFillType(SkPath::kInverseWinding_FillType);
1746 }
1747 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1748 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1749 }
1750 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1751 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1752 Json::Value verb = verbs[i];
1753 if (verb.isString()) {
1754 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1755 result->close();
1756 }
1757 else {
1758 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1759 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1760 result->moveTo(move[0].asFloat(), move[1].asFloat());
1761 }
1762 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1763 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1764 result->lineTo(line[0].asFloat(), line[1].asFloat());
1765 }
1766 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1767 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1768 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1769 quad[1][0].asFloat(), quad[1][1].asFloat());
1770 }
1771 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1772 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1773 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1774 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1775 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1776 }
1777 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1778 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1779 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1780 conic[1][0].asFloat(), conic[1][1].asFloat(),
1781 conic[2].asFloat());
1782 }
1783 else {
1784 SkASSERT(false);
1785 }
1786 }
1787 }
1788}
1789
Brian Osmanc25e2692018-03-12 10:57:28 -04001790static void extract_json_region(Json::Value& region, SkRegion* result) {
1791 SkPath path;
1792 extract_json_path(region, &path);
1793 result->setPath(path, SkRegion(path.getBounds().roundOut()));
1794}
1795
Mike Reedc1f77742016-12-09 09:00:50 -05001796SkClipOp get_json_clipop(Json::Value& jsonOp) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001797 const char* op = jsonOp.asCString();
1798 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001799 return kDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001800 }
1801 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001802 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001803 }
1804 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001805 return kUnion_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001806 }
1807 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001808 return kXOR_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001809 }
1810 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001811 return kReverseDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001812 }
1813 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001814 return kReplace_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001815 }
1816 SkASSERT(false);
Mike Reedc1f77742016-12-09 09:00:50 -05001817 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001818}
1819
Brian Osmanc25e2692018-03-12 10:57:28 -04001820SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001821 fColor = color;
ethannicholas1446a9a2016-02-10 14:05:02 -08001822}
1823
1824void SkClearCommand::execute(SkCanvas* canvas) const {
1825 canvas->clear(fColor);
1826}
1827
ethannicholasf62a8b72016-02-11 10:35:21 -08001828Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1829 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001830 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001831 return result;
1832}
1833
ethannicholasf62a8b72016-02-11 10:35:21 -08001834 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001835 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1836 return new SkClearCommand(get_json_color(color));
1837}
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001838
Mike Reedc1f77742016-12-09 09:00:50 -05001839SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001840 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001841 fPath = path;
1842 fOp = op;
1843 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001844}
1845
fmalita8c89c522014-11-08 16:18:56 -08001846void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001847 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001848}
1849
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001850bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001851 render_path(canvas, fPath);
1852 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001853}
1854
ethannicholasf62a8b72016-02-11 10:35:21 -08001855Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1856 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001857 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001858 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1859 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1860 return result;
1861}
1862
halcanary9d524f22016-03-29 09:03:52 -07001863SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001864 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001865 SkPath path;
1866 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
reed73603f32016-09-20 08:42:38 -07001867 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001868 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1869}
1870
Mike Reedc1f77742016-12-09 09:00:50 -05001871SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001872 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001873 fRegion = region;
1874 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001875}
1876
fmalita8c89c522014-11-08 16:18:56 -08001877void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001878 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001879}
1880
ethannicholasf62a8b72016-02-11 10:35:21 -08001881Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1882 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001883 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001884 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1885 return result;
1886}
1887
halcanary9d524f22016-03-29 09:03:52 -07001888SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001889 UrlDataManager& urlDataManager) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001890 SkRegion region;
1891 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
1892 return new SkClipRegionCommand(region,
1893 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001894}
1895
Mike Reedc1f77742016-12-09 09:00:50 -05001896SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001897 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001898 fRect = rect;
1899 fOp = op;
1900 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001901}
1902
fmalita8c89c522014-11-08 16:18:56 -08001903void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001904 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001905}
1906
ethannicholasf62a8b72016-02-11 10:35:21 -08001907Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1908 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001909 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001910 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1911 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001912
1913 SkString desc;
1914 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1915
ethannicholas50a8dd02016-02-10 05:40:46 -08001916 return result;
1917}
1918
halcanary9d524f22016-03-29 09:03:52 -07001919SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001920 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001921 SkRect rect;
1922 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
reed73603f32016-09-20 08:42:38 -07001923 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001924 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1925}
1926
Mike Reedc1f77742016-12-09 09:00:50 -05001927SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001928 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001929 fRRect = rrect;
1930 fOp = op;
1931 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001932}
1933
fmalita8c89c522014-11-08 16:18:56 -08001934void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001935 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001936}
1937
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001938bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001939 render_rrect(canvas, fRRect);
1940 return true;
1941}
1942
ethannicholasf62a8b72016-02-11 10:35:21 -08001943Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1944 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001945 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1946 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1947 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1948 return result;
1949}
1950
halcanary9d524f22016-03-29 09:03:52 -07001951SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001952 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001953 SkRRect rrect;
1954 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
halcanary9d524f22016-03-29 09:03:52 -07001955 return new SkClipRRectCommand(rrect,
reed73603f32016-09-20 08:42:38 -07001956 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001957 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1958}
1959
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001960SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001961 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001962 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001963}
1964
fmalita8c89c522014-11-08 16:18:56 -08001965void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001966 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001967}
1968
ethannicholasf62a8b72016-02-11 10:35:21 -08001969Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1970 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001971 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001972 return result;
1973}
1974
ethannicholasf62a8b72016-02-11 10:35:21 -08001975SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001976 SkMatrix matrix;
1977 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1978 return new SkConcatCommand(matrix);
1979}
1980
reed97660cc2016-06-28 18:54:19 -07001981////
1982
1983SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1984 sk_sp<SkData> value)
1985 : INHERITED(kDrawAnnotation_OpType)
1986 , fRect(rect)
1987 , fKey(key)
1988 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07001989{
robertphillipsfb409232016-06-29 10:28:11 -07001990}
reed97660cc2016-06-28 18:54:19 -07001991
1992void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1993 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1994}
1995
1996Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1997 Json::Value result = INHERITED::toJSON(urlDataManager);
1998
1999 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
2000 result["key"] = Json::Value(fKey.c_str());
2001 if (fValue.get()) {
2002 // TODO: dump out the "value"
2003 }
reed67f62fa2016-06-29 11:36:34 -07002004
2005 SkString desc;
2006 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
2007 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
2008
reed97660cc2016-06-28 18:54:19 -07002009 return result;
2010}
2011
2012SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
2013 UrlDataManager& urlDataManager) {
2014 SkRect rect;
2015 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
2016 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
2017 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
2018}
2019
2020////
2021
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002022SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07002023 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002024 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002025 fBitmap = bitmap;
2026 fLeft = left;
2027 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07002028 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002029 fPaint = *paint;
2030 fPaintPtr = &fPaint;
2031 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002032 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002033 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002034}
2035
fmalita8c89c522014-11-08 16:18:56 -08002036void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002037 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002038}
2039
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002040bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002041 render_bitmap(canvas, fBitmap);
2042 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002043}
2044
ethannicholasf62a8b72016-02-11 10:35:21 -08002045Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
2046 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002047 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002048 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002049 Json::Value command(Json::objectValue);
2050 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002051 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002052 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002053 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002054 }
2055 }
2056 return result;
2057}
2058
halcanary9d524f22016-03-29 09:03:52 -07002059SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002060 UrlDataManager& urlDataManager) {
2061 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002062 if (bitmap == nullptr) {
2063 return nullptr;
2064 }
2065 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2066 SkPaint* paintPtr;
2067 SkPaint paint;
2068 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002069 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002070 paintPtr = &paint;
2071 }
2072 else {
2073 paintPtr = nullptr;
2074 }
halcanary9d524f22016-03-29 09:03:52 -07002075 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002076 point[1].asFloat(), paintPtr);
2077 delete bitmap;
2078 return result;
2079}
2080
Brian Osman78a76482018-05-18 16:59:13 -04002081SkDrawBitmapLatticeCommand::SkDrawBitmapLatticeCommand(const SkBitmap& bitmap,
2082 const SkCanvas::Lattice& lattice,
2083 const SkRect& dst, const SkPaint* paint)
2084 : INHERITED(kDrawBitmapLattice_OpType)
2085 , fBitmap(bitmap)
2086 , fLattice(lattice)
2087 , fDst(dst) {
2088
2089 if (paint) {
2090 fPaint.set(*paint);
2091 }
2092}
2093
2094void SkDrawBitmapLatticeCommand::execute(SkCanvas* canvas) const {
2095 canvas->drawBitmapLattice(fBitmap, fLattice, fDst, fPaint.getMaybeNull());
2096}
2097
2098bool SkDrawBitmapLatticeCommand::render(SkCanvas* canvas) const {
2099 SkAutoCanvasRestore acr(canvas, true);
2100 canvas->clear(0xFFFFFFFF);
2101
2102 xlate_and_scale_to_bounds(canvas, fDst);
2103
2104 this->execute(canvas);
2105 return true;
2106}
2107
2108Json::Value SkDrawBitmapLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2109 Json::Value result = INHERITED::toJSON(urlDataManager);
2110 Json::Value encoded;
2111 if (flatten(fBitmap, &encoded, urlDataManager)) {
2112 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2113 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2114 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2115 if (fPaint.isValid()) {
2116 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2117 }
2118 }
2119
2120 SkString desc;
2121 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2122
2123 return result;
2124}
2125
2126SkDrawBitmapLatticeCommand* SkDrawBitmapLatticeCommand::fromJSON(Json::Value& command,
2127 UrlDataManager& urlDataManager) {
2128 SkDEBUGFAIL("Not implemented yet.");
2129 return nullptr;
2130}
2131
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002132SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00002133 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002134 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002135 fBitmap = bitmap;
2136 fCenter = center;
2137 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07002138 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002139 fPaint = *paint;
2140 fPaintPtr = &fPaint;
2141 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002142 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002143 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002144}
2145
fmalita8c89c522014-11-08 16:18:56 -08002146void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002147 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002148}
2149
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002150bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08002151 SkRect tmp = SkRect::Make(fCenter);
2152 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002153 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002154}
2155
ethannicholasf62a8b72016-02-11 10:35:21 -08002156Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2157 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002158 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002159 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002160 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08002161 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07002162 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002163 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002164 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002165 }
2166 }
2167 return result;
2168}
2169
halcanary9d524f22016-03-29 09:03:52 -07002170SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002171 UrlDataManager& urlDataManager) {
2172 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002173 if (bitmap == nullptr) {
2174 return nullptr;
2175 }
2176 SkIRect center;
2177 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2178 SkRect dst;
2179 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2180 SkPaint* paintPtr;
2181 SkPaint paint;
2182 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002183 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002184 paintPtr = &paint;
2185 }
2186 else {
2187 paintPtr = nullptr;
2188 }
2189 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2190 delete bitmap;
2191 return result;
2192}
2193
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002194SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002195 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002196 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08002197 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002198 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07002199 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002200 fSrc = *src;
2201 } else {
2202 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002203 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00002204 fDst = dst;
2205
bsalomon49f085d2014-09-05 13:34:00 -07002206 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002207 fPaint = *paint;
2208 fPaintPtr = &fPaint;
2209 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002210 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00002211 }
reeda5517e22015-07-14 10:54:12 -07002212 fConstraint = constraint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002213}
2214
fmalita8c89c522014-11-08 16:18:56 -08002215void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07002216 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002217}
2218
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002219bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002220 render_bitmap(canvas, fBitmap, this->srcRect());
2221 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002222}
2223
ethannicholasf62a8b72016-02-11 10:35:21 -08002224Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2225 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002226 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002227 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002228 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2229 if (!fSrc.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07002230 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
ethannicholas50a8dd02016-02-10 05:40:46 -08002231 }
brianosmanfad98562016-05-04 11:06:28 -07002232 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002233 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002234 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002235 }
2236 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2237 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2238 }
2239 }
reed67f62fa2016-06-29 11:36:34 -07002240
2241 SkString desc;
2242 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2243
ethannicholas50a8dd02016-02-10 05:40:46 -08002244 return result;
2245}
2246
halcanary9d524f22016-03-29 09:03:52 -07002247SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002248 UrlDataManager& urlDataManager) {
2249 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002250 if (bitmap == nullptr) {
2251 return nullptr;
2252 }
2253 SkRect dst;
2254 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2255 SkPaint* paintPtr;
2256 SkPaint paint;
2257 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002258 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002259 paintPtr = &paint;
2260 }
2261 else {
2262 paintPtr = nullptr;
2263 }
2264 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002265 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002266 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2267 constraint = SkCanvas::kStrict_SrcRectConstraint;
2268 }
2269 else {
2270 constraint = SkCanvas::kFast_SrcRectConstraint;
2271 }
2272 SkRect* srcPtr;
2273 SkRect src;
2274 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2275 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2276 srcPtr = &src;
2277 }
2278 else {
2279 srcPtr = nullptr;
2280 }
2281 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2282 constraint);
2283 delete bitmap;
2284 return result;
2285}
2286
fmalita651c9202015-07-22 10:23:01 -07002287SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2288 const SkPaint* paint)
2289 : INHERITED(kDrawImage_OpType)
2290 , fImage(SkRef(image))
2291 , fLeft(left)
2292 , fTop(top) {
2293
2294 if (paint) {
2295 fPaint.set(*paint);
2296 }
2297}
2298
2299void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002300 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07002301}
2302
2303bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2304 SkAutoCanvasRestore acr(canvas, true);
2305 canvas->clear(0xFFFFFFFF);
2306
2307 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2308 SkIntToScalar(fImage->width()),
2309 SkIntToScalar(fImage->height())));
2310 this->execute(canvas);
2311 return true;
2312}
2313
ethannicholasf62a8b72016-02-11 10:35:21 -08002314Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2315 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002316 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002317 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002318 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002319 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002320 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002321 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002322 }
msarett0ac1bec2016-08-29 09:15:33 -07002323
2324 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2325 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2326 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2327 switch (fImage->alphaType()) {
2328 case kOpaque_SkAlphaType:
2329 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2330 break;
2331 case kPremul_SkAlphaType:
2332 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2333 break;
2334 case kUnpremul_SkAlphaType:
2335 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2336 break;
2337 default:
2338 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2339 break;
2340 }
ethannicholas50a8dd02016-02-10 05:40:46 -08002341 }
2342 return result;
2343}
2344
halcanary9d524f22016-03-29 09:03:52 -07002345SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002346 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002347 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002348 if (image == nullptr) {
2349 return nullptr;
2350 }
2351 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2352 SkPaint* paintPtr;
2353 SkPaint paint;
2354 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002355 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002356 paintPtr = &paint;
2357 }
2358 else {
2359 paintPtr = nullptr;
2360 }
reed9ce9d672016-03-17 10:51:11 -07002361 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002362 point[1].asFloat(), paintPtr);
ethannicholas50a8dd02016-02-10 05:40:46 -08002363 return result;
2364}
2365
Stan Ilievac42aeb2017-01-12 16:20:50 -05002366SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2367 const SkCanvas::Lattice& lattice,
2368 const SkRect& dst, const SkPaint* paint)
2369 : INHERITED(kDrawImageLattice_OpType)
2370 , fImage(SkRef(image))
2371 , fLattice(lattice)
2372 , fDst(dst) {
2373
Stan Ilievac42aeb2017-01-12 16:20:50 -05002374 if (paint) {
2375 fPaint.set(*paint);
Stan Ilievac42aeb2017-01-12 16:20:50 -05002376 }
2377}
2378
2379void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
Brian Osman78a76482018-05-18 16:59:13 -04002380 canvas->drawImageLattice(fImage.get(), fLattice, fDst, fPaint.getMaybeNull());
Stan Ilievac42aeb2017-01-12 16:20:50 -05002381}
2382
2383bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2384 SkAutoCanvasRestore acr(canvas, true);
2385 canvas->clear(0xFFFFFFFF);
2386
2387 xlate_and_scale_to_bounds(canvas, fDst);
2388
2389 this->execute(canvas);
2390 return true;
2391}
2392
2393Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2394 Json::Value result = INHERITED::toJSON(urlDataManager);
2395 Json::Value encoded;
2396 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002397 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
Stan Ilievac42aeb2017-01-12 16:20:50 -05002398 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2399 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2400 if (fPaint.isValid()) {
2401 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2402 }
2403 }
2404
2405 SkString desc;
2406 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2407
2408 return result;
2409}
2410
Brian Osmanc25e2692018-03-12 10:57:28 -04002411SkDrawImageLatticeCommand* SkDrawImageLatticeCommand::fromJSON(Json::Value& command,
2412 UrlDataManager& urlDataManager) {
2413 SkDEBUGFAIL("Not implemented yet.");
2414 return nullptr;
2415}
2416
fmalita651c9202015-07-22 10:23:01 -07002417SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2418 const SkRect& dst, const SkPaint* paint,
2419 SkCanvas::SrcRectConstraint constraint)
2420 : INHERITED(kDrawImageRect_OpType)
2421 , fImage(SkRef(image))
2422 , fDst(dst)
2423 , fConstraint(constraint) {
2424
2425 if (src) {
2426 fSrc.set(*src);
2427 }
2428
2429 if (paint) {
2430 fPaint.set(*paint);
2431 }
2432}
2433
2434void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002435 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2436 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07002437}
2438
2439bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2440 SkAutoCanvasRestore acr(canvas, true);
2441 canvas->clear(0xFFFFFFFF);
2442
2443 xlate_and_scale_to_bounds(canvas, fDst);
2444
2445 this->execute(canvas);
2446 return true;
2447}
2448
ethannicholasf62a8b72016-02-11 10:35:21 -08002449Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2450 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002451 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002452 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002453 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
ethannicholas50a8dd02016-02-10 05:40:46 -08002454 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002455 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002456 }
brianosmanfad98562016-05-04 11:06:28 -07002457 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002458 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002459 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002460 }
2461 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2462 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2463 }
2464 }
reed67f62fa2016-06-29 11:36:34 -07002465
2466 SkString desc;
2467 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2468
ethannicholas50a8dd02016-02-10 05:40:46 -08002469 return result;
2470}
2471
halcanary9d524f22016-03-29 09:03:52 -07002472SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002473 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002474 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002475 if (image == nullptr) {
2476 return nullptr;
2477 }
2478 SkRect dst;
2479 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2480 SkPaint* paintPtr;
2481 SkPaint paint;
2482 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002483 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002484 paintPtr = &paint;
2485 }
2486 else {
2487 paintPtr = nullptr;
2488 }
2489 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002490 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002491 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2492 constraint = SkCanvas::kStrict_SrcRectConstraint;
2493 }
2494 else {
2495 constraint = SkCanvas::kFast_SrcRectConstraint;
2496 }
2497 SkRect* srcPtr;
2498 SkRect src;
2499 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2500 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2501 srcPtr = &src;
2502 }
2503 else {
2504 srcPtr = nullptr;
2505 }
reed9ce9d672016-03-17 10:51:11 -07002506 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
ethannicholas50a8dd02016-02-10 05:40:46 -08002507 constraint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002508 return result;
2509}
2510
Brian Osmanc25e2692018-03-12 10:57:28 -04002511SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
2512 const SkRect& dst, const SkPaint* paint)
2513 : INHERITED(kDrawImageNine_OpType)
2514 , fImage(SkRef(image))
2515 , fCenter(center)
2516 , fDst(dst) {
2517 if (paint) {
2518 fPaint = *paint;
2519 fPaintPtr = &fPaint;
2520 } else {
2521 fPaintPtr = nullptr;
2522 }
Brian Osmanc25e2692018-03-12 10:57:28 -04002523}
2524
2525void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
2526 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaintPtr);
2527}
2528
2529bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
2530 SkAutoCanvasRestore acr(canvas, true);
2531 canvas->clear(0xFFFFFFFF);
2532
2533 xlate_and_scale_to_bounds(canvas, fDst);
2534
2535 this->execute(canvas);
2536 return true;
2537}
2538
2539Json::Value SkDrawImageNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2540 Json::Value result = INHERITED::toJSON(urlDataManager);
2541 Json::Value encoded;
2542 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2543 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
2544 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
2545 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2546 if (fPaintPtr != nullptr) {
2547 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2548 }
2549 }
2550 return result;
2551}
2552
2553SkDrawImageNineCommand* SkDrawImageNineCommand::fromJSON(Json::Value& command,
2554 UrlDataManager& urlDataManager) {
2555 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2556 if (image == nullptr) {
2557 return nullptr;
2558 }
2559 SkIRect center;
2560 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2561 SkRect dst;
2562 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2563 SkPaint* paintPtr;
2564 SkPaint paint;
2565 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2566 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2567 paintPtr = &paint;
2568 } else {
2569 paintPtr = nullptr;
2570 }
2571 SkDrawImageNineCommand* result = new SkDrawImageNineCommand(image.get(), center, dst, paintPtr);
2572 return result;
2573}
2574
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002575SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002576 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002577 fOval = oval;
2578 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002579}
2580
fmalita8c89c522014-11-08 16:18:56 -08002581void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002582 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002583}
2584
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002585bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002586 canvas->clear(0xFFFFFFFF);
2587 canvas->save();
2588
2589 xlate_and_scale_to_bounds(canvas, fOval);
2590
2591 SkPaint p;
2592 p.setColor(SK_ColorBLACK);
2593 p.setStyle(SkPaint::kStroke_Style);
2594
2595 canvas->drawOval(fOval, p);
2596 canvas->restore();
2597
2598 return true;
2599}
2600
ethannicholasf62a8b72016-02-11 10:35:21 -08002601Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2602 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002603 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2604 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002605 return result;
2606}
2607
halcanary9d524f22016-03-29 09:03:52 -07002608SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002609 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002610 SkRect coords;
2611 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2612 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002613 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002614 return new SkDrawOvalCommand(coords, paint);
2615}
2616
bsalomonac3aa242016-08-19 11:25:19 -07002617SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2618 bool useCenter, const SkPaint& paint)
Brian Osmanc25e2692018-03-12 10:57:28 -04002619 : INHERITED(kDrawArc_OpType) {
bsalomonac3aa242016-08-19 11:25:19 -07002620 fOval = oval;
2621 fStartAngle = startAngle;
2622 fSweepAngle = sweepAngle;
2623 fUseCenter = useCenter;
2624 fPaint = paint;
bsalomonac3aa242016-08-19 11:25:19 -07002625}
2626
2627void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2628 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2629}
2630
2631bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2632 canvas->clear(0xFFFFFFFF);
2633 canvas->save();
2634
2635 xlate_and_scale_to_bounds(canvas, fOval);
2636
2637 SkPaint p;
2638 p.setColor(SK_ColorBLACK);
2639 p.setStyle(SkPaint::kStroke_Style);
2640
2641 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2642 canvas->restore();
2643
2644 return true;
2645}
2646
2647Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2648 Json::Value result = INHERITED::toJSON(urlDataManager);
2649 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2650 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2651 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2652 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2653 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2654 return result;
2655}
2656
2657SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2658 UrlDataManager& urlDataManager) {
2659 SkRect coords;
2660 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2661 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2662 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2663 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2664 SkPaint paint;
2665 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2666 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2667}
2668
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002669SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002670 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002671 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002672}
2673
fmalita8c89c522014-11-08 16:18:56 -08002674void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002675 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002676}
2677
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002678bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002679 canvas->clear(0xFFFFFFFF);
2680 canvas->drawPaint(fPaint);
2681 return true;
2682}
2683
ethannicholasf62a8b72016-02-11 10:35:21 -08002684Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2685 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002686 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002687 return result;
2688}
2689
halcanary9d524f22016-03-29 09:03:52 -07002690SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002691 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002692 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002693 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002694 return new SkDrawPaintCommand(paint);
2695}
2696
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002697SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002698 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002699 fPath = path;
2700 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002701}
2702
fmalita8c89c522014-11-08 16:18:56 -08002703void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002704 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002705}
2706
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002707bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002708 render_path(canvas, fPath);
2709 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002710}
2711
ethannicholasf62a8b72016-02-11 10:35:21 -08002712Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2713 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002714 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2715 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002716 return result;
2717}
2718
halcanary9d524f22016-03-29 09:03:52 -07002719SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002720 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002721 SkPath path;
2722 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2723 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002724 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002725 return new SkDrawPathCommand(path, paint);
2726}
2727
Brian Osmanc25e2692018-03-12 10:57:28 -04002728SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
2729 : INHERITED(kDrawRegion_OpType) {
2730 fRegion = region;
2731 fPaint = paint;
Brian Osmanc25e2692018-03-12 10:57:28 -04002732}
2733
2734void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
2735 canvas->drawRegion(fRegion, fPaint);
2736}
2737
2738bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
2739 render_region(canvas, fRegion);
2740 return true;
2741}
2742
2743Json::Value SkDrawRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
2744 Json::Value result = INHERITED::toJSON(urlDataManager);
2745 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
2746 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2747 return result;
2748}
2749
2750SkDrawRegionCommand* SkDrawRegionCommand::fromJSON(Json::Value& command,
2751 UrlDataManager& urlDataManager) {
2752 SkRegion region;
2753 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
2754 SkPaint paint;
2755 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2756 return new SkDrawRegionCommand(region, paint);
2757}
2758
fmalita160ebb22015-04-01 20:58:37 -07002759SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2760 const SkMatrix* matrix,
2761 const SkPaint* paint)
2762 : INHERITED(kBeginDrawPicture_OpType)
2763 , fPicture(SkRef(picture)) {
bsalomon49f085d2014-09-05 13:34:00 -07002764 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002765 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002766 }
fmalita160ebb22015-04-01 20:58:37 -07002767
bsalomon49f085d2014-09-05 13:34:00 -07002768 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002769 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002770 }
fmalita160ebb22015-04-01 20:58:37 -07002771}
2772
2773void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2774 if (fPaint.isValid()) {
2775 SkRect bounds = fPicture->cullRect();
2776 if (fMatrix.isValid()) {
2777 fMatrix.get()->mapRect(&bounds);
2778 }
2779 canvas->saveLayer(&bounds, fPaint.get());
2780 }
2781
2782 if (fMatrix.isValid()) {
2783 if (!fPaint.isValid()) {
2784 canvas->save();
2785 }
2786 canvas->concat(*fMatrix.get());
2787 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002788}
2789
fmalita160ebb22015-04-01 20:58:37 -07002790bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002791 canvas->clear(0xFFFFFFFF);
2792 canvas->save();
2793
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002794 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002795
robertphillips9b14f262014-06-04 05:40:44 -07002796 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002797
2798 canvas->restore();
2799
2800 return true;
2801}
2802
fmalita160ebb22015-04-01 20:58:37 -07002803SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2804 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2805
2806void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2807 if (fRestore) {
2808 canvas->restore();
2809 }
2810}
2811
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002812SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002813 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002814 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002815 fMode = mode;
2816 fCount = count;
2817 fPts = new SkPoint[count];
2818 memcpy(fPts, pts, count * sizeof(SkPoint));
2819 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002820}
2821
fmalita8c89c522014-11-08 16:18:56 -08002822void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002823 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002824}
2825
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002826bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002827 canvas->clear(0xFFFFFFFF);
2828 canvas->save();
2829
2830 SkRect bounds;
2831
2832 bounds.setEmpty();
2833 for (unsigned int i = 0; i < fCount; ++i) {
Mike Reed185ffe92018-01-08 17:09:54 -05002834 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002835 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002836
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002837 xlate_and_scale_to_bounds(canvas, bounds);
2838
2839 SkPaint p;
2840 p.setColor(SK_ColorBLACK);
2841 p.setStyle(SkPaint::kStroke_Style);
2842
2843 canvas->drawPoints(fMode, fCount, fPts, p);
2844 canvas->restore();
2845
2846 return true;
2847}
2848
ethannicholasf62a8b72016-02-11 10:35:21 -08002849Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2850 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002851 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2852 Json::Value points(Json::arrayValue);
2853 for (size_t i = 0; i < fCount; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002854 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002855 }
2856 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07002857 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002858 return result;
2859}
2860
halcanary9d524f22016-03-29 09:03:52 -07002861SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002862 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002863 SkCanvas::PointMode mode;
2864 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2865 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2866 mode = SkCanvas::kPoints_PointMode;
2867 }
2868 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2869 mode = SkCanvas::kLines_PointMode;
2870 }
2871 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2872 mode = SkCanvas::kPolygon_PointMode;
2873 }
2874 else {
2875 SkASSERT(false);
2876 return nullptr;
2877 }
2878 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2879 int count = (int) jsonPoints.size();
2880 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2881 for (int i = 0; i < count; i++) {
2882 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2883 }
2884 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002885 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002886 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2887 sk_free(points);
2888 return result;
2889}
2890
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002891SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002892 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002893 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002894 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002895
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002896 fText = new char[byteLength];
2897 memcpy(fText, text, byteLength);
2898 fByteLength = byteLength;
2899
2900 fPos = new SkPoint[numPts];
2901 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2902
2903 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002904}
2905
fmalita8c89c522014-11-08 16:18:56 -08002906void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002907 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002908}
2909
ethannicholasf62a8b72016-02-11 10:35:21 -08002910Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2911 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002912 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002913 ((const char*) fText) + fByteLength);
2914 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08002915 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2916 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002917 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002918 }
2919 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07002920 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002921 return result;
2922}
2923
halcanary9d524f22016-03-29 09:03:52 -07002924SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002925 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002926 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2927 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002928 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002929 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2930 int count = (int) coords.size();
2931 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2932 for (int i = 0; i < count; i++) {
2933 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2934 }
2935 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2936}
chudy@google.com902ebe52012-06-29 14:21:22 +00002937
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002938SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2939 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002940 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002941 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002942 size_t numPts = paint.countText(text, byteLength);
2943
2944 fText = new char[byteLength];
2945 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002946 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002947
2948 fXpos = new SkScalar[numPts];
2949 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2950
robertphillips@google.com91217d02013-03-17 18:33:46 +00002951 fConstY = constY;
2952 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002953}
2954
fmalita8c89c522014-11-08 16:18:56 -08002955void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002956 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002957}
2958
bungeman51190df2016-03-09 07:42:54 -08002959Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
2960 Json::Value result = INHERITED::toJSON(urlDataManager);
2961 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2962 ((const char*) fText) + fByteLength);
2963 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
2964 Json::Value xpos(Json::arrayValue);
2965 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2966 for (size_t i = 0; i < numXpos; i++) {
2967 xpos.append(Json::Value(fXpos[i]));
2968 }
2969 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07002970 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08002971 return result;
2972}
2973
2974SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
2975 UrlDataManager& urlDataManager) {
2976 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2977 SkPaint paint;
2978 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2979 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2980 int count = (int) jsonXpos.size();
2981 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
2982 for (int i = 0; i < count; i++) {
2983 xpos[i] = jsonXpos[i].asFloat();
2984 }
2985 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2986 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
2987}
2988
fmalita37283c22016-09-13 10:00:23 -07002989SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07002990 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002991 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07002992 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07002993 , fXPos(x)
2994 , fYPos(y)
Brian Osman255735e2018-04-06 14:51:42 -04002995 , fPaint(paint) {}
fmalitab7425172014-08-26 07:56:44 -07002996
fmalita8c89c522014-11-08 16:18:56 -08002997void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07002998 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2999}
3000
fmalita55773872014-08-29 15:08:20 -07003001bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
3002 canvas->clear(SK_ColorWHITE);
3003 canvas->save();
3004
3005 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
3006 xlate_and_scale_to_bounds(canvas, bounds);
3007
fmalita37283c22016-09-13 10:00:23 -07003008 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07003009
3010 canvas->restore();
3011
3012 return true;
3013}
3014
ethannicholasf62a8b72016-02-11 10:35:21 -08003015Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
3016 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003017 Json::Value runs(Json::arrayValue);
3018 SkTextBlobRunIterator iter(fBlob.get());
3019 while (!iter.done()) {
3020 Json::Value run(Json::objectValue);
3021 Json::Value jsonPositions(Json::arrayValue);
3022 Json::Value jsonGlyphs(Json::arrayValue);
3023 const SkScalar* iterPositions = iter.pos();
3024 const uint16_t* iterGlyphs = iter.glyphs();
3025 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
3026 switch (iter.positioning()) {
3027 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07003028 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
3029 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08003030 break;
3031 case SkTextBlob::kHorizontal_Positioning:
3032 jsonPositions.append(Json::Value(iterPositions[i]));
3033 break;
3034 case SkTextBlob::kDefault_Positioning:
3035 break;
3036 }
3037 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
3038 }
3039 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
3040 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
3041 }
3042 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
3043 SkPaint fontPaint;
3044 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07003045 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
3046 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08003047 runs.append(run);
3048 iter.next();
3049 }
reed6d2c3e72016-07-07 14:10:14 -07003050 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08003051 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
3052 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
3053 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07003054 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07003055 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07003056
3057 SkString desc;
3058 // make the bounds local by applying the x,y
3059 bounds.offset(fXPos, fYPos);
3060 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
3061
ethannicholas50a8dd02016-02-10 05:40:46 -08003062 return result;
3063}
3064
halcanary9d524f22016-03-29 09:03:52 -07003065SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003066 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003067 SkTextBlobBuilder builder;
3068 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
3069 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
3070 Json::Value run = runs[i];
3071 SkPaint font;
3072 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
ethannicholasf62a8b72016-02-11 10:35:21 -08003073 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
ethannicholas50a8dd02016-02-10 05:40:46 -08003074 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
3075 int count = glyphs.size();
3076 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3077 SkScalar x = coords[0].asFloat();
3078 SkScalar y = coords[1].asFloat();
reed6d2c3e72016-07-07 14:10:14 -07003079 SkRect bounds;
3080 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
3081
ethannicholas50a8dd02016-02-10 05:40:46 -08003082 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
3083 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3084 if (positions.size() > 0 && positions[0].isNumeric()) {
reed6d2c3e72016-07-07 14:10:14 -07003085 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003086 for (int j = 0; j < count; j++) {
3087 buffer.glyphs[j] = glyphs[j].asUInt();
3088 buffer.pos[j] = positions[j].asFloat();
3089 }
3090 }
3091 else {
reed6d2c3e72016-07-07 14:10:14 -07003092 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003093 for (int j = 0; j < count; j++) {
3094 buffer.glyphs[j] = glyphs[j].asUInt();
3095 buffer.pos[j * 2] = positions[j][0].asFloat();
3096 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
3097 }
3098 }
3099 }
3100 else {
reed6d2c3e72016-07-07 14:10:14 -07003101 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003102 for (int j = 0; j < count; j++) {
3103 buffer.glyphs[j] = glyphs[j].asUInt();
3104 }
3105 }
3106 }
3107 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
3108 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3109 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003110 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
fmalita37283c22016-09-13 10:00:23 -07003111 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003112}
3113
robertphillips9bafc302015-02-13 11:13:00 -08003114SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04003115 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08003116 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003117 : INHERITED(kDrawPatch_OpType)
3118 , fBlendMode(bmode)
3119{
robertphillips9bafc302015-02-13 11:13:00 -08003120 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08003121 if (colors != nullptr) {
3122 memcpy(fColors, colors, sizeof(fColors));
3123 fColorsPtr = fColors;
3124 } else {
3125 fColorsPtr = nullptr;
3126 }
3127 if (texCoords != nullptr) {
3128 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3129 fTexCoordsPtr = fTexCoords;
3130 } else {
3131 fTexCoordsPtr = nullptr;
3132 }
robertphillips9bafc302015-02-13 11:13:00 -08003133 fPaint = paint;
robertphillips9bafc302015-02-13 11:13:00 -08003134}
3135
3136void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04003137 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08003138}
3139
ethannicholasf62a8b72016-02-11 10:35:21 -08003140Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3141 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08003142 Json::Value cubics = Json::Value(Json::arrayValue);
3143 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003144 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003145 }
3146 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3147 if (fColorsPtr != nullptr) {
3148 Json::Value colors = Json::Value(Json::arrayValue);
3149 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003150 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003151 }
3152 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3153 }
3154 if (fTexCoordsPtr != nullptr) {
3155 Json::Value texCoords = Json::Value(Json::arrayValue);
3156 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003157 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003158 }
3159 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3160 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003161 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08003162 return result;
3163}
3164
halcanary9d524f22016-03-29 09:03:52 -07003165SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003166 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08003167 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3168 SkPoint cubics[12];
3169 for (int i = 0; i < 12; i++) {
3170 cubics[i] = get_json_point(jsonCubics[i]);
3171 }
3172 SkColor* colorsPtr;
3173 SkColor colors[4];
3174 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3175 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3176 for (int i = 0; i < 4; i++) {
3177 colors[i] = get_json_color(jsonColors[i]);
3178 }
3179 colorsPtr = colors;
3180 }
3181 else {
3182 colorsPtr = nullptr;
3183 }
3184 SkPoint* texCoordsPtr;
3185 SkPoint texCoords[4];
3186 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3187 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3188 for (int i = 0; i < 4; i++) {
3189 texCoords[i] = get_json_point(jsonTexCoords[i]);
3190 }
3191 texCoordsPtr = texCoords;
3192 }
3193 else {
3194 texCoordsPtr = nullptr;
3195 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003196
3197 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3198
ethannicholas1446a9a2016-02-10 14:05:02 -08003199 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003200 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04003201 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
robertphillips9bafc302015-02-13 11:13:00 -08003202}
3203
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003204SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003205 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003206 fRect = rect;
3207 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003208}
3209
fmalita8c89c522014-11-08 16:18:56 -08003210void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003211 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003212}
3213
ethannicholasf62a8b72016-02-11 10:35:21 -08003214Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3215 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07003216 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3217 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07003218
3219 SkString desc;
3220 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3221
ethannicholas50a8dd02016-02-10 05:40:46 -08003222 return result;
3223}
3224
halcanary9d524f22016-03-29 09:03:52 -07003225SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003226 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003227 SkRect coords;
3228 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3229 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003230 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003231 return new SkDrawRectCommand(coords, paint);
3232}
3233
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003234SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003235 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003236 fRRect = rrect;
3237 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00003238}
3239
fmalita8c89c522014-11-08 16:18:56 -08003240void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00003241 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00003242}
3243
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003244bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00003245 render_rrect(canvas, fRRect);
3246 return true;
3247}
3248
ethannicholasf62a8b72016-02-11 10:35:21 -08003249Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3250 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003251 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07003252 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003253 return result;
3254}
3255
halcanary9d524f22016-03-29 09:03:52 -07003256SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003257 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003258 SkRRect coords;
3259 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3260 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003261 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003262 return new SkDrawRRectCommand(coords, paint);
3263}
3264
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00003265SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003266 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003267 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003268 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003269 fOuter = outer;
3270 fInner = inner;
3271 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003272}
3273
fmalita8c89c522014-11-08 16:18:56 -08003274void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003275 canvas->drawDRRect(fOuter, fInner, fPaint);
3276}
3277
3278bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3279 render_drrect(canvas, fOuter, fInner);
3280 return true;
3281}
3282
ethannicholasf62a8b72016-02-11 10:35:21 -08003283Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3284 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003285 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3286 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07003287 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003288 return result;
3289}
3290
halcanary9d524f22016-03-29 09:03:52 -07003291SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003292 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003293 SkRRect outer;
3294 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3295 SkRRect inner;
3296 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3297 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003298 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003299 return new SkDrawDRRectCommand(outer, inner, paint);
3300}
3301
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04003302SkDrawShadowCommand::SkDrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
3303 : INHERITED(kDrawShadow_OpType) {
3304 fPath = path;
3305 fShadowRec = rec;
3306}
3307
3308void SkDrawShadowCommand::execute(SkCanvas* canvas) const {
3309 canvas->private_draw_shadow_rec(fPath, fShadowRec);
3310}
3311
3312bool SkDrawShadowCommand::render(SkCanvas* canvas) const {
3313 render_shadow(canvas, fPath, fShadowRec);
3314 return true;
3315}
3316
3317Json::Value SkDrawShadowCommand::toJSON(UrlDataManager& urlDataManager) const {
3318 Json::Value result = INHERITED::toJSON(urlDataManager);
3319 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3320
3321 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
3322 bool transparentOccluder =
3323 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
3324
3325 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3326 result[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE] = MakeJsonPoint3(fShadowRec.fZPlaneParams);
3327 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION] = MakeJsonPoint3(fShadowRec.fLightPos);
3328 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS] = MakeJsonScalar(fShadowRec.fLightRadius);
3329 result[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR] = MakeJsonColor(fShadowRec.fAmbientColor);
3330 result[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR] = MakeJsonColor(fShadowRec.fSpotColor);
3331 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
3332 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
3333 return result;
3334}
3335
3336SkDrawShadowCommand* SkDrawShadowCommand::fromJSON(Json::Value& command,
3337 UrlDataManager& urlDataManager) {
3338 SkPath path;
3339 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3340 SkDrawShadowRec rec;
3341 rec.fZPlaneParams = get_json_point3(command[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE]);
3342 rec.fLightPos = get_json_point3(command[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION]);
3343 rec.fLightRadius = command[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS].asFloat();
3344 rec.fAmbientColor = get_json_color(command[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR]);
3345 rec.fSpotColor = get_json_color(command[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR]);
3346
3347 rec.fFlags = SkShadowFlags::kNone_ShadowFlag;
3348 if (command.isMember(SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC)
3349 && command[SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC].asBool()) {
3350 rec.fFlags |= SkShadowFlags::kTransparentOccluder_ShadowFlag;
3351 }
3352 if (command.isMember(SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY)
3353 && command[SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY].asBool()) {
3354 rec.fFlags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
3355 }
3356 return new SkDrawShadowCommand(path, rec);
3357}
3358
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003359SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003360 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003361 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003362 fText = new char[byteLength];
3363 memcpy(fText, text, byteLength);
3364 fByteLength = byteLength;
3365 fX = x;
3366 fY = y;
3367 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003368}
3369
fmalita8c89c522014-11-08 16:18:56 -08003370void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003371 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003372}
3373
ethannicholasf62a8b72016-02-11 10:35:21 -08003374Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3375 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003376 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003377 ((const char*) fText) + fByteLength);
3378 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003379 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3380 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003381 return result;
3382}
3383
halcanary9d524f22016-03-29 09:03:52 -07003384SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003385 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003386 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3387 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003388 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003389 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
halcanary9d524f22016-03-29 09:03:52 -07003390 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08003391 paint);
3392}
3393
reed45561a02016-07-07 12:47:17 -07003394///////////////////////////////////////////////////////////////////////////////////////////////////
3395
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003396SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3397 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003398 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003399 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003400 fText = new char[byteLength];
3401 memcpy(fText, text, byteLength);
3402 fByteLength = byteLength;
3403 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07003404 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003405 fMatrix = *matrix;
3406 } else {
3407 fMatrix.setIdentity();
3408 }
3409 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003410}
3411
fmalita8c89c522014-11-08 16:18:56 -08003412void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003413 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07003414 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003415 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003416}
3417
ethannicholasf62a8b72016-02-11 10:35:21 -08003418Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3419 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003420 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003421 ((const char*) fText) + fByteLength);
3422 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003423 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08003424 if (!fMatrix.isIdentity()) {
joshualittbd724132016-03-03 11:39:38 -08003425 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003426 }
brianosmanfad98562016-05-04 11:06:28 -07003427 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003428 return result;
3429}
3430
halcanary9d524f22016-03-29 09:03:52 -07003431SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003432 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003433 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3434 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003435 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003436 SkPath path;
3437 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3438 SkMatrix* matrixPtr;
3439 SkMatrix matrix;
3440 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3441 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3442 matrixPtr = &matrix;
3443 }
3444 else {
3445 matrixPtr = nullptr;
3446 }
3447 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3448}
3449
reed45561a02016-07-07 12:47:17 -07003450///////////////////////////////////////////////////////////////////////////////////////////////////
3451
3452SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3453 const SkRSXform xform[], const SkRect* cull,
3454 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07003455 : INHERITED(kDrawTextRSXform_OpType)
reed45561a02016-07-07 12:47:17 -07003456{
3457 fText = new char[byteLength];
3458 memcpy(fText, text, byteLength);
3459 fByteLength = byteLength;
3460 int count = paint.countText(text, byteLength);
3461 fXform = new SkRSXform[count];
3462 memcpy(fXform, xform, count * sizeof(SkRSXform));
3463 if (cull) {
3464 fCullStorage = *cull;
3465 fCull = &fCullStorage;
3466 } else {
3467 fCull = nullptr;
3468 }
3469 fPaint = paint;
reed45561a02016-07-07 12:47:17 -07003470}
3471
3472void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3473 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3474}
3475
3476Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3477 Json::Value result = INHERITED::toJSON(urlDataManager);
3478 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3479 ((const char*) fText) + fByteLength);
3480 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3481 return result;
3482}
3483
3484SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3485 UrlDataManager& urlDataManager) {
3486 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3487 size_t byteLength = strlen(text);
3488 SkPaint paint;
3489 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3490
3491 // TODO: handle xform and cull
3492 int count = paint.countText(text, byteLength);
3493 SkAutoTArray<SkRSXform> xform(count);
3494 for (int i = 0; i < count; ++i) {
3495 xform[i].fSCos = 1;
3496 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3497 }
3498 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3499}
3500
3501///////////////////////////////////////////////////////////////////////////////////////////////////
3502
Mike Reedfed9cfd2017-03-17 12:09:04 -04003503SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003504 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003505 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003506 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04003507 , fBlendMode(bmode)
Brian Osman255735e2018-04-06 14:51:42 -04003508 , fPaint(paint) {}
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003509
fmalita8c89c522014-11-08 16:18:56 -08003510void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04003511 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003512}
3513
Brian Osman616f1cb2018-05-29 11:23:35 -04003514///////////////////////////////////////////////////////////////////////////////////////////////////
3515
3516SkDrawAtlasCommand::SkDrawAtlasCommand(const SkImage* image, const SkRSXform xform[],
3517 const SkRect tex[], const SkColor colors[], int count,
3518 SkBlendMode bmode, const SkRect* cull,
3519 const SkPaint* paint)
3520 : INHERITED(kDrawAtlas_OpType)
3521 , fImage(SkRef(image))
3522 , fXform(xform, count)
3523 , fTex(tex, count)
3524 , fColors(colors, colors ? count : 0)
3525 , fBlendMode(bmode)
3526 , fCull(cull)
3527 , fPaint(paint) {}
3528
3529void SkDrawAtlasCommand::execute(SkCanvas* canvas) const {
3530 canvas->drawAtlas(fImage.get(), fXform.begin(), fTex.begin(),
3531 fColors.isEmpty() ? nullptr : fColors.begin(), fXform.count(), fBlendMode,
3532 fCull.getMaybeNull(), fPaint.getMaybeNull());
3533}
3534
3535///////////////////////////////////////////////////////////////////////////////////////////////////
3536
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003537SkRestoreCommand::SkRestoreCommand()
Brian Osman255735e2018-04-06 14:51:42 -04003538 : INHERITED(kRestore_OpType) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00003539
fmalita8c89c522014-11-08 16:18:56 -08003540void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00003541 canvas->restore();
3542}
3543
ethannicholasf62a8b72016-02-11 10:35:21 -08003544SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003545 return new SkRestoreCommand();
3546}
3547
Florin Malita5f6102d2014-06-30 10:13:28 -04003548SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003549 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00003550}
3551
fmalita8c89c522014-11-08 16:18:56 -08003552void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04003553 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00003554}
3555
ethannicholasf62a8b72016-02-11 10:35:21 -08003556SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003557 return new SkSaveCommand();
3558}
3559
reed4960eee2015-12-18 07:09:18 -08003560SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08003561 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08003562 if (rec.fBounds) {
3563 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003564 } else {
3565 fBounds.setEmpty();
3566 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003567
reed4960eee2015-12-18 07:09:18 -08003568 if (rec.fPaint) {
3569 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003570 fPaintPtr = &fPaint;
3571 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07003572 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003573 }
reed4960eee2015-12-18 07:09:18 -08003574 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003575
ethannicholas50a8dd02016-02-10 05:40:46 -08003576 if (rec.fBackdrop) {
3577 fBackdrop = rec.fBackdrop;
3578 fBackdrop->ref();
3579 } else {
3580 fBackdrop = nullptr;
3581 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003582}
3583
ethannicholas50a8dd02016-02-10 05:40:46 -08003584SkSaveLayerCommand::~SkSaveLayerCommand() {
3585 if (fBackdrop != nullptr) {
3586 fBackdrop->unref();
3587 }
3588}
3589
fmalita8c89c522014-11-08 16:18:56 -08003590void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08003591 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3592 fPaintPtr,
3593 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003594}
3595
ethannicholasf62a8b72016-02-11 10:35:21 -08003596Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3597 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003598 if (!fBounds.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07003599 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003600 }
3601 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07003602 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
ethannicholasf62a8b72016-02-11 10:35:21 -08003603 urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003604 }
3605 if (fBackdrop != nullptr) {
3606 Json::Value jsonBackdrop;
ethannicholasf62a8b72016-02-11 10:35:21 -08003607 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003608 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3609 }
3610 if (fSaveLayerFlags != 0) {
3611 SkDebugf("unsupported: saveLayer flags\n");
3612 SkASSERT(false);
3613 }
3614 return result;
3615}
3616
halcanary9d524f22016-03-29 09:03:52 -07003617SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003618 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003619 SkCanvas::SaveLayerRec rec;
3620 SkRect bounds;
3621 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3622 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3623 rec.fBounds = &bounds;
3624 }
3625 SkPaint paint;
3626 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08003627 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003628 rec.fPaint = &paint;
3629 }
3630 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3631 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
ethannicholasf62a8b72016-02-11 10:35:21 -08003632 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003633 }
3634 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3635 if (rec.fBackdrop != nullptr) {
3636 rec.fBackdrop->unref();
3637 }
3638 return result;
3639}
3640
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003641SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08003642 : INHERITED(kSetMatrix_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003643 fMatrix = matrix;
robertphillips70171682014-10-16 14:28:28 -07003644}
3645
fmalita8c89c522014-11-08 16:18:56 -08003646void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
Brian Osman255735e2018-04-06 14:51:42 -04003647 canvas->setMatrix(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00003648}
3649
ethannicholasf62a8b72016-02-11 10:35:21 -08003650Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3651 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08003652 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003653 return result;
3654}
3655
halcanary9d524f22016-03-29 09:03:52 -07003656SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003657 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003658 SkMatrix matrix;
3659 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3660 return new SkSetMatrixCommand(matrix);
3661}