blob: ba54c88924e8e31b126213c0640c7fe7aa006f66 [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";
228 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
229 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
robertphillips9bafc302015-02-13 11:13:00 -0800230 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700231 case kDrawImage_OpType: return "DrawImage";
Stan Ilievac42aeb2017-01-12 16:20:50 -0500232 case kDrawImageLattice_OpType: return "DrawImageLattice";
Brian Osmanc25e2692018-03-12 10:57:28 -0400233 case kDrawImageNine_OpType: return "DrawImageNine";
fmalita651c9202015-07-22 10:23:01 -0700234 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800235 case kDrawOval_OpType: return "DrawOval";
236 case kDrawPaint_OpType: return "DrawPaint";
237 case kDrawPatch_OpType: return "DrawPatch";
238 case kDrawPath_OpType: return "DrawPath";
Brian Osmanc25e2692018-03-12 10:57:28 -0400239 case kDrawArc_OpType: return "DrawArc";
robertphillips9bafc302015-02-13 11:13:00 -0800240 case kDrawPoints_OpType: return "DrawPoints";
241 case kDrawPosText_OpType: return "DrawPosText";
242 case kDrawPosTextH_OpType: return "DrawPosTextH";
243 case kDrawRect_OpType: return "DrawRect";
244 case kDrawRRect_OpType: return "DrawRRect";
Brian Osmanc25e2692018-03-12 10:57:28 -0400245 case kDrawRegion_OpType: return "DrawRegion";
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400246 case kDrawShadow_OpType: return "DrawShadow";
robertphillips9bafc302015-02-13 11:13:00 -0800247 case kDrawText_OpType: return "DrawText";
248 case kDrawTextBlob_OpType: return "DrawTextBlob";
249 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
reed63f30d92016-07-07 16:32:51 -0700250 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
robertphillips9bafc302015-02-13 11:13:00 -0800251 case kDrawVertices_OpType: return "DrawVertices";
fmalita160ebb22015-04-01 20:58:37 -0700252 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800253 case kRestore_OpType: return "Restore";
254 case kSave_OpType: return "Save";
255 case kSaveLayer_OpType: return "SaveLayer";
256 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000257 default:
robertphillips9bafc302015-02-13 11:13:00 -0800258 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000259 SkASSERT(0);
260 break;
261 }
262 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700263 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000264}
265
ethannicholasf62a8b72016-02-11 10:35:21 -0800266Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800267 Json::Value result;
268 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800269 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800270 return result;
271}
272
273#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
274 (FROM_JSON) Sk ## name ## Command::fromJSON)
ethannicholasf62a8b72016-02-11 10:35:21 -0800275SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800276 static SkTHashMap<SkString, FROM_JSON> factories;
277 static bool initialized = false;
278 if (!initialized) {
279 initialized = true;
280 INSTALL_FACTORY(Restore);
Brian Osmanc25e2692018-03-12 10:57:28 -0400281 INSTALL_FACTORY(Clear);
ethannicholas50a8dd02016-02-10 05:40:46 -0800282 INSTALL_FACTORY(ClipPath);
283 INSTALL_FACTORY(ClipRegion);
284 INSTALL_FACTORY(ClipRect);
285 INSTALL_FACTORY(ClipRRect);
286 INSTALL_FACTORY(Concat);
reed97660cc2016-06-28 18:54:19 -0700287 INSTALL_FACTORY(DrawAnnotation);
ethannicholas50a8dd02016-02-10 05:40:46 -0800288 INSTALL_FACTORY(DrawBitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800289 INSTALL_FACTORY(DrawBitmapNine);
Brian Osmanc25e2692018-03-12 10:57:28 -0400290 INSTALL_FACTORY(DrawBitmapRect);
ethannicholas50a8dd02016-02-10 05:40:46 -0800291 INSTALL_FACTORY(DrawImage);
Brian Osmanc25e2692018-03-12 10:57:28 -0400292 INSTALL_FACTORY(DrawImageLattice);
293 INSTALL_FACTORY(DrawImageNine);
ethannicholas50a8dd02016-02-10 05:40:46 -0800294 INSTALL_FACTORY(DrawImageRect);
295 INSTALL_FACTORY(DrawOval);
Brian Osmanc25e2692018-03-12 10:57:28 -0400296 INSTALL_FACTORY(DrawArc);
ethannicholas50a8dd02016-02-10 05:40:46 -0800297 INSTALL_FACTORY(DrawPaint);
298 INSTALL_FACTORY(DrawPath);
299 INSTALL_FACTORY(DrawPoints);
Brian Osmanc25e2692018-03-12 10:57:28 -0400300 INSTALL_FACTORY(DrawRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -0800301 INSTALL_FACTORY(DrawText);
302 INSTALL_FACTORY(DrawPosText);
bungeman51190df2016-03-09 07:42:54 -0800303 INSTALL_FACTORY(DrawPosTextH);
ethannicholas50a8dd02016-02-10 05:40:46 -0800304 INSTALL_FACTORY(DrawTextOnPath);
reed45561a02016-07-07 12:47:17 -0700305 INSTALL_FACTORY(DrawTextRSXform);
ethannicholas50a8dd02016-02-10 05:40:46 -0800306 INSTALL_FACTORY(DrawTextBlob);
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400307 INSTALL_FACTORY(DrawShadow);
ethannicholas50a8dd02016-02-10 05:40:46 -0800308 INSTALL_FACTORY(DrawRect);
309 INSTALL_FACTORY(DrawRRect);
310 INSTALL_FACTORY(DrawDRRect);
ethannicholas1446a9a2016-02-10 14:05:02 -0800311 INSTALL_FACTORY(DrawPatch);
ethannicholas50a8dd02016-02-10 05:40:46 -0800312 INSTALL_FACTORY(Save);
313 INSTALL_FACTORY(SaveLayer);
314 INSTALL_FACTORY(SetMatrix);
315 }
316 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
317 FROM_JSON* factory = factories.find(name);
318 if (factory == nullptr) {
319 SkDebugf("no JSON factory for '%s'\n", name.c_str());
320 return nullptr;
321 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800322 return (*factory)(command, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800323}
324
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000325namespace {
326
327void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500328 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000329
330 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
331
332 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
333 if (bounds.width() > bounds.height()) {
334 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
335 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
336 } else {
337 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
338 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
339 }
340 canvas->translate(-bounds.centerX(), -bounds.centerY());
341}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000342
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000343
344void render_path(SkCanvas* canvas, const SkPath& path) {
345 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000346
347 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700348 if (bounds.isEmpty()) {
349 return;
350 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000351
fmalitab0cd8b72015-10-06 07:24:03 -0700352 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000353 xlate_and_scale_to_bounds(canvas, bounds);
354
355 SkPaint p;
356 p.setColor(SK_ColorBLACK);
357 p.setStyle(SkPaint::kStroke_Style);
358
359 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000360}
361
Brian Osmanc25e2692018-03-12 10:57:28 -0400362void render_region(SkCanvas* canvas, const SkRegion& region) {
363 canvas->clear(0xFFFFFFFF);
364
365 const SkIRect& bounds = region.getBounds();
366 if (bounds.isEmpty()) {
367 return;
368 }
369
370 SkAutoCanvasRestore acr(canvas, true);
Brian Osman99b63402018-03-13 10:19:27 -0400371 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
Brian Osmanc25e2692018-03-12 10:57:28 -0400372
373 SkPaint p;
374 p.setColor(SK_ColorBLACK);
375 p.setStyle(SkPaint::kStroke_Style);
376
377 canvas->drawRegion(region, p);
378}
379
halcanary96fcdcc2015-08-27 07:41:13 -0700380void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500381 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000382
383 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
384 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
385
386 if (input.width() > input.height()) {
387 yScale *= input.height() / (float) input.width();
388 } else {
389 xScale *= input.width() / (float) input.height();
390 }
391
392 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
393 xScale * input.width(),
394 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000395
robertphillips96a5cff2015-09-24 06:56:27 -0700396 static const int kNumBlocks = 8;
397
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000398 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700399 SkISize block = {
400 canvas->imageInfo().width()/kNumBlocks,
401 canvas->imageInfo().height()/kNumBlocks
402 };
403 for (int y = 0; y < kNumBlocks; ++y) {
404 for (int x = 0; x < kNumBlocks; ++x) {
405 SkPaint paint;
406 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
407 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
408 SkIntToScalar(y*block.height()),
409 SkIntToScalar(block.width()),
410 SkIntToScalar(block.height()));
411 canvas->drawRect(r, paint);
412 }
413 }
414
reede47829b2015-08-06 10:02:53 -0700415 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000416
bsalomon49f085d2014-09-05 13:34:00 -0700417 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000418 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
419 srcRect->fTop * yScale + SK_Scalar1,
420 srcRect->fRight * xScale + SK_Scalar1,
421 srcRect->fBottom * yScale + SK_Scalar1);
422 SkPaint p;
423 p.setColor(SK_ColorRED);
424 p.setStyle(SkPaint::kStroke_Style);
425
426 canvas->drawRect(r, p);
427 }
428}
429
430void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
431 canvas->clear(0xFFFFFFFF);
432 canvas->save();
433
434 const SkRect& bounds = rrect.getBounds();
435
436 xlate_and_scale_to_bounds(canvas, bounds);
437
438 SkPaint p;
439 p.setColor(SK_ColorBLACK);
440 p.setStyle(SkPaint::kStroke_Style);
441
442 canvas->drawRRect(rrect, p);
443 canvas->restore();
444}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000445
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000446void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
447 canvas->clear(0xFFFFFFFF);
448 canvas->save();
449
450 const SkRect& bounds = outer.getBounds();
451
452 xlate_and_scale_to_bounds(canvas, bounds);
453
454 SkPaint p;
455 p.setColor(SK_ColorBLACK);
456 p.setStyle(SkPaint::kStroke_Style);
457
458 canvas->drawDRRect(outer, inner, p);
459 canvas->restore();
460}
461
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400462void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
463 canvas->clear(0xFFFFFFFF);
464
465 const SkRect& bounds = path.getBounds();
466 if (bounds.isEmpty()) {
467 return;
468 }
469
470 SkAutoCanvasRestore acr(canvas, true);
471 xlate_and_scale_to_bounds(canvas, bounds);
472
473 rec.fAmbientColor = SK_ColorBLACK;
474 rec.fSpotColor = SK_ColorBLACK;
475 canvas->private_draw_shadow_rec(path, rec);
476}
477
Florin Malita82d80872017-06-06 16:58:40 -0400478static const char* const gBlendModeMap[] = {
479 "clear",
480 "src",
481 "dst",
482 "srcOver",
483 "dstOver",
484 "srcIn",
485 "dstIn",
486 "srcOut",
487 "dstOut",
488 "srcATop",
489 "dstATop",
490 "xor",
491 "plus",
492 "modulate",
493
494 "screen",
495
496 "overlay",
497 "darken",
498 "lighten",
499 "colorDodge",
500 "colorBurn",
501 "hardLight",
502 "softLight",
503 "difference",
504 "exclusion",
505 "multiply",
506
507 "hue",
508 "saturation",
509 "color",
510 "luminosity",
511};
512
513static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
514 "blendMode mismatch");
515static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
516 "blendMode mismatch");
517
518void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
519 const auto mode = paint.getBlendMode();
520 if (mode != SkBlendMode::kSrcOver) {
521 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
522 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
523 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
524 }
525}
526
527void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
528 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
529 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
530
531 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
532 if (!strcmp(mode, gBlendModeMap[i])) {
533 target->setBlendMode(static_cast<SkBlendMode>(i));
534 break;
535 }
536 }
537 }
538}
539
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000540};
541
brianosmanfad98562016-05-04 11:06:28 -0700542Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800543 Json::Value result(Json::arrayValue);
544 result.append(Json::Value(SkColorGetA(color)));
545 result.append(Json::Value(SkColorGetR(color)));
546 result.append(Json::Value(SkColorGetG(color)));
547 result.append(Json::Value(SkColorGetB(color)));
548 return result;
549}
550
brianosman97bbf822016-09-25 13:15:58 -0700551Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
552 Json::Value result(Json::arrayValue);
553 result.append(Json::Value(color.fA));
554 result.append(Json::Value(color.fR));
555 result.append(Json::Value(color.fG));
556 result.append(Json::Value(color.fB));
557 return result;
558}
559
brianosmanfad98562016-05-04 11:06:28 -0700560Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800561 Json::Value result(Json::arrayValue);
562 result.append(Json::Value(point.x()));
563 result.append(Json::Value(point.y()));
564 return result;
565}
566
brianosmanfad98562016-05-04 11:06:28 -0700567Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800568 Json::Value result(Json::arrayValue);
569 result.append(Json::Value(x));
570 result.append(Json::Value(y));
571 return result;
572}
573
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400574Json::Value SkDrawCommand::MakeJsonPoint3(const SkPoint3& point) {
575 Json::Value result(Json::arrayValue);
576 result.append(Json::Value(point.x()));
577 result.append(Json::Value(point.y()));
578 result.append(Json::Value(point.z()));
579 return result;
580}
581
brianosmanfad98562016-05-04 11:06:28 -0700582Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800583 Json::Value result(Json::arrayValue);
584 result.append(Json::Value(rect.left()));
585 result.append(Json::Value(rect.top()));
586 result.append(Json::Value(rect.right()));
587 result.append(Json::Value(rect.bottom()));
588 return result;
589}
590
joshualittbd724132016-03-03 11:39:38 -0800591Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800592 Json::Value result(Json::arrayValue);
593 result.append(Json::Value(rect.left()));
594 result.append(Json::Value(rect.top()));
595 result.append(Json::Value(rect.right()));
596 result.append(Json::Value(rect.bottom()));
597 return result;
598}
599
600static Json::Value make_json_rrect(const SkRRect& rrect) {
601 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700602 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
603 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
604 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
605 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
606 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800607 return result;
608}
609
joshualittbd724132016-03-03 11:39:38 -0800610Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800611 Json::Value result(Json::arrayValue);
612 Json::Value row1(Json::arrayValue);
613 row1.append(Json::Value(matrix[0]));
614 row1.append(Json::Value(matrix[1]));
615 row1.append(Json::Value(matrix[2]));
616 result.append(row1);
617 Json::Value row2(Json::arrayValue);
618 row2.append(Json::Value(matrix[3]));
619 row2.append(Json::Value(matrix[4]));
620 row2.append(Json::Value(matrix[5]));
621 result.append(row2);
622 Json::Value row3(Json::arrayValue);
623 row3.append(Json::Value(matrix[6]));
624 row3.append(Json::Value(matrix[7]));
625 row3.append(Json::Value(matrix[8]));
626 result.append(row3);
627 return result;
628}
ethannicholas1446a9a2016-02-10 14:05:02 -0800629
vjiaoblacke5de1302016-07-13 14:05:28 -0700630Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
631 Json::Value result(z);
632 return result;
633}
634
brianosmanfad98562016-05-04 11:06:28 -0700635Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800636 Json::Value result(Json::objectValue);
637 switch (path.getFillType()) {
638 case SkPath::kWinding_FillType:
639 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
640 break;
641 case SkPath::kEvenOdd_FillType:
642 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
643 break;
644 case SkPath::kInverseWinding_FillType:
645 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
646 break;
647 case SkPath::kInverseEvenOdd_FillType:
648 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
649 break;
halcanary9d524f22016-03-29 09:03:52 -0700650 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800651 Json::Value verbs(Json::arrayValue);
652 SkPath::Iter iter(path, false);
653 SkPoint pts[4];
654 SkPath::Verb verb;
655 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
656 switch (verb) {
657 case SkPath::kLine_Verb: {
658 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700659 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800660 verbs.append(line);
661 break;
662 }
663 case SkPath::kQuad_Verb: {
664 Json::Value quad(Json::objectValue);
665 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700666 coords.append(MakeJsonPoint(pts[1]));
667 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800668 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
669 verbs.append(quad);
670 break;
671 }
672 case SkPath::kCubic_Verb: {
673 Json::Value cubic(Json::objectValue);
674 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700675 coords.append(MakeJsonPoint(pts[1]));
676 coords.append(MakeJsonPoint(pts[2]));
677 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800678 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
679 verbs.append(cubic);
680 break;
681 }
682 case SkPath::kConic_Verb: {
683 Json::Value conic(Json::objectValue);
684 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700685 coords.append(MakeJsonPoint(pts[1]));
686 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800687 coords.append(Json::Value(iter.conicWeight()));
688 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
689 verbs.append(conic);
690 break;
691 }
692 case SkPath::kMove_Verb: {
693 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700694 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800695 verbs.append(move);
696 break;
697 }
698 case SkPath::kClose_Verb:
699 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
700 break;
701 case SkPath::kDone_Verb:
702 break;
703 }
704 }
705 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
706 return result;
707}
708
brianosmanfad98562016-05-04 11:06:28 -0700709Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
Brian Osmanc25e2692018-03-12 10:57:28 -0400710 // TODO: Actually serialize the rectangles, rather than just devolving to path
711 SkPath path;
712 region.getBoundaryPath(&path);
713 return MakeJsonPath(path);
ethannicholas50a8dd02016-02-10 05:40:46 -0800714}
715
Mike Reedc1f77742016-12-09 09:00:50 -0500716static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800717 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500718 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800719 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500720 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800721 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500722 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800723 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500724 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800725 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500726 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800727 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500728 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800729 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
730 default:
731 SkASSERT(false);
732 return Json::Value("<invalid region op>");
733 };
734}
735
736static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
737 switch (mode) {
738 case SkCanvas::kPoints_PointMode:
739 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
740 case SkCanvas::kLines_PointMode:
741 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700742 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800743 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
744 default:
745 SkASSERT(false);
746 return Json::Value("<invalid point mode>");
747 };
748}
749
halcanary9d524f22016-03-29 09:03:52 -0700750static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800751 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800752 if (value != defaultValue) {
753 (*target)[key] = Json::Value(value);
754 }
755}
756
ethannicholasbd3dae82016-02-10 12:10:00 -0800757static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800758 if (value != defaultValue) {
759 (*target)[key] = Json::Value(value);
760 }
761}
762
halcanary9d524f22016-03-29 09:03:52 -0700763static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800764 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700765 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
766 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800767 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800768}
769
brianosmanfad98562016-05-04 11:06:28 -0700770void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
771 UrlDataManager& urlDataManager) {
772 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800773 flattenable->flatten(buffer);
774 void* data = sk_malloc_throw(buffer.bytesWritten());
775 buffer.writeToMemory(data);
776 Json::Value jsonData;
777 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
778 Json::Value jsonFlattenable;
779 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
780 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700781
782 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
783 flattenable->flatten(jsonBuffer);
784 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
785
ethannicholasf62a8b72016-02-11 10:35:21 -0800786 (*target) = jsonFlattenable;
787 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800788}
789
ethannicholasf67531f2016-03-21 10:19:39 -0700790static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
791 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
792 out->write(data, length);
793}
794
halcanarya73d76a2016-10-17 13:19:02 -0700795void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700796 SkWStream& out, bool isOpaque) {
Ben Wagnera93a14a2017-08-28 10:34:05 -0400797 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700798 SkASSERT(png != nullptr);
799 png_infop info_ptr = png_create_info_struct(png);
800 SkASSERT(info_ptr != nullptr);
801 if (setjmp(png_jmpbuf(png))) {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400802 SK_ABORT("png encode error");
ethannicholasf67531f2016-03-21 10:19:39 -0700803 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400804 png_set_write_fn(png, &out, write_png_callback, nullptr);
msaretta5cf4f42016-06-30 10:06:51 -0700805 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
806 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700807 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
808 png_set_compression_level(png, 1);
809 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700810 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700811 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700812 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700813 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700814 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700815 rows[y][x * 4] = src[x * 4];
816 rows[y][x * 4 + 1] = src[x * 4 + 1];
817 rows[y][x * 4 + 2] = src[x * 4 + 2];
818 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700819 }
820 }
msaretta5cf4f42016-06-30 10:06:51 -0700821 png_write_info(png, info_ptr);
822 if (isOpaque) {
823 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
824 }
ethannicholasf67531f2016-03-21 10:19:39 -0700825 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700826 png_write_image(png, &rows[0]);
Ben Wagnera93a14a2017-08-28 10:34:05 -0400827 png_destroy_write_struct(&png, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700828 sk_free(rows);
829 sk_free(pixels);
830}
831
brianosmanfad98562016-05-04 11:06:28 -0700832bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
833 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700834 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500835 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700836 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700837 kN32_SkColorType, kPremul_SkAlphaType);
838 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
839 SkDebugf("readPixels failed\n");
840 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800841 }
msaretta5cf4f42016-06-30 10:06:51 -0700842
843 SkBitmap bm;
844 bm.installPixels(dstInfo, buffer.get(), rowBytes);
845 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
846
ethannicholasf67531f2016-03-21 10:19:39 -0700847 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700848 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700849 out, false);
reed42943c82016-09-12 12:01:44 -0700850 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800851 Json::Value jsonData;
852 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
853 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800854 return true;
855}
856
857static const char* color_type_name(SkColorType colorType) {
858 switch (colorType) {
859 case kARGB_4444_SkColorType:
860 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
861 case kRGBA_8888_SkColorType:
862 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
863 case kBGRA_8888_SkColorType:
864 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
865 case kRGB_565_SkColorType:
866 return SKDEBUGCANVAS_COLORTYPE_565;
867 case kGray_8_SkColorType:
868 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
ethannicholas50a8dd02016-02-10 05:40:46 -0800869 case kAlpha_8_SkColorType:
870 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
871 default:
872 SkASSERT(false);
873 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
874 }
875}
876
877static const char* alpha_type_name(SkAlphaType alphaType) {
878 switch (alphaType) {
879 case kOpaque_SkAlphaType:
880 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
881 case kPremul_SkAlphaType:
882 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
883 case kUnpremul_SkAlphaType:
884 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
885 default:
886 SkASSERT(false);
887 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
888 }
889}
890
halcanary9d524f22016-03-29 09:03:52 -0700891static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -0800892 const void** target) {
893 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
894 if (urlData == nullptr) {
895 SkASSERT(false);
896 *target = nullptr;
897 return 0;
ethannicholas50a8dd02016-02-10 05:40:46 -0800898 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800899 *target = urlData->fData->data();
900 // cast should be safe for any reasonably-sized object...
901 return (Json::ArrayIndex) urlData->fData->size();
ethannicholas50a8dd02016-02-10 05:40:46 -0800902}
903
halcanary9d524f22016-03-29 09:03:52 -0700904static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
ethannicholasf62a8b72016-02-11 10:35:21 -0800905 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800906 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
907 return nullptr;
908 }
909 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
910 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
911 if (factory == nullptr) {
912 SkDebugf("no factory for loading '%s'\n", name);
913 return nullptr;
914 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800915 const void* data;
916 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
Mike Reedfadbfcd2017-12-06 16:09:20 -0500917 SkReadBuffer buffer(data, size);
reed60c9b582016-04-03 09:11:13 -0700918 sk_sp<SkFlattenable> result = factory(buffer);
ethannicholas50a8dd02016-02-10 05:40:46 -0800919 if (!buffer.isValid()) {
920 SkDebugf("invalid buffer loading flattenable\n");
921 return nullptr;
922 }
reed60c9b582016-04-03 09:11:13 -0700923 return result.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800924}
925
926static SkColorType colortype_from_name(const char* name) {
927 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
928 return kARGB_4444_SkColorType;
929 }
930 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
931 return kRGBA_8888_SkColorType;
932 }
933 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
934 return kBGRA_8888_SkColorType;
935 }
936 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
937 return kRGB_565_SkColorType;
938 }
939 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
940 return kGray_8_SkColorType;
941 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800942 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
943 return kAlpha_8_SkColorType;
944 }
945 SkASSERT(false);
946 return kN32_SkColorType;
947}
948
949static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
950 if (bitmap->colorType() == colorType ) {
951 return bitmap;
952 }
953 SkBitmap* dst = new SkBitmap();
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400954 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
955 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
956 {
ethannicholas50a8dd02016-02-10 05:40:46 -0800957 delete bitmap;
958 return dst;
959 }
960 SkASSERT(false);
961 delete dst;
962 return bitmap;
963}
964
965// caller is responsible for freeing return value
ethannicholasf62a8b72016-02-11 10:35:21 -0800966static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
967 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800968 SkDebugf("invalid bitmap\n");
969 return nullptr;
970 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800971 const void* data;
972 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
bungeman38d909e2016-08-02 14:40:46 -0700973 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
reed9ce9d672016-03-17 10:51:11 -0700974 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
msarett790f99a2016-03-09 06:16:55 -0800975
Ben Wagner145dbcd2016-11-03 14:40:50 -0400976 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
msarett790f99a2016-03-09 06:16:55 -0800977 if (nullptr != image) {
Cary Clark4f5a79c2018-02-07 15:51:00 -0500978 if (!image->asLegacyBitmap(bitmap.get())) {
msarett790f99a2016-03-09 06:16:55 -0800979 SkDebugf("image decode failed\n");
980 return nullptr;
981 }
982
ethannicholas50a8dd02016-02-10 05:40:46 -0800983 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
984 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
985 SkColorType ct = colortype_from_name(ctName);
Mike Reed304a07c2017-07-12 15:10:28 -0400986 bitmap.reset(convert_colortype(bitmap.release(), ct));
ethannicholas50a8dd02016-02-10 05:40:46 -0800987 }
mtklein18300a32016-03-16 13:53:35 -0700988 return bitmap.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800989 }
990 SkDebugf("image decode failed\n");
ethannicholas50a8dd02016-02-10 05:40:46 -0800991 return nullptr;
992}
993
reed9ce9d672016-03-17 10:51:11 -0700994static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
ethannicholasf62a8b72016-02-11 10:35:21 -0800995 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800996 if (bitmap == nullptr) {
997 return nullptr;
998 }
reed9ce9d672016-03-17 10:51:11 -0700999 auto result = SkImage::MakeFromBitmap(*bitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -08001000 delete bitmap;
1001 return result;
1002}
1003
brianosmanfad98562016-05-04 11:06:28 -07001004bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
1005 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07001006 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -08001007 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
1008 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -08001009 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001010 return success;
1011}
1012
halcanaryf412f092016-08-25 11:10:41 -07001013static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
1014 SkPaint::Hinting hinting = paint.getHinting();
1015 if (hinting != SkPaintDefaults_Hinting) {
1016 switch (hinting) {
1017 case SkPaint::kNo_Hinting:
1018 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
1019 break;
1020 case SkPaint::kSlight_Hinting:
1021 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
1022 break;
1023 case SkPaint::kNormal_Hinting:
1024 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
1025 break;
1026 case SkPaint::kFull_Hinting:
1027 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
1028 break;
1029 }
1030 }
1031}
1032
ethannicholas50a8dd02016-02-10 05:40:46 -08001033static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
1034 SkColor color = paint.getColor();
1035 if (color != SK_ColorBLACK) {
1036 Json::Value colorValue(Json::arrayValue);
1037 colorValue.append(Json::Value(SkColorGetA(color)));
1038 colorValue.append(Json::Value(SkColorGetR(color)));
1039 colorValue.append(Json::Value(SkColorGetG(color)));
1040 colorValue.append(Json::Value(SkColorGetB(color)));
1041 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
1042 }
1043}
1044
1045static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
1046 SkPaint::Style style = paint.getStyle();
1047 if (style != SkPaint::kFill_Style) {
1048 switch (style) {
1049 case SkPaint::kStroke_Style: {
1050 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
1051 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
1052 break;
1053 }
1054 case SkPaint::kStrokeAndFill_Style: {
1055 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1056 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1057 break;
1058 }
1059 default: SkASSERT(false);
1060 }
1061 }
1062}
1063
1064static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1065 SkPaint::Cap cap = paint.getStrokeCap();
1066 if (cap != SkPaint::kDefault_Cap) {
1067 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001068 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001069 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1070 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001071 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001072 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1073 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001074 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001075 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1076 break;
ethannicholas50a8dd02016-02-10 05:40:46 -08001077 default: SkASSERT(false);
1078 }
1079 }
1080}
ethannicholas1446a9a2016-02-10 14:05:02 -08001081
1082static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1083 SkPaint::Join join = paint.getStrokeJoin();
1084 if (join != SkPaint::kDefault_Join) {
1085 switch (join) {
1086 case SkPaint::kMiter_Join:
1087 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1088 SKDEBUGCANVAS_MITER_JOIN);
1089 break;
1090 case SkPaint::kRound_Join:
1091 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1092 SKDEBUGCANVAS_ROUND_JOIN);
1093 break;
1094 case SkPaint::kBevel_Join:
1095 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1096 SKDEBUGCANVAS_BEVEL_JOIN);
1097 break;
1098 default: SkASSERT(false);
1099 }
1100 }
1101}
1102
1103static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1104 SkFilterQuality quality = paint.getFilterQuality();
1105 switch (quality) {
1106 case kNone_SkFilterQuality:
1107 break;
1108 case kLow_SkFilterQuality:
1109 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1110 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1111 break;
1112 case kMedium_SkFilterQuality:
1113 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1114 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1115 break;
1116 case kHigh_SkFilterQuality:
1117 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1118 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1119 break;
1120 }
1121}
1122
halcanary9d524f22016-03-29 09:03:52 -07001123static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001124 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001125 SkMaskFilter* maskFilter = paint.getMaskFilter();
1126 if (maskFilter != nullptr) {
Mike Reed80747ef2018-01-23 15:29:32 -05001127 SkMaskFilterBase::BlurRec blurRec;
1128 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001129 Json::Value blur(Json::objectValue);
1130 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1131 switch (blurRec.fStyle) {
1132 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001133 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1134 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -08001135 break;
1136 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001137 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1138 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -08001139 break;
1140 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001141 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1142 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001143 break;
1144 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001145 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1146 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001147 break;
1148 default:
1149 SkASSERT(false);
1150 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001151 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1152 } else {
1153 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -07001154 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001155 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1156 }
1157 }
1158}
1159
halcanary9d524f22016-03-29 09:03:52 -07001160static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001161 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001162 SkPathEffect* pathEffect = paint.getPathEffect();
1163 if (pathEffect != nullptr) {
1164 SkPathEffect::DashInfo dashInfo;
1165 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1166 if (dashType == SkPathEffect::kDash_DashType) {
1167 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1168 pathEffect->asADash(&dashInfo);
1169 Json::Value dashing(Json::objectValue);
1170 Json::Value intervals(Json::arrayValue);
1171 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1172 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1173 }
1174 sk_free(dashInfo.fIntervals);
1175 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1176 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1177 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1178 } else {
1179 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001180 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001181 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1182 }
1183 }
1184}
halcanary9d524f22016-03-29 09:03:52 -07001185
ethannicholas50a8dd02016-02-10 05:40:46 -08001186static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1187 SkPaint::Align textAlign = paint.getTextAlign();
1188 if (textAlign != SkPaint::kLeft_Align) {
1189 switch (textAlign) {
1190 case SkPaint::kCenter_Align: {
1191 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1192 break;
1193 }
1194 case SkPaint::kRight_Align: {
1195 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1196 break;
1197 }
1198 default: SkASSERT(false);
1199 }
1200 }
1201}
1202
halcanary9d524f22016-03-29 09:03:52 -07001203static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001204 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001205 SkTypeface* typeface = paint.getTypeface();
1206 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001207 Json::Value jsonTypeface;
1208 SkDynamicMemoryWStream buffer;
1209 typeface->serialize(&buffer);
1210 void* data = sk_malloc_throw(buffer.bytesWritten());
1211 buffer.copyTo(data);
1212 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001213 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001214 &jsonData);
1215 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1216 sk_free(data);
1217 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001218 }
1219}
1220
halcanary9d524f22016-03-29 09:03:52 -07001221static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001222 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001223 SkFlattenable* shader = paint.getShader();
1224 if (shader != nullptr) {
1225 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001226 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001227 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1228 }
1229}
1230
ethannicholasf62a8b72016-02-11 10:35:21 -08001231static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1232 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001233 SkFlattenable* imageFilter = paint.getImageFilter();
1234 if (imageFilter != nullptr) {
1235 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001236 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001237 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1238 }
1239}
1240
halcanary9d524f22016-03-29 09:03:52 -07001241static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001242 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001243 SkFlattenable* colorFilter = paint.getColorFilter();
1244 if (colorFilter != nullptr) {
1245 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001246 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001247 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1248 }
1249}
1250
halcanary9d524f22016-03-29 09:03:52 -07001251static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001252 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001253 SkFlattenable* looper = paint.getLooper();
1254 if (looper != nullptr) {
1255 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001256 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001257 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1258 }
1259}
1260
brianosmanfad98562016-05-04 11:06:28 -07001261Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001262 Json::Value result(Json::objectValue);
1263 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001264 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001265 SkPaintDefaults_MiterLimit);
1266 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001267 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001268 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1269 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1270 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001271 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1272 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1273 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1274 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1275 //kGenA8FromLCD_Flag
1276
halcanary9d524f22016-03-29 09:03:52 -07001277 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001278 SkPaintDefaults_TextSize);
1279 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1280 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001281 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001282 apply_paint_color(paint, &result);
1283 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001284 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001285 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001286 apply_paint_join(paint, &result);
1287 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001288 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001289 apply_paint_patheffect(paint, &result, urlDataManager);
1290 apply_paint_maskfilter(paint, &result, urlDataManager);
1291 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001292 apply_paint_looper(paint, &result, urlDataManager);
1293 apply_paint_imagefilter(paint, &result, urlDataManager);
1294 apply_paint_colorfilter(paint, &result, urlDataManager);
1295 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001296 return result;
1297}
1298
Stan Ilievac42aeb2017-01-12 16:20:50 -05001299Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1300 Json::Value result(Json::objectValue);
1301 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1302 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1303 if (nullptr != lattice.fBounds) {
1304 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1305 }
1306 Json::Value XDivs(Json::arrayValue);
1307 for (int i = 0; i < lattice.fXCount; i++) {
1308 XDivs.append(Json::Value(lattice.fXDivs[i]));
1309 }
1310 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1311 Json::Value YDivs(Json::arrayValue);
1312 for (int i = 0; i < lattice.fYCount; i++) {
1313 YDivs.append(Json::Value(lattice.fYDivs[i]));
1314 }
1315 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
Stan Ilievca8c0952017-12-11 13:01:58 -05001316 if (nullptr != lattice.fRectTypes) {
Stan Ilievac42aeb2017-01-12 16:20:50 -05001317 Json::Value flags(Json::arrayValue);
1318 int flagCount = 0;
1319 for (int row = 0; row < lattice.fYCount+1; row++) {
1320 Json::Value flagsRow(Json::arrayValue);
1321 for (int column = 0; column < lattice.fXCount+1; column++) {
Stan Ilievca8c0952017-12-11 13:01:58 -05001322 flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++]));
Stan Ilievac42aeb2017-01-12 16:20:50 -05001323 }
1324 flags.append(flagsRow);
1325 }
1326 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1327 }
1328 return result;
1329}
1330
ethannicholas1446a9a2016-02-10 14:05:02 -08001331static SkPoint get_json_point(Json::Value point) {
1332 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1333}
1334
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04001335static SkPoint3 get_json_point3(Json::Value point) {
1336 return SkPoint3::Make(point[0].asFloat(), point[1].asFloat(), point[2].asFloat());
1337}
1338
ethannicholas1446a9a2016-02-10 14:05:02 -08001339static SkColor get_json_color(Json::Value color) {
1340 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1341}
1342
ethannicholas50a8dd02016-02-10 05:40:46 -08001343static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1344 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001345 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001346 }
1347}
1348
halcanary9d524f22016-03-29 09:03:52 -07001349static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001350 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001351 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1352 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
ethannicholasf62a8b72016-02-11 10:35:21 -08001353 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001354 if (shader != nullptr) {
reedfe630452016-03-25 09:08:00 -07001355 target->setShader(sk_ref_sp(shader));
ethannicholas50a8dd02016-02-10 05:40:46 -08001356 }
1357 }
1358}
1359
halcanary9d524f22016-03-29 09:03:52 -07001360static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001361 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001362 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1363 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
reeda4393342016-03-18 11:22:57 -07001364 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1365 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001366 if (pathEffect != nullptr) {
1367 target->setPathEffect(pathEffect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001368 }
1369 }
1370}
1371
halcanary9d524f22016-03-29 09:03:52 -07001372static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001373 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001374 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1375 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
reedefdfd512016-04-04 10:02:58 -07001376 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1377 urlDataManager));
1378 if (maskFilter) {
1379 target->setMaskFilter(std::move(maskFilter));
ethannicholas50a8dd02016-02-10 05:40:46 -08001380 }
1381 }
1382}
1383
halcanary9d524f22016-03-29 09:03:52 -07001384static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001385 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001386 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1387 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
reedd053ce92016-03-22 10:17:23 -07001388 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1389 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001390 if (colorFilter != nullptr) {
1391 target->setColorFilter(colorFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001392 }
1393 }
1394}
1395
halcanary9d524f22016-03-29 09:03:52 -07001396static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001397 SkPaint* target) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001398 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1399 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
reed7b380d02016-03-21 13:25:16 -07001400 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
ethannicholas1446a9a2016-02-10 14:05:02 -08001401 if (looper != nullptr) {
reed7b380d02016-03-21 13:25:16 -07001402 target->setLooper(std::move(looper));
ethannicholas1446a9a2016-02-10 14:05:02 -08001403 }
1404 }
1405}
1406
halcanary9d524f22016-03-29 09:03:52 -07001407static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001408 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001409 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1410 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
Mike Reed5e257172016-11-01 11:22:05 -04001411 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1412 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001413 if (imageFilter != nullptr) {
1414 target->setImageFilter(imageFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001415 }
1416 }
1417}
1418
halcanary9d524f22016-03-29 09:03:52 -07001419static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001420 SkPaint* target) {
1421 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1422 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1423 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1424 const void* data;
1425 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1426 SkMemoryStream buffer(data, length);
bungeman13b9c952016-05-12 10:09:30 -07001427 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
ethannicholasf62a8b72016-02-11 10:35:21 -08001428 }
1429}
1430
halcanaryf412f092016-08-25 11:10:41 -07001431static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1432 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1433 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1434 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1435 target->setHinting(SkPaint::kNo_Hinting);
1436 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1437 target->setHinting(SkPaint::kSlight_Hinting);
1438 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1439 target->setHinting(SkPaint::kNormal_Hinting);
1440 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1441 target->setHinting(SkPaint::kFull_Hinting);
1442 }
1443 }
1444}
1445
ethannicholas50a8dd02016-02-10 05:40:46 -08001446static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1447 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1448 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1449 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1450 target->setStyle(SkPaint::kFill_Style);
1451 }
1452 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1453 target->setStyle(SkPaint::kStroke_Style);
1454 }
1455 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1456 target->setStyle(SkPaint::kStrokeAndFill_Style);
1457 }
1458 }
1459}
1460
1461static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1462 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1463 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1464 target->setStrokeWidth(strokeWidth);
halcanary9d524f22016-03-29 09:03:52 -07001465 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001466}
1467
1468static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1469 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1470 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1471 target->setStrokeMiter(strokeMiter);
halcanary9d524f22016-03-29 09:03:52 -07001472 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001473}
1474
ethannicholas1446a9a2016-02-10 14:05:02 -08001475static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1476 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1477 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1478 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1479 target->setStrokeJoin(SkPaint::kMiter_Join);
1480 }
1481 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1482 target->setStrokeJoin(SkPaint::kRound_Join);
1483 }
1484 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1485 target->setStrokeJoin(SkPaint::kBevel_Join);
1486 }
1487 else {
1488 SkASSERT(false);
1489 }
1490 }
1491}
1492
ethannicholas50a8dd02016-02-10 05:40:46 -08001493static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1494 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1495 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1496 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1497 target->setStrokeCap(SkPaint::kButt_Cap);
1498 }
1499 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1500 target->setStrokeCap(SkPaint::kRound_Cap);
1501 }
1502 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1503 target->setStrokeCap(SkPaint::kSquare_Cap);
1504 }
1505 }
1506}
1507
ethannicholas1446a9a2016-02-10 14:05:02 -08001508static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1509 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1510 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1511 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1512 target->setFilterQuality(kNone_SkFilterQuality);
1513 }
1514 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1515 target->setFilterQuality(kLow_SkFilterQuality);
1516 }
1517 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1518 target->setFilterQuality(kMedium_SkFilterQuality);
1519 }
1520 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1521 target->setFilterQuality(kHigh_SkFilterQuality);
1522 }
1523 }
1524}
1525
ethannicholas50a8dd02016-02-10 05:40:46 -08001526static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1527 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1528 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1529 }
1530}
1531
ethannicholas1446a9a2016-02-10 14:05:02 -08001532static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1533 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1534 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1535 }
1536}
1537
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001538static void extract_json_paint_fakeboldtext(Json::Value& jsonPaint, SkPaint* target) {
1539 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT)) {
1540 target->setFakeBoldText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT].asBool());
1541 }
1542}
1543
1544static void extract_json_paint_lineartext(Json::Value& jsonPaint, SkPaint* target) {
1545 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT)) {
1546 target->setLinearText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT].asBool());
1547 }
1548}
1549
1550static void extract_json_paint_subpixeltext(Json::Value& jsonPaint, SkPaint* target) {
1551 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT)) {
1552 target->setSubpixelText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT].asBool());
1553 }
1554}
1555
1556static void extract_json_paint_devkerntext(Json::Value& jsonPaint, SkPaint* target) {
1557 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT)) {
1558 target->setDevKernText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT].asBool());
1559 }
1560}
1561
1562static void extract_json_paint_lcdrendertext(Json::Value& jsonPaint, SkPaint* target) {
1563 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT)) {
1564 target->setLCDRenderText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT].asBool());
1565 }
1566}
1567
1568static void extract_json_paint_embeddedbitmaptext(Json::Value& jsonPaint, SkPaint* target) {
1569 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT)) {
1570 target->setEmbeddedBitmapText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT].asBool());
1571 }
1572}
1573
1574static void extract_json_paint_autohinting(Json::Value& jsonPaint, SkPaint* target) {
1575 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING)) {
1576 target->setAutohinted(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING].asBool());
1577 }
1578}
1579
1580static void extract_json_paint_verticaltext(Json::Value& jsonPaint, SkPaint* target) {
1581 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT)) {
1582 target->setVerticalText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT].asBool());
1583 }
1584}
1585
ethannicholas50a8dd02016-02-10 05:40:46 -08001586static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1587 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1588 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1589 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1590 SkBlurStyle style;
1591 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1592 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1593 style = SkBlurStyle::kNormal_SkBlurStyle;
1594 }
1595 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1596 style = SkBlurStyle::kSolid_SkBlurStyle;
1597 }
1598 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1599 style = SkBlurStyle::kOuter_SkBlurStyle;
1600 }
1601 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1602 style = SkBlurStyle::kInner_SkBlurStyle;
1603 }
1604 else {
1605 SkASSERT(false);
1606 style = SkBlurStyle::kNormal_SkBlurStyle;
1607 }
Mike Reed1be1f8d2018-03-14 13:01:17 -04001608 target->setMaskFilter(SkMaskFilter::MakeBlur(style, sigma));
ethannicholas50a8dd02016-02-10 05:40:46 -08001609 }
1610}
1611
1612static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1613 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1614 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1615 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1616 Json::ArrayIndex count = jsonIntervals.size();
1617 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1618 for (Json::ArrayIndex i = 0; i < count; i++) {
1619 intervals[i] = jsonIntervals[i].asFloat();
1620 }
1621 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
reeda4393342016-03-18 11:22:57 -07001622 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
ethannicholas50a8dd02016-02-10 05:40:46 -08001623 sk_free(intervals);
1624 }
1625}
1626
1627static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1628 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1629 SkPaint::Align textAlign;
1630 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1631 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1632 textAlign = SkPaint::kLeft_Align;
1633 }
1634 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1635 textAlign = SkPaint::kCenter_Align;
1636 }
1637 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1638 textAlign = SkPaint::kRight_Align;
1639 }
1640 else {
1641 SkASSERT(false);
1642 textAlign = SkPaint::kLeft_Align;
1643 }
1644 target->setTextAlign(textAlign);
1645 }
1646}
1647
1648static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1649 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1650 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1651 target->setTextSize(textSize);
1652 }
1653}
1654
1655static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1656 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1657 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1658 target->setTextScaleX(textScaleX);
1659 }
1660}
1661
1662static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1663 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1664 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1665 target->setTextSkewX(textSkewX);
1666 }
1667}
1668
halcanary9d524f22016-03-29 09:03:52 -07001669static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001670 SkPaint* result) {
halcanaryf412f092016-08-25 11:10:41 -07001671 extract_json_paint_hinting(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001672 extract_json_paint_color(paint, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001673 extract_json_paint_shader(paint, urlDataManager, result);
1674 extract_json_paint_patheffect(paint, urlDataManager, result);
1675 extract_json_paint_maskfilter(paint, urlDataManager, result);
1676 extract_json_paint_colorfilter(paint, urlDataManager, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001677 extract_json_paint_looper(paint, urlDataManager, result);
1678 extract_json_paint_imagefilter(paint, urlDataManager, result);
1679 extract_json_paint_typeface(paint, urlDataManager, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001680 extract_json_paint_style(paint, result);
Florin Malita82d80872017-06-06 16:58:40 -04001681 extract_json_paint_blend_mode(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001682 extract_json_paint_strokewidth(paint, result);
1683 extract_json_paint_strokemiter(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001684 extract_json_paint_strokejoin(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001685 extract_json_paint_cap(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001686 extract_json_paint_filterquality(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001687 extract_json_paint_antialias(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001688 extract_json_paint_dither(paint, result);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001689 extract_json_paint_fakeboldtext(paint, result);
1690 extract_json_paint_lineartext(paint, result);
1691 extract_json_paint_subpixeltext(paint, result);
1692 extract_json_paint_devkerntext(paint, result);
1693 extract_json_paint_lcdrendertext(paint, result);
1694 extract_json_paint_embeddedbitmaptext(paint, result);
1695 extract_json_paint_autohinting(paint, result);
1696 extract_json_paint_verticaltext(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001697 extract_json_paint_blur(paint, result);
1698 extract_json_paint_dashing(paint, result);
1699 extract_json_paint_textalign(paint, result);
1700 extract_json_paint_textsize(paint, result);
1701 extract_json_paint_textscalex(paint, result);
1702 extract_json_paint_textskewx(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001703}
1704
1705static void extract_json_rect(Json::Value& rect, SkRect* result) {
1706 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1707}
1708
1709static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1710 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1711}
1712
1713static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1714 SkVector radii[4] = {
halcanary9d524f22016-03-29 09:03:52 -07001715 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1716 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1717 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
ethannicholas50a8dd02016-02-10 05:40:46 -08001718 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1719 };
halcanary9d524f22016-03-29 09:03:52 -07001720 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1721 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
ethannicholas50a8dd02016-02-10 05:40:46 -08001722 radii);
1723}
1724
1725static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
halcanary9d524f22016-03-29 09:03:52 -07001726 SkScalar values[] = {
ethannicholas50a8dd02016-02-10 05:40:46 -08001727 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1728 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
halcanary9d524f22016-03-29 09:03:52 -07001729 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
ethannicholas50a8dd02016-02-10 05:40:46 -08001730 };
1731 result->set9(values);
1732}
1733
1734static void extract_json_path(Json::Value& path, SkPath* result) {
1735 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1736 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1737 result->setFillType(SkPath::kWinding_FillType);
1738 }
1739 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1740 result->setFillType(SkPath::kEvenOdd_FillType);
1741 }
1742 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1743 result->setFillType(SkPath::kInverseWinding_FillType);
1744 }
1745 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1746 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1747 }
1748 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1749 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1750 Json::Value verb = verbs[i];
1751 if (verb.isString()) {
1752 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1753 result->close();
1754 }
1755 else {
1756 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1757 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1758 result->moveTo(move[0].asFloat(), move[1].asFloat());
1759 }
1760 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1761 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1762 result->lineTo(line[0].asFloat(), line[1].asFloat());
1763 }
1764 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1765 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1766 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1767 quad[1][0].asFloat(), quad[1][1].asFloat());
1768 }
1769 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1770 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1771 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1772 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1773 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1774 }
1775 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1776 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1777 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1778 conic[1][0].asFloat(), conic[1][1].asFloat(),
1779 conic[2].asFloat());
1780 }
1781 else {
1782 SkASSERT(false);
1783 }
1784 }
1785 }
1786}
1787
Brian Osmanc25e2692018-03-12 10:57:28 -04001788static void extract_json_region(Json::Value& region, SkRegion* result) {
1789 SkPath path;
1790 extract_json_path(region, &path);
1791 result->setPath(path, SkRegion(path.getBounds().roundOut()));
1792}
1793
Mike Reedc1f77742016-12-09 09:00:50 -05001794SkClipOp get_json_clipop(Json::Value& jsonOp) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001795 const char* op = jsonOp.asCString();
1796 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001797 return kDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001798 }
1799 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001800 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001801 }
1802 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001803 return kUnion_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001804 }
1805 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001806 return kXOR_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001807 }
1808 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001809 return kReverseDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001810 }
1811 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001812 return kReplace_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001813 }
1814 SkASSERT(false);
Mike Reedc1f77742016-12-09 09:00:50 -05001815 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001816}
1817
Brian Osmanc25e2692018-03-12 10:57:28 -04001818SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001819 fColor = color;
ethannicholas1446a9a2016-02-10 14:05:02 -08001820}
1821
1822void SkClearCommand::execute(SkCanvas* canvas) const {
1823 canvas->clear(fColor);
1824}
1825
ethannicholasf62a8b72016-02-11 10:35:21 -08001826Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1827 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001828 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001829 return result;
1830}
1831
ethannicholasf62a8b72016-02-11 10:35:21 -08001832 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001833 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1834 return new SkClearCommand(get_json_color(color));
1835}
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001836
Mike Reedc1f77742016-12-09 09:00:50 -05001837SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001838 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001839 fPath = path;
1840 fOp = op;
1841 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001842}
1843
fmalita8c89c522014-11-08 16:18:56 -08001844void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001845 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001846}
1847
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001848bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001849 render_path(canvas, fPath);
1850 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001851}
1852
ethannicholasf62a8b72016-02-11 10:35:21 -08001853Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1854 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001855 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001856 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1857 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1858 return result;
1859}
1860
halcanary9d524f22016-03-29 09:03:52 -07001861SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001862 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001863 SkPath path;
1864 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
reed73603f32016-09-20 08:42:38 -07001865 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001866 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1867}
1868
Mike Reedc1f77742016-12-09 09:00:50 -05001869SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001870 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001871 fRegion = region;
1872 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001873}
1874
fmalita8c89c522014-11-08 16:18:56 -08001875void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001876 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001877}
1878
ethannicholasf62a8b72016-02-11 10:35:21 -08001879Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1880 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001881 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001882 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1883 return result;
1884}
1885
halcanary9d524f22016-03-29 09:03:52 -07001886SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001887 UrlDataManager& urlDataManager) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001888 SkRegion region;
1889 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
1890 return new SkClipRegionCommand(region,
1891 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001892}
1893
Mike Reedc1f77742016-12-09 09:00:50 -05001894SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001895 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001896 fRect = rect;
1897 fOp = op;
1898 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001899}
1900
fmalita8c89c522014-11-08 16:18:56 -08001901void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001902 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001903}
1904
ethannicholasf62a8b72016-02-11 10:35:21 -08001905Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1906 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001907 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001908 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1909 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001910
1911 SkString desc;
1912 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1913
ethannicholas50a8dd02016-02-10 05:40:46 -08001914 return result;
1915}
1916
halcanary9d524f22016-03-29 09:03:52 -07001917SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001918 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001919 SkRect rect;
1920 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
reed73603f32016-09-20 08:42:38 -07001921 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001922 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1923}
1924
Mike Reedc1f77742016-12-09 09:00:50 -05001925SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001926 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001927 fRRect = rrect;
1928 fOp = op;
1929 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001930}
1931
fmalita8c89c522014-11-08 16:18:56 -08001932void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001933 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001934}
1935
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001936bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001937 render_rrect(canvas, fRRect);
1938 return true;
1939}
1940
ethannicholasf62a8b72016-02-11 10:35:21 -08001941Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1942 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001943 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1944 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1945 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1946 return result;
1947}
1948
halcanary9d524f22016-03-29 09:03:52 -07001949SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001950 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001951 SkRRect rrect;
1952 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
halcanary9d524f22016-03-29 09:03:52 -07001953 return new SkClipRRectCommand(rrect,
reed73603f32016-09-20 08:42:38 -07001954 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001955 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1956}
1957
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001958SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001959 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001960 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001961}
1962
fmalita8c89c522014-11-08 16:18:56 -08001963void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001964 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001965}
1966
ethannicholasf62a8b72016-02-11 10:35:21 -08001967Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1968 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001969 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001970 return result;
1971}
1972
ethannicholasf62a8b72016-02-11 10:35:21 -08001973SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001974 SkMatrix matrix;
1975 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1976 return new SkConcatCommand(matrix);
1977}
1978
reed97660cc2016-06-28 18:54:19 -07001979////
1980
1981SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1982 sk_sp<SkData> value)
1983 : INHERITED(kDrawAnnotation_OpType)
1984 , fRect(rect)
1985 , fKey(key)
1986 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07001987{
robertphillipsfb409232016-06-29 10:28:11 -07001988}
reed97660cc2016-06-28 18:54:19 -07001989
1990void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1991 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1992}
1993
1994Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1995 Json::Value result = INHERITED::toJSON(urlDataManager);
1996
1997 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1998 result["key"] = Json::Value(fKey.c_str());
1999 if (fValue.get()) {
2000 // TODO: dump out the "value"
2001 }
reed67f62fa2016-06-29 11:36:34 -07002002
2003 SkString desc;
2004 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
2005 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
2006
reed97660cc2016-06-28 18:54:19 -07002007 return result;
2008}
2009
2010SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
2011 UrlDataManager& urlDataManager) {
2012 SkRect rect;
2013 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
2014 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
2015 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
2016}
2017
2018////
2019
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002020SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07002021 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002022 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002023 fBitmap = bitmap;
2024 fLeft = left;
2025 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07002026 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002027 fPaint = *paint;
2028 fPaintPtr = &fPaint;
2029 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002030 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002031 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002032}
2033
fmalita8c89c522014-11-08 16:18:56 -08002034void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002035 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002036}
2037
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002038bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002039 render_bitmap(canvas, fBitmap);
2040 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002041}
2042
ethannicholasf62a8b72016-02-11 10:35:21 -08002043Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
2044 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002045 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002046 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002047 Json::Value command(Json::objectValue);
2048 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002049 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002050 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002051 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002052 }
2053 }
2054 return result;
2055}
2056
halcanary9d524f22016-03-29 09:03:52 -07002057SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002058 UrlDataManager& urlDataManager) {
2059 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002060 if (bitmap == nullptr) {
2061 return nullptr;
2062 }
2063 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2064 SkPaint* paintPtr;
2065 SkPaint paint;
2066 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002067 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002068 paintPtr = &paint;
2069 }
2070 else {
2071 paintPtr = nullptr;
2072 }
halcanary9d524f22016-03-29 09:03:52 -07002073 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002074 point[1].asFloat(), paintPtr);
2075 delete bitmap;
2076 return result;
2077}
2078
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002079SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00002080 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002081 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002082 fBitmap = bitmap;
2083 fCenter = center;
2084 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07002085 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002086 fPaint = *paint;
2087 fPaintPtr = &fPaint;
2088 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002089 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002090 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002091}
2092
fmalita8c89c522014-11-08 16:18:56 -08002093void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002094 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002095}
2096
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002097bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08002098 SkRect tmp = SkRect::Make(fCenter);
2099 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002100 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002101}
2102
ethannicholasf62a8b72016-02-11 10:35:21 -08002103Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2104 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002105 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002106 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002107 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08002108 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07002109 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002110 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002111 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002112 }
2113 }
2114 return result;
2115}
2116
halcanary9d524f22016-03-29 09:03:52 -07002117SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002118 UrlDataManager& urlDataManager) {
2119 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002120 if (bitmap == nullptr) {
2121 return nullptr;
2122 }
2123 SkIRect center;
2124 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2125 SkRect dst;
2126 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2127 SkPaint* paintPtr;
2128 SkPaint paint;
2129 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002130 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002131 paintPtr = &paint;
2132 }
2133 else {
2134 paintPtr = nullptr;
2135 }
2136 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2137 delete bitmap;
2138 return result;
2139}
2140
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002141SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002142 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002143 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08002144 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002145 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07002146 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002147 fSrc = *src;
2148 } else {
2149 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002150 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00002151 fDst = dst;
2152
bsalomon49f085d2014-09-05 13:34:00 -07002153 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002154 fPaint = *paint;
2155 fPaintPtr = &fPaint;
2156 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002157 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00002158 }
reeda5517e22015-07-14 10:54:12 -07002159 fConstraint = constraint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002160}
2161
fmalita8c89c522014-11-08 16:18:56 -08002162void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07002163 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002164}
2165
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002166bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002167 render_bitmap(canvas, fBitmap, this->srcRect());
2168 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002169}
2170
ethannicholasf62a8b72016-02-11 10:35:21 -08002171Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2172 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002173 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002174 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002175 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2176 if (!fSrc.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07002177 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
ethannicholas50a8dd02016-02-10 05:40:46 -08002178 }
brianosmanfad98562016-05-04 11:06:28 -07002179 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002180 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002181 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002182 }
2183 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2184 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2185 }
2186 }
reed67f62fa2016-06-29 11:36:34 -07002187
2188 SkString desc;
2189 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2190
ethannicholas50a8dd02016-02-10 05:40:46 -08002191 return result;
2192}
2193
halcanary9d524f22016-03-29 09:03:52 -07002194SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002195 UrlDataManager& urlDataManager) {
2196 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002197 if (bitmap == nullptr) {
2198 return nullptr;
2199 }
2200 SkRect dst;
2201 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2202 SkPaint* paintPtr;
2203 SkPaint paint;
2204 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002205 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002206 paintPtr = &paint;
2207 }
2208 else {
2209 paintPtr = nullptr;
2210 }
2211 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002212 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002213 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2214 constraint = SkCanvas::kStrict_SrcRectConstraint;
2215 }
2216 else {
2217 constraint = SkCanvas::kFast_SrcRectConstraint;
2218 }
2219 SkRect* srcPtr;
2220 SkRect src;
2221 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2222 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2223 srcPtr = &src;
2224 }
2225 else {
2226 srcPtr = nullptr;
2227 }
2228 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2229 constraint);
2230 delete bitmap;
2231 return result;
2232}
2233
fmalita651c9202015-07-22 10:23:01 -07002234SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2235 const SkPaint* paint)
2236 : INHERITED(kDrawImage_OpType)
2237 , fImage(SkRef(image))
2238 , fLeft(left)
2239 , fTop(top) {
2240
2241 if (paint) {
2242 fPaint.set(*paint);
2243 }
2244}
2245
2246void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002247 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07002248}
2249
2250bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2251 SkAutoCanvasRestore acr(canvas, true);
2252 canvas->clear(0xFFFFFFFF);
2253
2254 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2255 SkIntToScalar(fImage->width()),
2256 SkIntToScalar(fImage->height())));
2257 this->execute(canvas);
2258 return true;
2259}
2260
ethannicholasf62a8b72016-02-11 10:35:21 -08002261Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2262 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002263 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002264 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002265 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002266 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002267 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002268 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002269 }
msarett0ac1bec2016-08-29 09:15:33 -07002270
2271 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2272 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2273 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2274 switch (fImage->alphaType()) {
2275 case kOpaque_SkAlphaType:
2276 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2277 break;
2278 case kPremul_SkAlphaType:
2279 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2280 break;
2281 case kUnpremul_SkAlphaType:
2282 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2283 break;
2284 default:
2285 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2286 break;
2287 }
ethannicholas50a8dd02016-02-10 05:40:46 -08002288 }
2289 return result;
2290}
2291
halcanary9d524f22016-03-29 09:03:52 -07002292SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002293 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002294 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002295 if (image == nullptr) {
2296 return nullptr;
2297 }
2298 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2299 SkPaint* paintPtr;
2300 SkPaint paint;
2301 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002302 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002303 paintPtr = &paint;
2304 }
2305 else {
2306 paintPtr = nullptr;
2307 }
reed9ce9d672016-03-17 10:51:11 -07002308 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002309 point[1].asFloat(), paintPtr);
ethannicholas50a8dd02016-02-10 05:40:46 -08002310 return result;
2311}
2312
Stan Ilievac42aeb2017-01-12 16:20:50 -05002313SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2314 const SkCanvas::Lattice& lattice,
2315 const SkRect& dst, const SkPaint* paint)
2316 : INHERITED(kDrawImageLattice_OpType)
2317 , fImage(SkRef(image))
2318 , fLattice(lattice)
2319 , fDst(dst) {
2320
Stan Ilievac42aeb2017-01-12 16:20:50 -05002321 if (paint) {
2322 fPaint.set(*paint);
Stan Ilievac42aeb2017-01-12 16:20:50 -05002323 }
2324}
2325
2326void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
2327 SkLatticeIter iter(fLattice, fDst);
2328 SkRect srcR, dstR;
2329 while (iter.next(&srcR, &dstR)) {
2330 canvas->legacy_drawImageRect(fImage.get(), &srcR, dstR,
2331 fPaint.getMaybeNull(), SkCanvas::kStrict_SrcRectConstraint);
2332 }
2333}
2334
2335bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2336 SkAutoCanvasRestore acr(canvas, true);
2337 canvas->clear(0xFFFFFFFF);
2338
2339 xlate_and_scale_to_bounds(canvas, fDst);
2340
2341 this->execute(canvas);
2342 return true;
2343}
2344
2345Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2346 Json::Value result = INHERITED::toJSON(urlDataManager);
2347 Json::Value encoded;
2348 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002349 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
Stan Ilievac42aeb2017-01-12 16:20:50 -05002350 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2351 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2352 if (fPaint.isValid()) {
2353 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2354 }
2355 }
2356
2357 SkString desc;
2358 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2359
2360 return result;
2361}
2362
Brian Osmanc25e2692018-03-12 10:57:28 -04002363SkDrawImageLatticeCommand* SkDrawImageLatticeCommand::fromJSON(Json::Value& command,
2364 UrlDataManager& urlDataManager) {
2365 SkDEBUGFAIL("Not implemented yet.");
2366 return nullptr;
2367}
2368
fmalita651c9202015-07-22 10:23:01 -07002369SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2370 const SkRect& dst, const SkPaint* paint,
2371 SkCanvas::SrcRectConstraint constraint)
2372 : INHERITED(kDrawImageRect_OpType)
2373 , fImage(SkRef(image))
2374 , fDst(dst)
2375 , fConstraint(constraint) {
2376
2377 if (src) {
2378 fSrc.set(*src);
2379 }
2380
2381 if (paint) {
2382 fPaint.set(*paint);
2383 }
2384}
2385
2386void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002387 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2388 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07002389}
2390
2391bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2392 SkAutoCanvasRestore acr(canvas, true);
2393 canvas->clear(0xFFFFFFFF);
2394
2395 xlate_and_scale_to_bounds(canvas, fDst);
2396
2397 this->execute(canvas);
2398 return true;
2399}
2400
ethannicholasf62a8b72016-02-11 10:35:21 -08002401Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2402 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002403 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002404 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002405 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
ethannicholas50a8dd02016-02-10 05:40:46 -08002406 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002407 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002408 }
brianosmanfad98562016-05-04 11:06:28 -07002409 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002410 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002411 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002412 }
2413 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2414 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2415 }
2416 }
reed67f62fa2016-06-29 11:36:34 -07002417
2418 SkString desc;
2419 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2420
ethannicholas50a8dd02016-02-10 05:40:46 -08002421 return result;
2422}
2423
halcanary9d524f22016-03-29 09:03:52 -07002424SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002425 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002426 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002427 if (image == nullptr) {
2428 return nullptr;
2429 }
2430 SkRect dst;
2431 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2432 SkPaint* paintPtr;
2433 SkPaint paint;
2434 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002435 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002436 paintPtr = &paint;
2437 }
2438 else {
2439 paintPtr = nullptr;
2440 }
2441 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002442 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002443 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2444 constraint = SkCanvas::kStrict_SrcRectConstraint;
2445 }
2446 else {
2447 constraint = SkCanvas::kFast_SrcRectConstraint;
2448 }
2449 SkRect* srcPtr;
2450 SkRect src;
2451 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2452 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2453 srcPtr = &src;
2454 }
2455 else {
2456 srcPtr = nullptr;
2457 }
reed9ce9d672016-03-17 10:51:11 -07002458 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
ethannicholas50a8dd02016-02-10 05:40:46 -08002459 constraint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002460 return result;
2461}
2462
Brian Osmanc25e2692018-03-12 10:57:28 -04002463SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
2464 const SkRect& dst, const SkPaint* paint)
2465 : INHERITED(kDrawImageNine_OpType)
2466 , fImage(SkRef(image))
2467 , fCenter(center)
2468 , fDst(dst) {
2469 if (paint) {
2470 fPaint = *paint;
2471 fPaintPtr = &fPaint;
2472 } else {
2473 fPaintPtr = nullptr;
2474 }
Brian Osmanc25e2692018-03-12 10:57:28 -04002475}
2476
2477void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
2478 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaintPtr);
2479}
2480
2481bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
2482 SkAutoCanvasRestore acr(canvas, true);
2483 canvas->clear(0xFFFFFFFF);
2484
2485 xlate_and_scale_to_bounds(canvas, fDst);
2486
2487 this->execute(canvas);
2488 return true;
2489}
2490
2491Json::Value SkDrawImageNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2492 Json::Value result = INHERITED::toJSON(urlDataManager);
2493 Json::Value encoded;
2494 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2495 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
2496 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
2497 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2498 if (fPaintPtr != nullptr) {
2499 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2500 }
2501 }
2502 return result;
2503}
2504
2505SkDrawImageNineCommand* SkDrawImageNineCommand::fromJSON(Json::Value& command,
2506 UrlDataManager& urlDataManager) {
2507 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2508 if (image == nullptr) {
2509 return nullptr;
2510 }
2511 SkIRect center;
2512 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2513 SkRect dst;
2514 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2515 SkPaint* paintPtr;
2516 SkPaint paint;
2517 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2518 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2519 paintPtr = &paint;
2520 } else {
2521 paintPtr = nullptr;
2522 }
2523 SkDrawImageNineCommand* result = new SkDrawImageNineCommand(image.get(), center, dst, paintPtr);
2524 return result;
2525}
2526
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002527SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002528 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002529 fOval = oval;
2530 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002531}
2532
fmalita8c89c522014-11-08 16:18:56 -08002533void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002534 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002535}
2536
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002537bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002538 canvas->clear(0xFFFFFFFF);
2539 canvas->save();
2540
2541 xlate_and_scale_to_bounds(canvas, fOval);
2542
2543 SkPaint p;
2544 p.setColor(SK_ColorBLACK);
2545 p.setStyle(SkPaint::kStroke_Style);
2546
2547 canvas->drawOval(fOval, p);
2548 canvas->restore();
2549
2550 return true;
2551}
2552
ethannicholasf62a8b72016-02-11 10:35:21 -08002553Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2554 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002555 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2556 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002557 return result;
2558}
2559
halcanary9d524f22016-03-29 09:03:52 -07002560SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002561 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002562 SkRect coords;
2563 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2564 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002565 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002566 return new SkDrawOvalCommand(coords, paint);
2567}
2568
bsalomonac3aa242016-08-19 11:25:19 -07002569SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2570 bool useCenter, const SkPaint& paint)
Brian Osmanc25e2692018-03-12 10:57:28 -04002571 : INHERITED(kDrawArc_OpType) {
bsalomonac3aa242016-08-19 11:25:19 -07002572 fOval = oval;
2573 fStartAngle = startAngle;
2574 fSweepAngle = sweepAngle;
2575 fUseCenter = useCenter;
2576 fPaint = paint;
bsalomonac3aa242016-08-19 11:25:19 -07002577}
2578
2579void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2580 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2581}
2582
2583bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2584 canvas->clear(0xFFFFFFFF);
2585 canvas->save();
2586
2587 xlate_and_scale_to_bounds(canvas, fOval);
2588
2589 SkPaint p;
2590 p.setColor(SK_ColorBLACK);
2591 p.setStyle(SkPaint::kStroke_Style);
2592
2593 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2594 canvas->restore();
2595
2596 return true;
2597}
2598
2599Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2600 Json::Value result = INHERITED::toJSON(urlDataManager);
2601 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2602 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2603 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2604 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2605 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2606 return result;
2607}
2608
2609SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2610 UrlDataManager& urlDataManager) {
2611 SkRect coords;
2612 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2613 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2614 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2615 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2616 SkPaint paint;
2617 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2618 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2619}
2620
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002621SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002622 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002623 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002624}
2625
fmalita8c89c522014-11-08 16:18:56 -08002626void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002627 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002628}
2629
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002630bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002631 canvas->clear(0xFFFFFFFF);
2632 canvas->drawPaint(fPaint);
2633 return true;
2634}
2635
ethannicholasf62a8b72016-02-11 10:35:21 -08002636Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2637 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002638 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002639 return result;
2640}
2641
halcanary9d524f22016-03-29 09:03:52 -07002642SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002643 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002644 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002645 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002646 return new SkDrawPaintCommand(paint);
2647}
2648
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002649SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002650 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002651 fPath = path;
2652 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002653}
2654
fmalita8c89c522014-11-08 16:18:56 -08002655void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002656 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002657}
2658
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002659bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002660 render_path(canvas, fPath);
2661 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002662}
2663
ethannicholasf62a8b72016-02-11 10:35:21 -08002664Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2665 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002666 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2667 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002668 return result;
2669}
2670
halcanary9d524f22016-03-29 09:03:52 -07002671SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002672 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002673 SkPath path;
2674 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2675 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002676 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002677 return new SkDrawPathCommand(path, paint);
2678}
2679
Brian Osmanc25e2692018-03-12 10:57:28 -04002680SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
2681 : INHERITED(kDrawRegion_OpType) {
2682 fRegion = region;
2683 fPaint = paint;
Brian Osmanc25e2692018-03-12 10:57:28 -04002684}
2685
2686void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
2687 canvas->drawRegion(fRegion, fPaint);
2688}
2689
2690bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
2691 render_region(canvas, fRegion);
2692 return true;
2693}
2694
2695Json::Value SkDrawRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
2696 Json::Value result = INHERITED::toJSON(urlDataManager);
2697 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
2698 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2699 return result;
2700}
2701
2702SkDrawRegionCommand* SkDrawRegionCommand::fromJSON(Json::Value& command,
2703 UrlDataManager& urlDataManager) {
2704 SkRegion region;
2705 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
2706 SkPaint paint;
2707 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2708 return new SkDrawRegionCommand(region, paint);
2709}
2710
fmalita160ebb22015-04-01 20:58:37 -07002711SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2712 const SkMatrix* matrix,
2713 const SkPaint* paint)
2714 : INHERITED(kBeginDrawPicture_OpType)
2715 , fPicture(SkRef(picture)) {
bsalomon49f085d2014-09-05 13:34:00 -07002716 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002717 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002718 }
fmalita160ebb22015-04-01 20:58:37 -07002719
bsalomon49f085d2014-09-05 13:34:00 -07002720 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002721 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002722 }
fmalita160ebb22015-04-01 20:58:37 -07002723}
2724
2725void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2726 if (fPaint.isValid()) {
2727 SkRect bounds = fPicture->cullRect();
2728 if (fMatrix.isValid()) {
2729 fMatrix.get()->mapRect(&bounds);
2730 }
2731 canvas->saveLayer(&bounds, fPaint.get());
2732 }
2733
2734 if (fMatrix.isValid()) {
2735 if (!fPaint.isValid()) {
2736 canvas->save();
2737 }
2738 canvas->concat(*fMatrix.get());
2739 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002740}
2741
fmalita160ebb22015-04-01 20:58:37 -07002742bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002743 canvas->clear(0xFFFFFFFF);
2744 canvas->save();
2745
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002746 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002747
robertphillips9b14f262014-06-04 05:40:44 -07002748 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002749
2750 canvas->restore();
2751
2752 return true;
2753}
2754
fmalita160ebb22015-04-01 20:58:37 -07002755SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2756 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2757
2758void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2759 if (fRestore) {
2760 canvas->restore();
2761 }
2762}
2763
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002764SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002765 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002766 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002767 fMode = mode;
2768 fCount = count;
2769 fPts = new SkPoint[count];
2770 memcpy(fPts, pts, count * sizeof(SkPoint));
2771 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002772}
2773
fmalita8c89c522014-11-08 16:18:56 -08002774void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002775 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002776}
2777
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002778bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002779 canvas->clear(0xFFFFFFFF);
2780 canvas->save();
2781
2782 SkRect bounds;
2783
2784 bounds.setEmpty();
2785 for (unsigned int i = 0; i < fCount; ++i) {
Mike Reed185ffe92018-01-08 17:09:54 -05002786 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002787 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002788
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002789 xlate_and_scale_to_bounds(canvas, bounds);
2790
2791 SkPaint p;
2792 p.setColor(SK_ColorBLACK);
2793 p.setStyle(SkPaint::kStroke_Style);
2794
2795 canvas->drawPoints(fMode, fCount, fPts, p);
2796 canvas->restore();
2797
2798 return true;
2799}
2800
ethannicholasf62a8b72016-02-11 10:35:21 -08002801Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2802 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002803 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2804 Json::Value points(Json::arrayValue);
2805 for (size_t i = 0; i < fCount; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002806 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002807 }
2808 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07002809 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002810 return result;
2811}
2812
halcanary9d524f22016-03-29 09:03:52 -07002813SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002814 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002815 SkCanvas::PointMode mode;
2816 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2817 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2818 mode = SkCanvas::kPoints_PointMode;
2819 }
2820 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2821 mode = SkCanvas::kLines_PointMode;
2822 }
2823 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2824 mode = SkCanvas::kPolygon_PointMode;
2825 }
2826 else {
2827 SkASSERT(false);
2828 return nullptr;
2829 }
2830 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2831 int count = (int) jsonPoints.size();
2832 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2833 for (int i = 0; i < count; i++) {
2834 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2835 }
2836 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002837 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002838 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2839 sk_free(points);
2840 return result;
2841}
2842
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002843SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002844 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002845 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002846 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002847
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002848 fText = new char[byteLength];
2849 memcpy(fText, text, byteLength);
2850 fByteLength = byteLength;
2851
2852 fPos = new SkPoint[numPts];
2853 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2854
2855 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002856}
2857
fmalita8c89c522014-11-08 16:18:56 -08002858void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002859 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002860}
2861
ethannicholasf62a8b72016-02-11 10:35:21 -08002862Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2863 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002864 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002865 ((const char*) fText) + fByteLength);
2866 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08002867 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2868 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002869 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002870 }
2871 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07002872 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002873 return result;
2874}
2875
halcanary9d524f22016-03-29 09:03:52 -07002876SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002877 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002878 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2879 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002880 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002881 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2882 int count = (int) coords.size();
2883 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2884 for (int i = 0; i < count; i++) {
2885 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2886 }
2887 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2888}
chudy@google.com902ebe52012-06-29 14:21:22 +00002889
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002890SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2891 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002892 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002893 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002894 size_t numPts = paint.countText(text, byteLength);
2895
2896 fText = new char[byteLength];
2897 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002898 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002899
2900 fXpos = new SkScalar[numPts];
2901 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2902
robertphillips@google.com91217d02013-03-17 18:33:46 +00002903 fConstY = constY;
2904 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002905}
2906
fmalita8c89c522014-11-08 16:18:56 -08002907void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002908 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002909}
2910
bungeman51190df2016-03-09 07:42:54 -08002911Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
2912 Json::Value result = INHERITED::toJSON(urlDataManager);
2913 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2914 ((const char*) fText) + fByteLength);
2915 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
2916 Json::Value xpos(Json::arrayValue);
2917 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2918 for (size_t i = 0; i < numXpos; i++) {
2919 xpos.append(Json::Value(fXpos[i]));
2920 }
2921 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07002922 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08002923 return result;
2924}
2925
2926SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
2927 UrlDataManager& urlDataManager) {
2928 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2929 SkPaint paint;
2930 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2931 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
2932 int count = (int) jsonXpos.size();
2933 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
2934 for (int i = 0; i < count; i++) {
2935 xpos[i] = jsonXpos[i].asFloat();
2936 }
2937 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
2938 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
2939}
2940
fmalita37283c22016-09-13 10:00:23 -07002941SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07002942 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002943 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07002944 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07002945 , fXPos(x)
2946 , fYPos(y)
Brian Osman255735e2018-04-06 14:51:42 -04002947 , fPaint(paint) {}
fmalitab7425172014-08-26 07:56:44 -07002948
fmalita8c89c522014-11-08 16:18:56 -08002949void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07002950 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
2951}
2952
fmalita55773872014-08-29 15:08:20 -07002953bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
2954 canvas->clear(SK_ColorWHITE);
2955 canvas->save();
2956
2957 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
2958 xlate_and_scale_to_bounds(canvas, bounds);
2959
fmalita37283c22016-09-13 10:00:23 -07002960 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07002961
2962 canvas->restore();
2963
2964 return true;
2965}
2966
ethannicholasf62a8b72016-02-11 10:35:21 -08002967Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
2968 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002969 Json::Value runs(Json::arrayValue);
2970 SkTextBlobRunIterator iter(fBlob.get());
2971 while (!iter.done()) {
2972 Json::Value run(Json::objectValue);
2973 Json::Value jsonPositions(Json::arrayValue);
2974 Json::Value jsonGlyphs(Json::arrayValue);
2975 const SkScalar* iterPositions = iter.pos();
2976 const uint16_t* iterGlyphs = iter.glyphs();
2977 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
2978 switch (iter.positioning()) {
2979 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07002980 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
2981 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002982 break;
2983 case SkTextBlob::kHorizontal_Positioning:
2984 jsonPositions.append(Json::Value(iterPositions[i]));
2985 break;
2986 case SkTextBlob::kDefault_Positioning:
2987 break;
2988 }
2989 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
2990 }
2991 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
2992 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
2993 }
2994 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
2995 SkPaint fontPaint;
2996 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07002997 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
2998 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08002999 runs.append(run);
3000 iter.next();
3001 }
reed6d2c3e72016-07-07 14:10:14 -07003002 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08003003 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
3004 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
3005 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07003006 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07003007 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07003008
3009 SkString desc;
3010 // make the bounds local by applying the x,y
3011 bounds.offset(fXPos, fYPos);
3012 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
3013
ethannicholas50a8dd02016-02-10 05:40:46 -08003014 return result;
3015}
3016
halcanary9d524f22016-03-29 09:03:52 -07003017SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003018 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003019 SkTextBlobBuilder builder;
3020 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
3021 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
3022 Json::Value run = runs[i];
3023 SkPaint font;
3024 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
ethannicholasf62a8b72016-02-11 10:35:21 -08003025 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
ethannicholas50a8dd02016-02-10 05:40:46 -08003026 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
3027 int count = glyphs.size();
3028 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3029 SkScalar x = coords[0].asFloat();
3030 SkScalar y = coords[1].asFloat();
reed6d2c3e72016-07-07 14:10:14 -07003031 SkRect bounds;
3032 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
3033
ethannicholas50a8dd02016-02-10 05:40:46 -08003034 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
3035 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3036 if (positions.size() > 0 && positions[0].isNumeric()) {
reed6d2c3e72016-07-07 14:10:14 -07003037 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003038 for (int j = 0; j < count; j++) {
3039 buffer.glyphs[j] = glyphs[j].asUInt();
3040 buffer.pos[j] = positions[j].asFloat();
3041 }
3042 }
3043 else {
reed6d2c3e72016-07-07 14:10:14 -07003044 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003045 for (int j = 0; j < count; j++) {
3046 buffer.glyphs[j] = glyphs[j].asUInt();
3047 buffer.pos[j * 2] = positions[j][0].asFloat();
3048 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
3049 }
3050 }
3051 }
3052 else {
reed6d2c3e72016-07-07 14:10:14 -07003053 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003054 for (int j = 0; j < count; j++) {
3055 buffer.glyphs[j] = glyphs[j].asUInt();
3056 }
3057 }
3058 }
3059 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
3060 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3061 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003062 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
fmalita37283c22016-09-13 10:00:23 -07003063 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003064}
3065
robertphillips9bafc302015-02-13 11:13:00 -08003066SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04003067 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08003068 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003069 : INHERITED(kDrawPatch_OpType)
3070 , fBlendMode(bmode)
3071{
robertphillips9bafc302015-02-13 11:13:00 -08003072 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08003073 if (colors != nullptr) {
3074 memcpy(fColors, colors, sizeof(fColors));
3075 fColorsPtr = fColors;
3076 } else {
3077 fColorsPtr = nullptr;
3078 }
3079 if (texCoords != nullptr) {
3080 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3081 fTexCoordsPtr = fTexCoords;
3082 } else {
3083 fTexCoordsPtr = nullptr;
3084 }
robertphillips9bafc302015-02-13 11:13:00 -08003085 fPaint = paint;
robertphillips9bafc302015-02-13 11:13:00 -08003086}
3087
3088void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04003089 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08003090}
3091
ethannicholasf62a8b72016-02-11 10:35:21 -08003092Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3093 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08003094 Json::Value cubics = Json::Value(Json::arrayValue);
3095 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003096 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003097 }
3098 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3099 if (fColorsPtr != nullptr) {
3100 Json::Value colors = Json::Value(Json::arrayValue);
3101 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003102 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003103 }
3104 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3105 }
3106 if (fTexCoordsPtr != nullptr) {
3107 Json::Value texCoords = Json::Value(Json::arrayValue);
3108 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003109 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003110 }
3111 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3112 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003113 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08003114 return result;
3115}
3116
halcanary9d524f22016-03-29 09:03:52 -07003117SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003118 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08003119 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3120 SkPoint cubics[12];
3121 for (int i = 0; i < 12; i++) {
3122 cubics[i] = get_json_point(jsonCubics[i]);
3123 }
3124 SkColor* colorsPtr;
3125 SkColor colors[4];
3126 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3127 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3128 for (int i = 0; i < 4; i++) {
3129 colors[i] = get_json_color(jsonColors[i]);
3130 }
3131 colorsPtr = colors;
3132 }
3133 else {
3134 colorsPtr = nullptr;
3135 }
3136 SkPoint* texCoordsPtr;
3137 SkPoint texCoords[4];
3138 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3139 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3140 for (int i = 0; i < 4; i++) {
3141 texCoords[i] = get_json_point(jsonTexCoords[i]);
3142 }
3143 texCoordsPtr = texCoords;
3144 }
3145 else {
3146 texCoordsPtr = nullptr;
3147 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003148
3149 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3150
ethannicholas1446a9a2016-02-10 14:05:02 -08003151 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003152 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04003153 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
robertphillips9bafc302015-02-13 11:13:00 -08003154}
3155
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003156SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003157 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003158 fRect = rect;
3159 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003160}
3161
fmalita8c89c522014-11-08 16:18:56 -08003162void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003163 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003164}
3165
ethannicholasf62a8b72016-02-11 10:35:21 -08003166Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3167 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07003168 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3169 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07003170
3171 SkString desc;
3172 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3173
ethannicholas50a8dd02016-02-10 05:40:46 -08003174 return result;
3175}
3176
halcanary9d524f22016-03-29 09:03:52 -07003177SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003178 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003179 SkRect coords;
3180 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3181 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003182 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003183 return new SkDrawRectCommand(coords, paint);
3184}
3185
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003186SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003187 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003188 fRRect = rrect;
3189 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00003190}
3191
fmalita8c89c522014-11-08 16:18:56 -08003192void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00003193 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00003194}
3195
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003196bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00003197 render_rrect(canvas, fRRect);
3198 return true;
3199}
3200
ethannicholasf62a8b72016-02-11 10:35:21 -08003201Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3202 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003203 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07003204 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003205 return result;
3206}
3207
halcanary9d524f22016-03-29 09:03:52 -07003208SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003209 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003210 SkRRect coords;
3211 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3212 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003213 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003214 return new SkDrawRRectCommand(coords, paint);
3215}
3216
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00003217SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003218 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003219 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003220 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003221 fOuter = outer;
3222 fInner = inner;
3223 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003224}
3225
fmalita8c89c522014-11-08 16:18:56 -08003226void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003227 canvas->drawDRRect(fOuter, fInner, fPaint);
3228}
3229
3230bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3231 render_drrect(canvas, fOuter, fInner);
3232 return true;
3233}
3234
ethannicholasf62a8b72016-02-11 10:35:21 -08003235Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3236 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003237 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3238 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07003239 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003240 return result;
3241}
3242
halcanary9d524f22016-03-29 09:03:52 -07003243SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003244 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003245 SkRRect outer;
3246 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3247 SkRRect inner;
3248 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3249 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003250 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003251 return new SkDrawDRRectCommand(outer, inner, paint);
3252}
3253
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04003254SkDrawShadowCommand::SkDrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
3255 : INHERITED(kDrawShadow_OpType) {
3256 fPath = path;
3257 fShadowRec = rec;
3258}
3259
3260void SkDrawShadowCommand::execute(SkCanvas* canvas) const {
3261 canvas->private_draw_shadow_rec(fPath, fShadowRec);
3262}
3263
3264bool SkDrawShadowCommand::render(SkCanvas* canvas) const {
3265 render_shadow(canvas, fPath, fShadowRec);
3266 return true;
3267}
3268
3269Json::Value SkDrawShadowCommand::toJSON(UrlDataManager& urlDataManager) const {
3270 Json::Value result = INHERITED::toJSON(urlDataManager);
3271 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3272
3273 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
3274 bool transparentOccluder =
3275 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
3276
3277 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
3278 result[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE] = MakeJsonPoint3(fShadowRec.fZPlaneParams);
3279 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION] = MakeJsonPoint3(fShadowRec.fLightPos);
3280 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS] = MakeJsonScalar(fShadowRec.fLightRadius);
3281 result[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR] = MakeJsonColor(fShadowRec.fAmbientColor);
3282 result[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR] = MakeJsonColor(fShadowRec.fSpotColor);
3283 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
3284 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
3285 return result;
3286}
3287
3288SkDrawShadowCommand* SkDrawShadowCommand::fromJSON(Json::Value& command,
3289 UrlDataManager& urlDataManager) {
3290 SkPath path;
3291 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3292 SkDrawShadowRec rec;
3293 rec.fZPlaneParams = get_json_point3(command[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE]);
3294 rec.fLightPos = get_json_point3(command[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION]);
3295 rec.fLightRadius = command[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS].asFloat();
3296 rec.fAmbientColor = get_json_color(command[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR]);
3297 rec.fSpotColor = get_json_color(command[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR]);
3298
3299 rec.fFlags = SkShadowFlags::kNone_ShadowFlag;
3300 if (command.isMember(SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC)
3301 && command[SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC].asBool()) {
3302 rec.fFlags |= SkShadowFlags::kTransparentOccluder_ShadowFlag;
3303 }
3304 if (command.isMember(SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY)
3305 && command[SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY].asBool()) {
3306 rec.fFlags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
3307 }
3308 return new SkDrawShadowCommand(path, rec);
3309}
3310
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003311SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003312 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003313 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003314 fText = new char[byteLength];
3315 memcpy(fText, text, byteLength);
3316 fByteLength = byteLength;
3317 fX = x;
3318 fY = y;
3319 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003320}
3321
fmalita8c89c522014-11-08 16:18:56 -08003322void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003323 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003324}
3325
ethannicholasf62a8b72016-02-11 10:35:21 -08003326Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3327 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003328 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003329 ((const char*) fText) + fByteLength);
3330 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003331 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3332 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003333 return result;
3334}
3335
halcanary9d524f22016-03-29 09:03:52 -07003336SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003337 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003338 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3339 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003340 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003341 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
halcanary9d524f22016-03-29 09:03:52 -07003342 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08003343 paint);
3344}
3345
reed45561a02016-07-07 12:47:17 -07003346///////////////////////////////////////////////////////////////////////////////////////////////////
3347
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003348SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3349 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003350 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003351 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003352 fText = new char[byteLength];
3353 memcpy(fText, text, byteLength);
3354 fByteLength = byteLength;
3355 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07003356 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003357 fMatrix = *matrix;
3358 } else {
3359 fMatrix.setIdentity();
3360 }
3361 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003362}
3363
fmalita8c89c522014-11-08 16:18:56 -08003364void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003365 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07003366 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003367 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003368}
3369
ethannicholasf62a8b72016-02-11 10:35:21 -08003370Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3371 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003372 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003373 ((const char*) fText) + fByteLength);
3374 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003375 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08003376 if (!fMatrix.isIdentity()) {
joshualittbd724132016-03-03 11:39:38 -08003377 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003378 }
brianosmanfad98562016-05-04 11:06:28 -07003379 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003380 return result;
3381}
3382
halcanary9d524f22016-03-29 09:03:52 -07003383SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003384 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003385 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3386 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003387 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003388 SkPath path;
3389 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3390 SkMatrix* matrixPtr;
3391 SkMatrix matrix;
3392 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3393 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3394 matrixPtr = &matrix;
3395 }
3396 else {
3397 matrixPtr = nullptr;
3398 }
3399 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3400}
3401
reed45561a02016-07-07 12:47:17 -07003402///////////////////////////////////////////////////////////////////////////////////////////////////
3403
3404SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3405 const SkRSXform xform[], const SkRect* cull,
3406 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07003407 : INHERITED(kDrawTextRSXform_OpType)
reed45561a02016-07-07 12:47:17 -07003408{
3409 fText = new char[byteLength];
3410 memcpy(fText, text, byteLength);
3411 fByteLength = byteLength;
3412 int count = paint.countText(text, byteLength);
3413 fXform = new SkRSXform[count];
3414 memcpy(fXform, xform, count * sizeof(SkRSXform));
3415 if (cull) {
3416 fCullStorage = *cull;
3417 fCull = &fCullStorage;
3418 } else {
3419 fCull = nullptr;
3420 }
3421 fPaint = paint;
reed45561a02016-07-07 12:47:17 -07003422}
3423
3424void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3425 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3426}
3427
3428Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3429 Json::Value result = INHERITED::toJSON(urlDataManager);
3430 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3431 ((const char*) fText) + fByteLength);
3432 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3433 return result;
3434}
3435
3436SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3437 UrlDataManager& urlDataManager) {
3438 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3439 size_t byteLength = strlen(text);
3440 SkPaint paint;
3441 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3442
3443 // TODO: handle xform and cull
3444 int count = paint.countText(text, byteLength);
3445 SkAutoTArray<SkRSXform> xform(count);
3446 for (int i = 0; i < count; ++i) {
3447 xform[i].fSCos = 1;
3448 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3449 }
3450 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3451}
3452
3453///////////////////////////////////////////////////////////////////////////////////////////////////
3454
Mike Reedfed9cfd2017-03-17 12:09:04 -04003455SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003456 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003457 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003458 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04003459 , fBlendMode(bmode)
Brian Osman255735e2018-04-06 14:51:42 -04003460 , fPaint(paint) {}
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003461
fmalita8c89c522014-11-08 16:18:56 -08003462void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04003463 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003464}
3465
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003466SkRestoreCommand::SkRestoreCommand()
Brian Osman255735e2018-04-06 14:51:42 -04003467 : INHERITED(kRestore_OpType) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00003468
fmalita8c89c522014-11-08 16:18:56 -08003469void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00003470 canvas->restore();
3471}
3472
ethannicholasf62a8b72016-02-11 10:35:21 -08003473SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003474 return new SkRestoreCommand();
3475}
3476
Florin Malita5f6102d2014-06-30 10:13:28 -04003477SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003478 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00003479}
3480
fmalita8c89c522014-11-08 16:18:56 -08003481void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04003482 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00003483}
3484
ethannicholasf62a8b72016-02-11 10:35:21 -08003485SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003486 return new SkSaveCommand();
3487}
3488
reed4960eee2015-12-18 07:09:18 -08003489SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08003490 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08003491 if (rec.fBounds) {
3492 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003493 } else {
3494 fBounds.setEmpty();
3495 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003496
reed4960eee2015-12-18 07:09:18 -08003497 if (rec.fPaint) {
3498 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003499 fPaintPtr = &fPaint;
3500 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07003501 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003502 }
reed4960eee2015-12-18 07:09:18 -08003503 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003504
ethannicholas50a8dd02016-02-10 05:40:46 -08003505 if (rec.fBackdrop) {
3506 fBackdrop = rec.fBackdrop;
3507 fBackdrop->ref();
3508 } else {
3509 fBackdrop = nullptr;
3510 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003511}
3512
ethannicholas50a8dd02016-02-10 05:40:46 -08003513SkSaveLayerCommand::~SkSaveLayerCommand() {
3514 if (fBackdrop != nullptr) {
3515 fBackdrop->unref();
3516 }
3517}
3518
fmalita8c89c522014-11-08 16:18:56 -08003519void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08003520 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3521 fPaintPtr,
3522 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003523}
3524
ethannicholasf62a8b72016-02-11 10:35:21 -08003525Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3526 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003527 if (!fBounds.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07003528 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003529 }
3530 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07003531 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
ethannicholasf62a8b72016-02-11 10:35:21 -08003532 urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003533 }
3534 if (fBackdrop != nullptr) {
3535 Json::Value jsonBackdrop;
ethannicholasf62a8b72016-02-11 10:35:21 -08003536 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003537 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3538 }
3539 if (fSaveLayerFlags != 0) {
3540 SkDebugf("unsupported: saveLayer flags\n");
3541 SkASSERT(false);
3542 }
3543 return result;
3544}
3545
halcanary9d524f22016-03-29 09:03:52 -07003546SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003547 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003548 SkCanvas::SaveLayerRec rec;
3549 SkRect bounds;
3550 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3551 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3552 rec.fBounds = &bounds;
3553 }
3554 SkPaint paint;
3555 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08003556 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003557 rec.fPaint = &paint;
3558 }
3559 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3560 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
ethannicholasf62a8b72016-02-11 10:35:21 -08003561 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003562 }
3563 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3564 if (rec.fBackdrop != nullptr) {
3565 rec.fBackdrop->unref();
3566 }
3567 return result;
3568}
3569
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003570SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08003571 : INHERITED(kSetMatrix_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003572 fMatrix = matrix;
robertphillips70171682014-10-16 14:28:28 -07003573}
3574
fmalita8c89c522014-11-08 16:18:56 -08003575void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
Brian Osman255735e2018-04-06 14:51:42 -04003576 canvas->setMatrix(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00003577}
3578
ethannicholasf62a8b72016-02-11 10:35:21 -08003579Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3580 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08003581 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003582 return result;
3583}
3584
halcanary9d524f22016-03-29 09:03:52 -07003585SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003586 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003587 SkMatrix matrix;
3588 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3589 return new SkSetMatrixCommand(matrix);
3590}