blob: 076dac57a555520c38d06575a651c76b8e1a7f88 [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"
chudy@google.com902ebe52012-06-29 14:21:22 +000018#include "SkObjectParser.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080019#include "SkPaintDefaults.h"
20#include "SkPathEffect.h"
robertphillips9bafc302015-02-13 11:13:00 -080021#include "SkPicture.h"
Mike Reedfadbfcd2017-12-06 16:09:20 -050022#include "SkReadBuffer.h"
Mike Reed185ffe92018-01-08 17:09:54 -050023#include "SkRectPriv.h"
fmalitab7425172014-08-26 07:56:44 -070024#include "SkTextBlob.h"
fmalitae77f2da2015-12-08 18:59:18 -080025#include "SkTextBlobRunIterator.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080026#include "SkTHash.h"
27#include "SkTypeface.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080028#include "SkWriteBuffer.h"
msaretta5cf4f42016-06-30 10:06:51 -070029#include "picture_utils.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050030#include "SkClipOpPriv.h"
Stan Ilievac42aeb2017-01-12 16:20:50 -050031#include <SkLatticeIter.h>
ethannicholas50a8dd02016-02-10 05:40:46 -080032
ethannicholas50a8dd02016-02-10 05:40:46 -080033#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
ethannicholas807dcab2016-02-23 06:53:37 -080034#define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
ethannicholas50a8dd02016-02-10 05:40:46 -080035#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
vjiaoblacke5de1302016-07-13 14:05:28 -070036#define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
ethannicholas50a8dd02016-02-10 05:40:46 -080037#define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
halcanaryf412f092016-08-25 11:10:41 -070038#define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
ethannicholas50a8dd02016-02-10 05:40:46 -080039#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
40#define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
41#define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
42#define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
43#define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
44#define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
45#define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
46#define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
47#define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
48#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Florin Malita82d80872017-06-06 16:58:40 -040049#define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
ethannicholas50a8dd02016-02-10 05:40:46 -080050#define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
51#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
52#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
ethannicholas1446a9a2016-02-10 14:05:02 -080053#define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
ethannicholas50a8dd02016-02-10 05:40:46 -080054#define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
55#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
ethannicholas1446a9a2016-02-10 14:05:02 -080056#define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
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"
reed67f62fa2016-06-29 11:36:34 -0700124
ethannicholas50a8dd02016-02-10 05:40:46 -0800125#define SKDEBUGCANVAS_VERB_MOVE "move"
126#define SKDEBUGCANVAS_VERB_LINE "line"
127#define SKDEBUGCANVAS_VERB_QUAD "quad"
128#define SKDEBUGCANVAS_VERB_CUBIC "cubic"
129#define SKDEBUGCANVAS_VERB_CONIC "conic"
130#define SKDEBUGCANVAS_VERB_CLOSE "close"
131
132#define SKDEBUGCANVAS_STYLE_FILL "fill"
133#define SKDEBUGCANVAS_STYLE_STROKE "stroke"
134#define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
135
136#define SKDEBUGCANVAS_POINTMODE_POINTS "points"
137#define SKDEBUGCANVAS_POINTMODE_LINES "lines"
138#define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
139
140#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
141#define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
142#define SKDEBUGCANVAS_REGIONOP_UNION "union"
143#define SKDEBUGCANVAS_REGIONOP_XOR "xor"
144#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
145#define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
146
147#define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
148#define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
149#define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
150#define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
151
152#define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
153#define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
154
155#define SKDEBUGCANVAS_ALIGN_LEFT "left"
156#define SKDEBUGCANVAS_ALIGN_CENTER "center"
157#define SKDEBUGCANVAS_ALIGN_RIGHT "right"
158
159#define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
160#define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
161#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
162#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
163
164#define SKDEBUGCANVAS_CAP_BUTT "butt"
165#define SKDEBUGCANVAS_CAP_ROUND "round"
166#define SKDEBUGCANVAS_CAP_SQUARE "square"
167
ethannicholas1446a9a2016-02-10 14:05:02 -0800168#define SKDEBUGCANVAS_MITER_JOIN "miter"
169#define SKDEBUGCANVAS_ROUND_JOIN "round"
170#define SKDEBUGCANVAS_BEVEL_JOIN "bevel"
171
ethannicholas50a8dd02016-02-10 05:40:46 -0800172#define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
173#define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
174#define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
175#define SKDEBUGCANVAS_COLORTYPE_565 "565"
176#define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
177#define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
178#define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
179
180#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
181#define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
182#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
msarett0ac1bec2016-08-29 09:15:33 -0700183#define SKDEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
ethannicholas50a8dd02016-02-10 05:40:46 -0800184
ethannicholas1446a9a2016-02-10 14:05:02 -0800185#define SKDEBUGCANVAS_FILTERQUALITY_NONE "none"
186#define SKDEBUGCANVAS_FILTERQUALITY_LOW "low"
187#define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
188#define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high"
189
halcanaryf412f092016-08-25 11:10:41 -0700190#define SKDEBUGCANVAS_HINTING_NONE "none"
191#define SKDEBUGCANVAS_HINTING_SLIGHT "slight"
192#define SKDEBUGCANVAS_HINTING_NORMAL "normal"
193#define SKDEBUGCANVAS_HINTING_FULL "full"
194
ethannicholasf62a8b72016-02-11 10:35:21 -0800195typedef SkDrawCommand* (*FROM_JSON)(Json::Value&, UrlDataManager&);
fmalitab7425172014-08-26 07:56:44 -0700196
reed67f62fa2016-06-29 11:36:34 -0700197static SkString* str_append(SkString* str, const SkRect& r) {
198 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
199 return str;
200}
201
chudy@google.com902ebe52012-06-29 14:21:22 +0000202// TODO(chudy): Refactor into non subclass model.
203
robertphillips9bafc302015-02-13 11:13:00 -0800204SkDrawCommand::SkDrawCommand(OpType type)
205 : fOpType(type)
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000206 , fVisible(true) {
207}
208
chudy@google.com902ebe52012-06-29 14:21:22 +0000209SkDrawCommand::~SkDrawCommand() {
chudy@google.com97cee972012-08-07 20:41:37 +0000210 fInfo.deleteAll();
chudy@google.com902ebe52012-06-29 14:21:22 +0000211}
212
robertphillips9bafc302015-02-13 11:13:00 -0800213const char* SkDrawCommand::GetCommandString(OpType type) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000214 switch (type) {
fmalita160ebb22015-04-01 20:58:37 -0700215 case kBeginDrawPicture_OpType: return "BeginDrawPicture";
Brian Osmanc25e2692018-03-12 10:57:28 -0400216 case kClear_OpType: return "DrawClear";
robertphillips9bafc302015-02-13 11:13:00 -0800217 case kClipPath_OpType: return "ClipPath";
218 case kClipRegion_OpType: return "ClipRegion";
219 case kClipRect_OpType: return "ClipRect";
220 case kClipRRect_OpType: return "ClipRRect";
robertphillips9bafc302015-02-13 11:13:00 -0800221 case kConcat_OpType: return "Concat";
robertphillipsfb409232016-06-29 10:28:11 -0700222 case kDrawAnnotation_OpType: return "DrawAnnotation";
robertphillips9bafc302015-02-13 11:13:00 -0800223 case kDrawBitmap_OpType: return "DrawBitmap";
224 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
225 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
robertphillips9bafc302015-02-13 11:13:00 -0800226 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700227 case kDrawImage_OpType: return "DrawImage";
Stan Ilievac42aeb2017-01-12 16:20:50 -0500228 case kDrawImageLattice_OpType: return "DrawImageLattice";
Brian Osmanc25e2692018-03-12 10:57:28 -0400229 case kDrawImageNine_OpType: return "DrawImageNine";
fmalita651c9202015-07-22 10:23:01 -0700230 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800231 case kDrawOval_OpType: return "DrawOval";
232 case kDrawPaint_OpType: return "DrawPaint";
233 case kDrawPatch_OpType: return "DrawPatch";
234 case kDrawPath_OpType: return "DrawPath";
Brian Osmanc25e2692018-03-12 10:57:28 -0400235 case kDrawArc_OpType: return "DrawArc";
robertphillips9bafc302015-02-13 11:13:00 -0800236 case kDrawPoints_OpType: return "DrawPoints";
237 case kDrawPosText_OpType: return "DrawPosText";
238 case kDrawPosTextH_OpType: return "DrawPosTextH";
239 case kDrawRect_OpType: return "DrawRect";
240 case kDrawRRect_OpType: return "DrawRRect";
Brian Osmanc25e2692018-03-12 10:57:28 -0400241 case kDrawRegion_OpType: return "DrawRegion";
robertphillips9bafc302015-02-13 11:13:00 -0800242 case kDrawText_OpType: return "DrawText";
243 case kDrawTextBlob_OpType: return "DrawTextBlob";
244 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
reed63f30d92016-07-07 16:32:51 -0700245 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
robertphillips9bafc302015-02-13 11:13:00 -0800246 case kDrawVertices_OpType: return "DrawVertices";
fmalita160ebb22015-04-01 20:58:37 -0700247 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800248 case kRestore_OpType: return "Restore";
249 case kSave_OpType: return "Save";
250 case kSaveLayer_OpType: return "SaveLayer";
251 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000252 default:
robertphillips9bafc302015-02-13 11:13:00 -0800253 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000254 SkASSERT(0);
255 break;
256 }
257 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700258 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000259}
260
fmalita8c89c522014-11-08 16:18:56 -0800261SkString SkDrawCommand::toString() const {
robertphillips9bafc302015-02-13 11:13:00 -0800262 return SkString(GetCommandString(fOpType));
chudy@google.com902ebe52012-06-29 14:21:22 +0000263}
264
ethannicholasf62a8b72016-02-11 10:35:21 -0800265Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800266 Json::Value result;
267 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800268 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800269 return result;
270}
271
272#define INSTALL_FACTORY(name) factories.set(SkString(GetCommandString(k ## name ##_OpType)), \
273 (FROM_JSON) Sk ## name ## Command::fromJSON)
ethannicholasf62a8b72016-02-11 10:35:21 -0800274SkDrawCommand* SkDrawCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800275 static SkTHashMap<SkString, FROM_JSON> factories;
276 static bool initialized = false;
277 if (!initialized) {
278 initialized = true;
279 INSTALL_FACTORY(Restore);
Brian Osmanc25e2692018-03-12 10:57:28 -0400280 INSTALL_FACTORY(Clear);
ethannicholas50a8dd02016-02-10 05:40:46 -0800281 INSTALL_FACTORY(ClipPath);
282 INSTALL_FACTORY(ClipRegion);
283 INSTALL_FACTORY(ClipRect);
284 INSTALL_FACTORY(ClipRRect);
285 INSTALL_FACTORY(Concat);
reed97660cc2016-06-28 18:54:19 -0700286 INSTALL_FACTORY(DrawAnnotation);
ethannicholas50a8dd02016-02-10 05:40:46 -0800287 INSTALL_FACTORY(DrawBitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800288 INSTALL_FACTORY(DrawBitmapNine);
Brian Osmanc25e2692018-03-12 10:57:28 -0400289 INSTALL_FACTORY(DrawBitmapRect);
ethannicholas50a8dd02016-02-10 05:40:46 -0800290 INSTALL_FACTORY(DrawImage);
Brian Osmanc25e2692018-03-12 10:57:28 -0400291 INSTALL_FACTORY(DrawImageLattice);
292 INSTALL_FACTORY(DrawImageNine);
ethannicholas50a8dd02016-02-10 05:40:46 -0800293 INSTALL_FACTORY(DrawImageRect);
294 INSTALL_FACTORY(DrawOval);
Brian Osmanc25e2692018-03-12 10:57:28 -0400295 INSTALL_FACTORY(DrawArc);
ethannicholas50a8dd02016-02-10 05:40:46 -0800296 INSTALL_FACTORY(DrawPaint);
297 INSTALL_FACTORY(DrawPath);
298 INSTALL_FACTORY(DrawPoints);
Brian Osmanc25e2692018-03-12 10:57:28 -0400299 INSTALL_FACTORY(DrawRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -0800300 INSTALL_FACTORY(DrawText);
301 INSTALL_FACTORY(DrawPosText);
bungeman51190df2016-03-09 07:42:54 -0800302 INSTALL_FACTORY(DrawPosTextH);
ethannicholas50a8dd02016-02-10 05:40:46 -0800303 INSTALL_FACTORY(DrawTextOnPath);
reed45561a02016-07-07 12:47:17 -0700304 INSTALL_FACTORY(DrawTextRSXform);
ethannicholas50a8dd02016-02-10 05:40:46 -0800305 INSTALL_FACTORY(DrawTextBlob);
306
307 INSTALL_FACTORY(DrawRect);
308 INSTALL_FACTORY(DrawRRect);
309 INSTALL_FACTORY(DrawDRRect);
ethannicholas1446a9a2016-02-10 14:05:02 -0800310 INSTALL_FACTORY(DrawPatch);
ethannicholas50a8dd02016-02-10 05:40:46 -0800311 INSTALL_FACTORY(Save);
312 INSTALL_FACTORY(SaveLayer);
313 INSTALL_FACTORY(SetMatrix);
314 }
315 SkString name = SkString(command[SKDEBUGCANVAS_ATTRIBUTE_COMMAND].asCString());
316 FROM_JSON* factory = factories.find(name);
317 if (factory == nullptr) {
318 SkDebugf("no JSON factory for '%s'\n", name.c_str());
319 return nullptr;
320 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800321 return (*factory)(command, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800322}
323
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000324namespace {
325
326void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500327 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000328
329 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
330
331 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
332 if (bounds.width() > bounds.height()) {
333 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
334 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
335 } else {
336 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
337 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
338 }
339 canvas->translate(-bounds.centerX(), -bounds.centerY());
340}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000341
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000342
343void render_path(SkCanvas* canvas, const SkPath& path) {
344 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000345
346 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700347 if (bounds.isEmpty()) {
348 return;
349 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000350
fmalitab0cd8b72015-10-06 07:24:03 -0700351 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000352 xlate_and_scale_to_bounds(canvas, bounds);
353
354 SkPaint p;
355 p.setColor(SK_ColorBLACK);
356 p.setStyle(SkPaint::kStroke_Style);
357
358 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000359}
360
Brian Osmanc25e2692018-03-12 10:57:28 -0400361void render_region(SkCanvas* canvas, const SkRegion& region) {
362 canvas->clear(0xFFFFFFFF);
363
364 const SkIRect& bounds = region.getBounds();
365 if (bounds.isEmpty()) {
366 return;
367 }
368
369 SkAutoCanvasRestore acr(canvas, true);
Brian Osman99b63402018-03-13 10:19:27 -0400370 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
Brian Osmanc25e2692018-03-12 10:57:28 -0400371
372 SkPaint p;
373 p.setColor(SK_ColorBLACK);
374 p.setStyle(SkPaint::kStroke_Style);
375
376 canvas->drawRegion(region, p);
377}
378
halcanary96fcdcc2015-08-27 07:41:13 -0700379void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500380 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000381
382 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
383 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
384
385 if (input.width() > input.height()) {
386 yScale *= input.height() / (float) input.width();
387 } else {
388 xScale *= input.width() / (float) input.height();
389 }
390
391 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
392 xScale * input.width(),
393 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000394
robertphillips96a5cff2015-09-24 06:56:27 -0700395 static const int kNumBlocks = 8;
396
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000397 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700398 SkISize block = {
399 canvas->imageInfo().width()/kNumBlocks,
400 canvas->imageInfo().height()/kNumBlocks
401 };
402 for (int y = 0; y < kNumBlocks; ++y) {
403 for (int x = 0; x < kNumBlocks; ++x) {
404 SkPaint paint;
405 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
406 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
407 SkIntToScalar(y*block.height()),
408 SkIntToScalar(block.width()),
409 SkIntToScalar(block.height()));
410 canvas->drawRect(r, paint);
411 }
412 }
413
reede47829b2015-08-06 10:02:53 -0700414 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000415
bsalomon49f085d2014-09-05 13:34:00 -0700416 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000417 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
418 srcRect->fTop * yScale + SK_Scalar1,
419 srcRect->fRight * xScale + SK_Scalar1,
420 srcRect->fBottom * yScale + SK_Scalar1);
421 SkPaint p;
422 p.setColor(SK_ColorRED);
423 p.setStyle(SkPaint::kStroke_Style);
424
425 canvas->drawRect(r, p);
426 }
427}
428
429void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
430 canvas->clear(0xFFFFFFFF);
431 canvas->save();
432
433 const SkRect& bounds = rrect.getBounds();
434
435 xlate_and_scale_to_bounds(canvas, bounds);
436
437 SkPaint p;
438 p.setColor(SK_ColorBLACK);
439 p.setStyle(SkPaint::kStroke_Style);
440
441 canvas->drawRRect(rrect, p);
442 canvas->restore();
443}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000444
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000445void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
446 canvas->clear(0xFFFFFFFF);
447 canvas->save();
448
449 const SkRect& bounds = outer.getBounds();
450
451 xlate_and_scale_to_bounds(canvas, bounds);
452
453 SkPaint p;
454 p.setColor(SK_ColorBLACK);
455 p.setStyle(SkPaint::kStroke_Style);
456
457 canvas->drawDRRect(outer, inner, p);
458 canvas->restore();
459}
460
Florin Malita82d80872017-06-06 16:58:40 -0400461static const char* const gBlendModeMap[] = {
462 "clear",
463 "src",
464 "dst",
465 "srcOver",
466 "dstOver",
467 "srcIn",
468 "dstIn",
469 "srcOut",
470 "dstOut",
471 "srcATop",
472 "dstATop",
473 "xor",
474 "plus",
475 "modulate",
476
477 "screen",
478
479 "overlay",
480 "darken",
481 "lighten",
482 "colorDodge",
483 "colorBurn",
484 "hardLight",
485 "softLight",
486 "difference",
487 "exclusion",
488 "multiply",
489
490 "hue",
491 "saturation",
492 "color",
493 "luminosity",
494};
495
496static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
497 "blendMode mismatch");
498static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
499 "blendMode mismatch");
500
501void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
502 const auto mode = paint.getBlendMode();
503 if (mode != SkBlendMode::kSrcOver) {
504 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
505 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
506 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
507 }
508}
509
510void extract_json_paint_blend_mode(Json::Value& jsonPaint, SkPaint* target) {
511 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE)) {
512 const char* mode = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE].asCString();
513
514 for (size_t i = 0; i < SK_ARRAY_COUNT(gBlendModeMap); ++i) {
515 if (!strcmp(mode, gBlendModeMap[i])) {
516 target->setBlendMode(static_cast<SkBlendMode>(i));
517 break;
518 }
519 }
520 }
521}
522
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000523};
524
brianosmanfad98562016-05-04 11:06:28 -0700525Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800526 Json::Value result(Json::arrayValue);
527 result.append(Json::Value(SkColorGetA(color)));
528 result.append(Json::Value(SkColorGetR(color)));
529 result.append(Json::Value(SkColorGetG(color)));
530 result.append(Json::Value(SkColorGetB(color)));
531 return result;
532}
533
brianosman97bbf822016-09-25 13:15:58 -0700534Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
535 Json::Value result(Json::arrayValue);
536 result.append(Json::Value(color.fA));
537 result.append(Json::Value(color.fR));
538 result.append(Json::Value(color.fG));
539 result.append(Json::Value(color.fB));
540 return result;
541}
542
brianosmanfad98562016-05-04 11:06:28 -0700543Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800544 Json::Value result(Json::arrayValue);
545 result.append(Json::Value(point.x()));
546 result.append(Json::Value(point.y()));
547 return result;
548}
549
brianosmanfad98562016-05-04 11:06:28 -0700550Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800551 Json::Value result(Json::arrayValue);
552 result.append(Json::Value(x));
553 result.append(Json::Value(y));
554 return result;
555}
556
brianosmanfad98562016-05-04 11:06:28 -0700557Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800558 Json::Value result(Json::arrayValue);
559 result.append(Json::Value(rect.left()));
560 result.append(Json::Value(rect.top()));
561 result.append(Json::Value(rect.right()));
562 result.append(Json::Value(rect.bottom()));
563 return result;
564}
565
joshualittbd724132016-03-03 11:39:38 -0800566Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800567 Json::Value result(Json::arrayValue);
568 result.append(Json::Value(rect.left()));
569 result.append(Json::Value(rect.top()));
570 result.append(Json::Value(rect.right()));
571 result.append(Json::Value(rect.bottom()));
572 return result;
573}
574
575static Json::Value make_json_rrect(const SkRRect& rrect) {
576 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700577 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
578 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
579 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
580 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
581 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800582 return result;
583}
584
joshualittbd724132016-03-03 11:39:38 -0800585Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800586 Json::Value result(Json::arrayValue);
587 Json::Value row1(Json::arrayValue);
588 row1.append(Json::Value(matrix[0]));
589 row1.append(Json::Value(matrix[1]));
590 row1.append(Json::Value(matrix[2]));
591 result.append(row1);
592 Json::Value row2(Json::arrayValue);
593 row2.append(Json::Value(matrix[3]));
594 row2.append(Json::Value(matrix[4]));
595 row2.append(Json::Value(matrix[5]));
596 result.append(row2);
597 Json::Value row3(Json::arrayValue);
598 row3.append(Json::Value(matrix[6]));
599 row3.append(Json::Value(matrix[7]));
600 row3.append(Json::Value(matrix[8]));
601 result.append(row3);
602 return result;
603}
ethannicholas1446a9a2016-02-10 14:05:02 -0800604
vjiaoblacke5de1302016-07-13 14:05:28 -0700605Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
606 Json::Value result(z);
607 return result;
608}
609
brianosmanfad98562016-05-04 11:06:28 -0700610Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800611 Json::Value result(Json::objectValue);
612 switch (path.getFillType()) {
613 case SkPath::kWinding_FillType:
614 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
615 break;
616 case SkPath::kEvenOdd_FillType:
617 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
618 break;
619 case SkPath::kInverseWinding_FillType:
620 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
621 break;
622 case SkPath::kInverseEvenOdd_FillType:
623 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
624 break;
halcanary9d524f22016-03-29 09:03:52 -0700625 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800626 Json::Value verbs(Json::arrayValue);
627 SkPath::Iter iter(path, false);
628 SkPoint pts[4];
629 SkPath::Verb verb;
630 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
631 switch (verb) {
632 case SkPath::kLine_Verb: {
633 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700634 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800635 verbs.append(line);
636 break;
637 }
638 case SkPath::kQuad_Verb: {
639 Json::Value quad(Json::objectValue);
640 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700641 coords.append(MakeJsonPoint(pts[1]));
642 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800643 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
644 verbs.append(quad);
645 break;
646 }
647 case SkPath::kCubic_Verb: {
648 Json::Value cubic(Json::objectValue);
649 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700650 coords.append(MakeJsonPoint(pts[1]));
651 coords.append(MakeJsonPoint(pts[2]));
652 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800653 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
654 verbs.append(cubic);
655 break;
656 }
657 case SkPath::kConic_Verb: {
658 Json::Value conic(Json::objectValue);
659 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700660 coords.append(MakeJsonPoint(pts[1]));
661 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800662 coords.append(Json::Value(iter.conicWeight()));
663 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
664 verbs.append(conic);
665 break;
666 }
667 case SkPath::kMove_Verb: {
668 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700669 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800670 verbs.append(move);
671 break;
672 }
673 case SkPath::kClose_Verb:
674 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
675 break;
676 case SkPath::kDone_Verb:
677 break;
678 }
679 }
680 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
681 return result;
682}
683
brianosmanfad98562016-05-04 11:06:28 -0700684Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
Brian Osmanc25e2692018-03-12 10:57:28 -0400685 // TODO: Actually serialize the rectangles, rather than just devolving to path
686 SkPath path;
687 region.getBoundaryPath(&path);
688 return MakeJsonPath(path);
ethannicholas50a8dd02016-02-10 05:40:46 -0800689}
690
Mike Reedc1f77742016-12-09 09:00:50 -0500691static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800692 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500693 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800694 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500695 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800696 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500697 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800698 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500699 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800700 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500701 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800702 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500703 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800704 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
705 default:
706 SkASSERT(false);
707 return Json::Value("<invalid region op>");
708 };
709}
710
711static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
712 switch (mode) {
713 case SkCanvas::kPoints_PointMode:
714 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
715 case SkCanvas::kLines_PointMode:
716 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700717 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800718 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
719 default:
720 SkASSERT(false);
721 return Json::Value("<invalid point mode>");
722 };
723}
724
halcanary9d524f22016-03-29 09:03:52 -0700725static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800726 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800727 if (value != defaultValue) {
728 (*target)[key] = Json::Value(value);
729 }
730}
731
ethannicholasbd3dae82016-02-10 12:10:00 -0800732static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800733 if (value != defaultValue) {
734 (*target)[key] = Json::Value(value);
735 }
736}
737
halcanary9d524f22016-03-29 09:03:52 -0700738static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800739 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700740 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
741 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800742 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800743}
744
brianosmanfad98562016-05-04 11:06:28 -0700745void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
746 UrlDataManager& urlDataManager) {
747 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800748 flattenable->flatten(buffer);
749 void* data = sk_malloc_throw(buffer.bytesWritten());
750 buffer.writeToMemory(data);
751 Json::Value jsonData;
752 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
753 Json::Value jsonFlattenable;
754 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
755 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700756
757 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
758 flattenable->flatten(jsonBuffer);
759 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
760
ethannicholasf62a8b72016-02-11 10:35:21 -0800761 (*target) = jsonFlattenable;
762 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800763}
764
ethannicholasf67531f2016-03-21 10:19:39 -0700765static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
766 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
767 out->write(data, length);
768}
769
halcanarya73d76a2016-10-17 13:19:02 -0700770void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700771 SkWStream& out, bool isOpaque) {
Ben Wagnera93a14a2017-08-28 10:34:05 -0400772 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700773 SkASSERT(png != nullptr);
774 png_infop info_ptr = png_create_info_struct(png);
775 SkASSERT(info_ptr != nullptr);
776 if (setjmp(png_jmpbuf(png))) {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400777 SK_ABORT("png encode error");
ethannicholasf67531f2016-03-21 10:19:39 -0700778 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400779 png_set_write_fn(png, &out, write_png_callback, nullptr);
msaretta5cf4f42016-06-30 10:06:51 -0700780 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
781 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700782 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
783 png_set_compression_level(png, 1);
784 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700785 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700786 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700787 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700788 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700789 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700790 rows[y][x * 4] = src[x * 4];
791 rows[y][x * 4 + 1] = src[x * 4 + 1];
792 rows[y][x * 4 + 2] = src[x * 4 + 2];
793 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700794 }
795 }
msaretta5cf4f42016-06-30 10:06:51 -0700796 png_write_info(png, info_ptr);
797 if (isOpaque) {
798 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
799 }
ethannicholasf67531f2016-03-21 10:19:39 -0700800 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700801 png_write_image(png, &rows[0]);
Ben Wagnera93a14a2017-08-28 10:34:05 -0400802 png_destroy_write_struct(&png, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700803 sk_free(rows);
804 sk_free(pixels);
805}
806
brianosmanfad98562016-05-04 11:06:28 -0700807bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
808 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700809 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500810 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700811 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700812 kN32_SkColorType, kPremul_SkAlphaType);
813 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
814 SkDebugf("readPixels failed\n");
815 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800816 }
msaretta5cf4f42016-06-30 10:06:51 -0700817
818 SkBitmap bm;
819 bm.installPixels(dstInfo, buffer.get(), rowBytes);
820 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
821
ethannicholasf67531f2016-03-21 10:19:39 -0700822 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700823 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700824 out, false);
reed42943c82016-09-12 12:01:44 -0700825 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800826 Json::Value jsonData;
827 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
828 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800829 return true;
830}
831
832static const char* color_type_name(SkColorType colorType) {
833 switch (colorType) {
834 case kARGB_4444_SkColorType:
835 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
836 case kRGBA_8888_SkColorType:
837 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
838 case kBGRA_8888_SkColorType:
839 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
840 case kRGB_565_SkColorType:
841 return SKDEBUGCANVAS_COLORTYPE_565;
842 case kGray_8_SkColorType:
843 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
ethannicholas50a8dd02016-02-10 05:40:46 -0800844 case kAlpha_8_SkColorType:
845 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
846 default:
847 SkASSERT(false);
848 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
849 }
850}
851
852static const char* alpha_type_name(SkAlphaType alphaType) {
853 switch (alphaType) {
854 case kOpaque_SkAlphaType:
855 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
856 case kPremul_SkAlphaType:
857 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
858 case kUnpremul_SkAlphaType:
859 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
860 default:
861 SkASSERT(false);
862 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
863 }
864}
865
halcanary9d524f22016-03-29 09:03:52 -0700866static Json::ArrayIndex decode_data(Json::Value data, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -0800867 const void** target) {
868 UrlDataManager::UrlData* urlData = urlDataManager.getDataFromUrl(SkString(data.asCString()));
869 if (urlData == nullptr) {
870 SkASSERT(false);
871 *target = nullptr;
872 return 0;
ethannicholas50a8dd02016-02-10 05:40:46 -0800873 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800874 *target = urlData->fData->data();
875 // cast should be safe for any reasonably-sized object...
876 return (Json::ArrayIndex) urlData->fData->size();
ethannicholas50a8dd02016-02-10 05:40:46 -0800877}
878
halcanary9d524f22016-03-29 09:03:52 -0700879static SkFlattenable* load_flattenable(Json::Value jsonFlattenable,
ethannicholasf62a8b72016-02-11 10:35:21 -0800880 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800881 if (!jsonFlattenable.isMember(SKDEBUGCANVAS_ATTRIBUTE_NAME)) {
882 return nullptr;
883 }
884 const char* name = jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME].asCString();
885 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
886 if (factory == nullptr) {
887 SkDebugf("no factory for loading '%s'\n", name);
888 return nullptr;
889 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800890 const void* data;
891 int size = decode_data(jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
Mike Reedfadbfcd2017-12-06 16:09:20 -0500892 SkReadBuffer buffer(data, size);
reed60c9b582016-04-03 09:11:13 -0700893 sk_sp<SkFlattenable> result = factory(buffer);
ethannicholas50a8dd02016-02-10 05:40:46 -0800894 if (!buffer.isValid()) {
895 SkDebugf("invalid buffer loading flattenable\n");
896 return nullptr;
897 }
reed60c9b582016-04-03 09:11:13 -0700898 return result.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800899}
900
901static SkColorType colortype_from_name(const char* name) {
902 if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ARGB4444)) {
903 return kARGB_4444_SkColorType;
904 }
905 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_RGBA8888)) {
906 return kRGBA_8888_SkColorType;
907 }
908 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_BGRA8888)) {
909 return kBGRA_8888_SkColorType;
910 }
911 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_565)) {
912 return kRGB_565_SkColorType;
913 }
914 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_GRAY8)) {
915 return kGray_8_SkColorType;
916 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800917 else if (!strcmp(name, SKDEBUGCANVAS_COLORTYPE_ALPHA8)) {
918 return kAlpha_8_SkColorType;
919 }
920 SkASSERT(false);
921 return kN32_SkColorType;
922}
923
924static SkBitmap* convert_colortype(SkBitmap* bitmap, SkColorType colorType) {
925 if (bitmap->colorType() == colorType ) {
926 return bitmap;
927 }
928 SkBitmap* dst = new SkBitmap();
Matt Sarett68b8e3d2017-04-28 11:15:22 -0400929 if (dst->tryAllocPixels(bitmap->info().makeColorType(colorType)) &&
930 bitmap->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0))
931 {
ethannicholas50a8dd02016-02-10 05:40:46 -0800932 delete bitmap;
933 return dst;
934 }
935 SkASSERT(false);
936 delete dst;
937 return bitmap;
938}
939
940// caller is responsible for freeing return value
ethannicholasf62a8b72016-02-11 10:35:21 -0800941static SkBitmap* load_bitmap(const Json::Value& jsonBitmap, UrlDataManager& urlDataManager) {
942 if (!jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_DATA)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800943 SkDebugf("invalid bitmap\n");
944 return nullptr;
945 }
ethannicholasf62a8b72016-02-11 10:35:21 -0800946 const void* data;
947 int size = decode_data(jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_DATA], urlDataManager, &data);
bungeman38d909e2016-08-02 14:40:46 -0700948 sk_sp<SkData> encoded(SkData::MakeWithoutCopy(data, size));
reed9ce9d672016-03-17 10:51:11 -0700949 sk_sp<SkImage> image(SkImage::MakeFromEncoded(std::move(encoded), nullptr));
msarett790f99a2016-03-09 06:16:55 -0800950
Ben Wagner145dbcd2016-11-03 14:40:50 -0400951 std::unique_ptr<SkBitmap> bitmap(new SkBitmap());
msarett790f99a2016-03-09 06:16:55 -0800952 if (nullptr != image) {
Cary Clark4f5a79c2018-02-07 15:51:00 -0500953 if (!image->asLegacyBitmap(bitmap.get())) {
msarett790f99a2016-03-09 06:16:55 -0800954 SkDebugf("image decode failed\n");
955 return nullptr;
956 }
957
ethannicholas50a8dd02016-02-10 05:40:46 -0800958 if (jsonBitmap.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
959 const char* ctName = jsonBitmap[SKDEBUGCANVAS_ATTRIBUTE_COLOR].asCString();
960 SkColorType ct = colortype_from_name(ctName);
Mike Reed304a07c2017-07-12 15:10:28 -0400961 bitmap.reset(convert_colortype(bitmap.release(), ct));
ethannicholas50a8dd02016-02-10 05:40:46 -0800962 }
mtklein18300a32016-03-16 13:53:35 -0700963 return bitmap.release();
ethannicholas50a8dd02016-02-10 05:40:46 -0800964 }
965 SkDebugf("image decode failed\n");
ethannicholas50a8dd02016-02-10 05:40:46 -0800966 return nullptr;
967}
968
reed9ce9d672016-03-17 10:51:11 -0700969static sk_sp<SkImage> load_image(const Json::Value& jsonImage, UrlDataManager& urlDataManager) {
ethannicholasf62a8b72016-02-11 10:35:21 -0800970 SkBitmap* bitmap = load_bitmap(jsonImage, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800971 if (bitmap == nullptr) {
972 return nullptr;
973 }
reed9ce9d672016-03-17 10:51:11 -0700974 auto result = SkImage::MakeFromBitmap(*bitmap);
ethannicholas50a8dd02016-02-10 05:40:46 -0800975 delete bitmap;
976 return result;
977}
978
brianosmanfad98562016-05-04 11:06:28 -0700979bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
980 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -0700981 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -0800982 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
983 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -0800984 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800985 return success;
986}
987
halcanaryf412f092016-08-25 11:10:41 -0700988static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
989 SkPaint::Hinting hinting = paint.getHinting();
990 if (hinting != SkPaintDefaults_Hinting) {
991 switch (hinting) {
992 case SkPaint::kNo_Hinting:
993 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
994 break;
995 case SkPaint::kSlight_Hinting:
996 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
997 break;
998 case SkPaint::kNormal_Hinting:
999 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
1000 break;
1001 case SkPaint::kFull_Hinting:
1002 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
1003 break;
1004 }
1005 }
1006}
1007
ethannicholas50a8dd02016-02-10 05:40:46 -08001008static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
1009 SkColor color = paint.getColor();
1010 if (color != SK_ColorBLACK) {
1011 Json::Value colorValue(Json::arrayValue);
1012 colorValue.append(Json::Value(SkColorGetA(color)));
1013 colorValue.append(Json::Value(SkColorGetR(color)));
1014 colorValue.append(Json::Value(SkColorGetG(color)));
1015 colorValue.append(Json::Value(SkColorGetB(color)));
1016 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
1017 }
1018}
1019
1020static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
1021 SkPaint::Style style = paint.getStyle();
1022 if (style != SkPaint::kFill_Style) {
1023 switch (style) {
1024 case SkPaint::kStroke_Style: {
1025 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
1026 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
1027 break;
1028 }
1029 case SkPaint::kStrokeAndFill_Style: {
1030 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
1031 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
1032 break;
1033 }
1034 default: SkASSERT(false);
1035 }
1036 }
1037}
1038
1039static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
1040 SkPaint::Cap cap = paint.getStrokeCap();
1041 if (cap != SkPaint::kDefault_Cap) {
1042 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001043 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001044 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
1045 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001046 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001047 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
1048 break;
ethannicholas1446a9a2016-02-10 14:05:02 -08001049 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -08001050 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
1051 break;
ethannicholas50a8dd02016-02-10 05:40:46 -08001052 default: SkASSERT(false);
1053 }
1054 }
1055}
ethannicholas1446a9a2016-02-10 14:05:02 -08001056
1057static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
1058 SkPaint::Join join = paint.getStrokeJoin();
1059 if (join != SkPaint::kDefault_Join) {
1060 switch (join) {
1061 case SkPaint::kMiter_Join:
1062 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1063 SKDEBUGCANVAS_MITER_JOIN);
1064 break;
1065 case SkPaint::kRound_Join:
1066 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1067 SKDEBUGCANVAS_ROUND_JOIN);
1068 break;
1069 case SkPaint::kBevel_Join:
1070 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
1071 SKDEBUGCANVAS_BEVEL_JOIN);
1072 break;
1073 default: SkASSERT(false);
1074 }
1075 }
1076}
1077
1078static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
1079 SkFilterQuality quality = paint.getFilterQuality();
1080 switch (quality) {
1081 case kNone_SkFilterQuality:
1082 break;
1083 case kLow_SkFilterQuality:
1084 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1085 SKDEBUGCANVAS_FILTERQUALITY_LOW);
1086 break;
1087 case kMedium_SkFilterQuality:
1088 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1089 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
1090 break;
1091 case kHigh_SkFilterQuality:
1092 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
1093 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
1094 break;
1095 }
1096}
1097
halcanary9d524f22016-03-29 09:03:52 -07001098static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001099 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001100 SkMaskFilter* maskFilter = paint.getMaskFilter();
1101 if (maskFilter != nullptr) {
Mike Reed80747ef2018-01-23 15:29:32 -05001102 SkMaskFilterBase::BlurRec blurRec;
1103 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001104 Json::Value blur(Json::objectValue);
1105 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
1106 switch (blurRec.fStyle) {
1107 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001108 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1109 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -08001110 break;
1111 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001112 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1113 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -08001114 break;
1115 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001116 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1117 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001118 break;
1119 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -08001120 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
1121 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -08001122 break;
1123 default:
1124 SkASSERT(false);
1125 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001126 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
1127 } else {
1128 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -07001129 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001130 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
1131 }
1132 }
1133}
1134
halcanary9d524f22016-03-29 09:03:52 -07001135static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001136 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001137 SkPathEffect* pathEffect = paint.getPathEffect();
1138 if (pathEffect != nullptr) {
1139 SkPathEffect::DashInfo dashInfo;
1140 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
1141 if (dashType == SkPathEffect::kDash_DashType) {
1142 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
1143 pathEffect->asADash(&dashInfo);
1144 Json::Value dashing(Json::objectValue);
1145 Json::Value intervals(Json::arrayValue);
1146 for (int32_t i = 0; i < dashInfo.fCount; i++) {
1147 intervals.append(Json::Value(dashInfo.fIntervals[i]));
1148 }
1149 sk_free(dashInfo.fIntervals);
1150 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
1151 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
1152 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
1153 } else {
1154 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001155 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001156 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1157 }
1158 }
1159}
halcanary9d524f22016-03-29 09:03:52 -07001160
ethannicholas50a8dd02016-02-10 05:40:46 -08001161static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1162 SkPaint::Align textAlign = paint.getTextAlign();
1163 if (textAlign != SkPaint::kLeft_Align) {
1164 switch (textAlign) {
1165 case SkPaint::kCenter_Align: {
1166 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1167 break;
1168 }
1169 case SkPaint::kRight_Align: {
1170 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1171 break;
1172 }
1173 default: SkASSERT(false);
1174 }
1175 }
1176}
1177
halcanary9d524f22016-03-29 09:03:52 -07001178static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001179 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001180 SkTypeface* typeface = paint.getTypeface();
1181 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001182 Json::Value jsonTypeface;
1183 SkDynamicMemoryWStream buffer;
1184 typeface->serialize(&buffer);
1185 void* data = sk_malloc_throw(buffer.bytesWritten());
1186 buffer.copyTo(data);
1187 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001188 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001189 &jsonData);
1190 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1191 sk_free(data);
1192 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001193 }
1194}
1195
halcanary9d524f22016-03-29 09:03:52 -07001196static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001197 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001198 SkFlattenable* shader = paint.getShader();
1199 if (shader != nullptr) {
1200 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001201 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001202 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1203 }
1204}
1205
ethannicholasf62a8b72016-02-11 10:35:21 -08001206static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1207 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001208 SkFlattenable* imageFilter = paint.getImageFilter();
1209 if (imageFilter != nullptr) {
1210 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001211 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001212 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1213 }
1214}
1215
halcanary9d524f22016-03-29 09:03:52 -07001216static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001217 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001218 SkFlattenable* colorFilter = paint.getColorFilter();
1219 if (colorFilter != nullptr) {
1220 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001221 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001222 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1223 }
1224}
1225
halcanary9d524f22016-03-29 09:03:52 -07001226static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001227 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001228 SkFlattenable* looper = paint.getLooper();
1229 if (looper != nullptr) {
1230 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001231 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001232 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1233 }
1234}
1235
brianosmanfad98562016-05-04 11:06:28 -07001236Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001237 Json::Value result(Json::objectValue);
1238 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001239 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001240 SkPaintDefaults_MiterLimit);
1241 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001242 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001243 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1244 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1245 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
1246 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT, paint.isDevKernText(), false);
1247 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1248 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1249 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1250 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1251 //kGenA8FromLCD_Flag
1252
halcanary9d524f22016-03-29 09:03:52 -07001253 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001254 SkPaintDefaults_TextSize);
1255 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1256 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001257 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001258 apply_paint_color(paint, &result);
1259 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001260 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001261 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001262 apply_paint_join(paint, &result);
1263 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001264 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001265 apply_paint_patheffect(paint, &result, urlDataManager);
1266 apply_paint_maskfilter(paint, &result, urlDataManager);
1267 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001268 apply_paint_looper(paint, &result, urlDataManager);
1269 apply_paint_imagefilter(paint, &result, urlDataManager);
1270 apply_paint_colorfilter(paint, &result, urlDataManager);
1271 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001272 return result;
1273}
1274
Stan Ilievac42aeb2017-01-12 16:20:50 -05001275Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1276 Json::Value result(Json::objectValue);
1277 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1278 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1279 if (nullptr != lattice.fBounds) {
1280 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1281 }
1282 Json::Value XDivs(Json::arrayValue);
1283 for (int i = 0; i < lattice.fXCount; i++) {
1284 XDivs.append(Json::Value(lattice.fXDivs[i]));
1285 }
1286 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1287 Json::Value YDivs(Json::arrayValue);
1288 for (int i = 0; i < lattice.fYCount; i++) {
1289 YDivs.append(Json::Value(lattice.fYDivs[i]));
1290 }
1291 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
Stan Ilievca8c0952017-12-11 13:01:58 -05001292 if (nullptr != lattice.fRectTypes) {
Stan Ilievac42aeb2017-01-12 16:20:50 -05001293 Json::Value flags(Json::arrayValue);
1294 int flagCount = 0;
1295 for (int row = 0; row < lattice.fYCount+1; row++) {
1296 Json::Value flagsRow(Json::arrayValue);
1297 for (int column = 0; column < lattice.fXCount+1; column++) {
Stan Ilievca8c0952017-12-11 13:01:58 -05001298 flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++]));
Stan Ilievac42aeb2017-01-12 16:20:50 -05001299 }
1300 flags.append(flagsRow);
1301 }
1302 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1303 }
1304 return result;
1305}
1306
ethannicholas1446a9a2016-02-10 14:05:02 -08001307static SkPoint get_json_point(Json::Value point) {
1308 return SkPoint::Make(point[0].asFloat(), point[1].asFloat());
1309}
1310
1311static SkColor get_json_color(Json::Value color) {
1312 return SkColorSetARGB(color[0].asInt(), color[1].asInt(), color[2].asInt(), color[3].asInt());
1313}
1314
ethannicholas50a8dd02016-02-10 05:40:46 -08001315static void extract_json_paint_color(Json::Value& jsonPaint, SkPaint* target) {
1316 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLOR)) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001317 target->setColor(get_json_color(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLOR]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001318 }
1319}
1320
halcanary9d524f22016-03-29 09:03:52 -07001321static void extract_json_paint_shader(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001322 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001323 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SHADER)) {
1324 Json::Value jsonShader = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SHADER];
ethannicholasf62a8b72016-02-11 10:35:21 -08001325 SkShader* shader = (SkShader*) load_flattenable(jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001326 if (shader != nullptr) {
reedfe630452016-03-25 09:08:00 -07001327 target->setShader(sk_ref_sp(shader));
ethannicholas50a8dd02016-02-10 05:40:46 -08001328 }
1329 }
1330}
1331
halcanary9d524f22016-03-29 09:03:52 -07001332static void extract_json_paint_patheffect(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001333 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001334 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT)) {
1335 Json::Value jsonPathEffect = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT];
reeda4393342016-03-18 11:22:57 -07001336 sk_sp<SkPathEffect> pathEffect((SkPathEffect*)load_flattenable(jsonPathEffect,
1337 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001338 if (pathEffect != nullptr) {
1339 target->setPathEffect(pathEffect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001340 }
1341 }
1342}
1343
halcanary9d524f22016-03-29 09:03:52 -07001344static void extract_json_paint_maskfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001345 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001346 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER)) {
1347 Json::Value jsonMaskFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER];
reedefdfd512016-04-04 10:02:58 -07001348 sk_sp<SkMaskFilter> maskFilter((SkMaskFilter*)load_flattenable(jsonMaskFilter,
1349 urlDataManager));
1350 if (maskFilter) {
1351 target->setMaskFilter(std::move(maskFilter));
ethannicholas50a8dd02016-02-10 05:40:46 -08001352 }
1353 }
1354}
1355
halcanary9d524f22016-03-29 09:03:52 -07001356static void extract_json_paint_colorfilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001357 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001358 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER)) {
1359 Json::Value jsonColorFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER];
reedd053ce92016-03-22 10:17:23 -07001360 sk_sp<SkColorFilter> colorFilter((SkColorFilter*)load_flattenable(jsonColorFilter,
1361 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001362 if (colorFilter != nullptr) {
1363 target->setColorFilter(colorFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001364 }
1365 }
1366}
1367
halcanary9d524f22016-03-29 09:03:52 -07001368static void extract_json_paint_looper(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001369 SkPaint* target) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001370 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LOOPER)) {
1371 Json::Value jsonLooper = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LOOPER];
reed7b380d02016-03-21 13:25:16 -07001372 sk_sp<SkDrawLooper> looper((SkDrawLooper*) load_flattenable(jsonLooper, urlDataManager));
ethannicholas1446a9a2016-02-10 14:05:02 -08001373 if (looper != nullptr) {
reed7b380d02016-03-21 13:25:16 -07001374 target->setLooper(std::move(looper));
ethannicholas1446a9a2016-02-10 14:05:02 -08001375 }
1376 }
1377}
1378
halcanary9d524f22016-03-29 09:03:52 -07001379static void extract_json_paint_imagefilter(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001380 SkPaint* target) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001381 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER)) {
1382 Json::Value jsonImageFilter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER];
Mike Reed5e257172016-11-01 11:22:05 -04001383 sk_sp<SkImageFilter> imageFilter((SkImageFilter*) load_flattenable(jsonImageFilter,
1384 urlDataManager));
ethannicholas50a8dd02016-02-10 05:40:46 -08001385 if (imageFilter != nullptr) {
1386 target->setImageFilter(imageFilter);
ethannicholas50a8dd02016-02-10 05:40:46 -08001387 }
1388 }
1389}
1390
halcanary9d524f22016-03-29 09:03:52 -07001391static void extract_json_paint_typeface(Json::Value& jsonPaint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001392 SkPaint* target) {
1393 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE)) {
1394 Json::Value jsonTypeface = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE];
1395 Json::Value jsonData = jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA];
1396 const void* data;
1397 Json::ArrayIndex length = decode_data(jsonData, urlDataManager, &data);
1398 SkMemoryStream buffer(data, length);
bungeman13b9c952016-05-12 10:09:30 -07001399 target->setTypeface(SkTypeface::MakeDeserialize(&buffer));
ethannicholasf62a8b72016-02-11 10:35:21 -08001400 }
1401}
1402
halcanaryf412f092016-08-25 11:10:41 -07001403static void extract_json_paint_hinting(Json::Value& jsonPaint, SkPaint* target) {
1404 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_HINTING)) {
1405 const char* hinting = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_HINTING].asCString();
1406 if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NONE)) {
1407 target->setHinting(SkPaint::kNo_Hinting);
1408 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_SLIGHT)) {
1409 target->setHinting(SkPaint::kSlight_Hinting);
1410 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_NORMAL)) {
1411 target->setHinting(SkPaint::kNormal_Hinting);
1412 } else if (!strcmp(hinting, SKDEBUGCANVAS_HINTING_FULL)) {
1413 target->setHinting(SkPaint::kFull_Hinting);
1414 }
1415 }
1416}
1417
ethannicholas50a8dd02016-02-10 05:40:46 -08001418static void extract_json_paint_style(Json::Value& jsonPaint, SkPaint* target) {
1419 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STYLE)) {
1420 const char* style = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1421 if (!strcmp(style, SKDEBUGCANVAS_STYLE_FILL)) {
1422 target->setStyle(SkPaint::kFill_Style);
1423 }
1424 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKE)) {
1425 target->setStyle(SkPaint::kStroke_Style);
1426 }
1427 else if (!strcmp(style, SKDEBUGCANVAS_STYLE_STROKEANDFILL)) {
1428 target->setStyle(SkPaint::kStrokeAndFill_Style);
1429 }
1430 }
1431}
1432
1433static void extract_json_paint_strokewidth(Json::Value& jsonPaint, SkPaint* target) {
1434 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH)) {
1435 float strokeWidth = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH].asFloat();
1436 target->setStrokeWidth(strokeWidth);
halcanary9d524f22016-03-29 09:03:52 -07001437 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001438}
1439
1440static void extract_json_paint_strokemiter(Json::Value& jsonPaint, SkPaint* target) {
1441 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER)) {
1442 float strokeMiter = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER].asFloat();
1443 target->setStrokeMiter(strokeMiter);
halcanary9d524f22016-03-29 09:03:52 -07001444 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001445}
1446
ethannicholas1446a9a2016-02-10 14:05:02 -08001447static void extract_json_paint_strokejoin(Json::Value& jsonPaint, SkPaint* target) {
1448 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN)) {
1449 const char* join = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN].asCString();
1450 if (!strcmp(join, SKDEBUGCANVAS_MITER_JOIN)) {
1451 target->setStrokeJoin(SkPaint::kMiter_Join);
1452 }
1453 else if (!strcmp(join, SKDEBUGCANVAS_ROUND_JOIN)) {
1454 target->setStrokeJoin(SkPaint::kRound_Join);
1455 }
1456 else if (!strcmp(join, SKDEBUGCANVAS_BEVEL_JOIN)) {
1457 target->setStrokeJoin(SkPaint::kBevel_Join);
1458 }
1459 else {
1460 SkASSERT(false);
1461 }
1462 }
1463}
1464
ethannicholas50a8dd02016-02-10 05:40:46 -08001465static void extract_json_paint_cap(Json::Value& jsonPaint, SkPaint* target) {
1466 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_CAP)) {
1467 const char* cap = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_CAP].asCString();
1468 if (!strcmp(cap, SKDEBUGCANVAS_CAP_BUTT)) {
1469 target->setStrokeCap(SkPaint::kButt_Cap);
1470 }
1471 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_ROUND)) {
1472 target->setStrokeCap(SkPaint::kRound_Cap);
1473 }
1474 else if (!strcmp(cap, SKDEBUGCANVAS_CAP_SQUARE)) {
1475 target->setStrokeCap(SkPaint::kSquare_Cap);
1476 }
1477 }
1478}
1479
ethannicholas1446a9a2016-02-10 14:05:02 -08001480static void extract_json_paint_filterquality(Json::Value& jsonPaint, SkPaint* target) {
1481 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY)) {
1482 const char* quality = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY].asCString();
1483 if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_NONE)) {
1484 target->setFilterQuality(kNone_SkFilterQuality);
1485 }
1486 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_LOW)) {
1487 target->setFilterQuality(kLow_SkFilterQuality);
1488 }
1489 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_MEDIUM)) {
1490 target->setFilterQuality(kMedium_SkFilterQuality);
1491 }
1492 else if (!strcmp(quality, SKDEBUGCANVAS_FILTERQUALITY_HIGH)) {
1493 target->setFilterQuality(kHigh_SkFilterQuality);
1494 }
1495 }
1496}
1497
ethannicholas50a8dd02016-02-10 05:40:46 -08001498static void extract_json_paint_antialias(Json::Value& jsonPaint, SkPaint* target) {
1499 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS)) {
1500 target->setAntiAlias(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1501 }
1502}
1503
ethannicholas1446a9a2016-02-10 14:05:02 -08001504static void extract_json_paint_dither(Json::Value& jsonPaint, SkPaint* target) {
1505 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DITHER)) {
1506 target->setDither(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DITHER].asBool());
1507 }
1508}
1509
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001510static void extract_json_paint_fakeboldtext(Json::Value& jsonPaint, SkPaint* target) {
1511 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT)) {
1512 target->setFakeBoldText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT].asBool());
1513 }
1514}
1515
1516static void extract_json_paint_lineartext(Json::Value& jsonPaint, SkPaint* target) {
1517 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT)) {
1518 target->setLinearText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT].asBool());
1519 }
1520}
1521
1522static void extract_json_paint_subpixeltext(Json::Value& jsonPaint, SkPaint* target) {
1523 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT)) {
1524 target->setSubpixelText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT].asBool());
1525 }
1526}
1527
1528static void extract_json_paint_devkerntext(Json::Value& jsonPaint, SkPaint* target) {
1529 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT)) {
1530 target->setDevKernText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT].asBool());
1531 }
1532}
1533
1534static void extract_json_paint_lcdrendertext(Json::Value& jsonPaint, SkPaint* target) {
1535 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT)) {
1536 target->setLCDRenderText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT].asBool());
1537 }
1538}
1539
1540static void extract_json_paint_embeddedbitmaptext(Json::Value& jsonPaint, SkPaint* target) {
1541 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT)) {
1542 target->setEmbeddedBitmapText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT].asBool());
1543 }
1544}
1545
1546static void extract_json_paint_autohinting(Json::Value& jsonPaint, SkPaint* target) {
1547 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING)) {
1548 target->setAutohinted(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING].asBool());
1549 }
1550}
1551
1552static void extract_json_paint_verticaltext(Json::Value& jsonPaint, SkPaint* target) {
1553 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT)) {
1554 target->setVerticalText(jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT].asBool());
1555 }
1556}
1557
ethannicholas50a8dd02016-02-10 05:40:46 -08001558static void extract_json_paint_blur(Json::Value& jsonPaint, SkPaint* target) {
1559 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_BLUR)) {
1560 Json::Value blur = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_BLUR];
1561 SkScalar sigma = blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA].asFloat();
1562 SkBlurStyle style;
1563 const char* jsonStyle = blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE].asCString();
1564 if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_NORMAL)) {
1565 style = SkBlurStyle::kNormal_SkBlurStyle;
1566 }
1567 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_SOLID)) {
1568 style = SkBlurStyle::kSolid_SkBlurStyle;
1569 }
1570 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_OUTER)) {
1571 style = SkBlurStyle::kOuter_SkBlurStyle;
1572 }
1573 else if (!strcmp(jsonStyle, SKDEBUGCANVAS_BLURSTYLE_INNER)) {
1574 style = SkBlurStyle::kInner_SkBlurStyle;
1575 }
1576 else {
1577 SkASSERT(false);
1578 style = SkBlurStyle::kNormal_SkBlurStyle;
1579 }
Mike Reed1be1f8d2018-03-14 13:01:17 -04001580 target->setMaskFilter(SkMaskFilter::MakeBlur(style, sigma));
ethannicholas50a8dd02016-02-10 05:40:46 -08001581 }
1582}
1583
1584static void extract_json_paint_dashing(Json::Value& jsonPaint, SkPaint* target) {
1585 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_DASHING)) {
1586 Json::Value dash = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_DASHING];
1587 Json::Value jsonIntervals = dash[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS];
1588 Json::ArrayIndex count = jsonIntervals.size();
1589 SkScalar* intervals = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
1590 for (Json::ArrayIndex i = 0; i < count; i++) {
1591 intervals[i] = jsonIntervals[i].asFloat();
1592 }
1593 SkScalar phase = dash[SKDEBUGCANVAS_ATTRIBUTE_PHASE].asFloat();
reeda4393342016-03-18 11:22:57 -07001594 target->setPathEffect(SkDashPathEffect::Make(intervals, count, phase));
ethannicholas50a8dd02016-02-10 05:40:46 -08001595 sk_free(intervals);
1596 }
1597}
1598
1599static void extract_json_paint_textalign(Json::Value& jsonPaint, SkPaint* target) {
1600 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN)) {
1601 SkPaint::Align textAlign;
1602 const char* jsonAlign = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN].asCString();
1603 if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_LEFT)) {
1604 textAlign = SkPaint::kLeft_Align;
1605 }
1606 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_CENTER)) {
1607 textAlign = SkPaint::kCenter_Align;
1608 }
1609 else if (!strcmp(jsonAlign, SKDEBUGCANVAS_ALIGN_RIGHT)) {
1610 textAlign = SkPaint::kRight_Align;
1611 }
1612 else {
1613 SkASSERT(false);
1614 textAlign = SkPaint::kLeft_Align;
1615 }
1616 target->setTextAlign(textAlign);
1617 }
1618}
1619
1620static void extract_json_paint_textsize(Json::Value& jsonPaint, SkPaint* target) {
1621 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE)) {
1622 float textSize = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE].asFloat();
1623 target->setTextSize(textSize);
1624 }
1625}
1626
1627static void extract_json_paint_textscalex(Json::Value& jsonPaint, SkPaint* target) {
1628 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX)) {
1629 float textScaleX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX].asFloat();
1630 target->setTextScaleX(textScaleX);
1631 }
1632}
1633
1634static void extract_json_paint_textskewx(Json::Value& jsonPaint, SkPaint* target) {
1635 if (jsonPaint.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX)) {
1636 float textSkewX = jsonPaint[SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX].asFloat();
1637 target->setTextSkewX(textSkewX);
1638 }
1639}
1640
halcanary9d524f22016-03-29 09:03:52 -07001641static void extract_json_paint(Json::Value& paint, UrlDataManager& urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001642 SkPaint* result) {
halcanaryf412f092016-08-25 11:10:41 -07001643 extract_json_paint_hinting(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001644 extract_json_paint_color(paint, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001645 extract_json_paint_shader(paint, urlDataManager, result);
1646 extract_json_paint_patheffect(paint, urlDataManager, result);
1647 extract_json_paint_maskfilter(paint, urlDataManager, result);
1648 extract_json_paint_colorfilter(paint, urlDataManager, result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001649 extract_json_paint_looper(paint, urlDataManager, result);
1650 extract_json_paint_imagefilter(paint, urlDataManager, result);
1651 extract_json_paint_typeface(paint, urlDataManager, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001652 extract_json_paint_style(paint, result);
Florin Malita82d80872017-06-06 16:58:40 -04001653 extract_json_paint_blend_mode(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001654 extract_json_paint_strokewidth(paint, result);
1655 extract_json_paint_strokemiter(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001656 extract_json_paint_strokejoin(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001657 extract_json_paint_cap(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001658 extract_json_paint_filterquality(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001659 extract_json_paint_antialias(paint, result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001660 extract_json_paint_dither(paint, result);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001661 extract_json_paint_fakeboldtext(paint, result);
1662 extract_json_paint_lineartext(paint, result);
1663 extract_json_paint_subpixeltext(paint, result);
1664 extract_json_paint_devkerntext(paint, result);
1665 extract_json_paint_lcdrendertext(paint, result);
1666 extract_json_paint_embeddedbitmaptext(paint, result);
1667 extract_json_paint_autohinting(paint, result);
1668 extract_json_paint_verticaltext(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001669 extract_json_paint_blur(paint, result);
1670 extract_json_paint_dashing(paint, result);
1671 extract_json_paint_textalign(paint, result);
1672 extract_json_paint_textsize(paint, result);
1673 extract_json_paint_textscalex(paint, result);
1674 extract_json_paint_textskewx(paint, result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001675}
1676
1677static void extract_json_rect(Json::Value& rect, SkRect* result) {
1678 result->set(rect[0].asFloat(), rect[1].asFloat(), rect[2].asFloat(), rect[3].asFloat());
1679}
1680
1681static void extract_json_irect(Json::Value& rect, SkIRect* result) {
1682 result->set(rect[0].asInt(), rect[1].asInt(), rect[2].asInt(), rect[3].asInt());
1683}
1684
1685static void extract_json_rrect(Json::Value& rrect, SkRRect* result) {
1686 SkVector radii[4] = {
halcanary9d524f22016-03-29 09:03:52 -07001687 { rrect[1][0].asFloat(), rrect[1][1].asFloat() },
1688 { rrect[2][0].asFloat(), rrect[2][1].asFloat() },
1689 { rrect[3][0].asFloat(), rrect[3][1].asFloat() },
ethannicholas50a8dd02016-02-10 05:40:46 -08001690 { rrect[4][0].asFloat(), rrect[4][1].asFloat() }
1691 };
halcanary9d524f22016-03-29 09:03:52 -07001692 result->setRectRadii(SkRect::MakeLTRB(rrect[0][0].asFloat(), rrect[0][1].asFloat(),
1693 rrect[0][2].asFloat(), rrect[0][3].asFloat()),
ethannicholas50a8dd02016-02-10 05:40:46 -08001694 radii);
1695}
1696
1697static void extract_json_matrix(Json::Value& matrix, SkMatrix* result) {
halcanary9d524f22016-03-29 09:03:52 -07001698 SkScalar values[] = {
ethannicholas50a8dd02016-02-10 05:40:46 -08001699 matrix[0][0].asFloat(), matrix[0][1].asFloat(), matrix[0][2].asFloat(),
1700 matrix[1][0].asFloat(), matrix[1][1].asFloat(), matrix[1][2].asFloat(),
halcanary9d524f22016-03-29 09:03:52 -07001701 matrix[2][0].asFloat(), matrix[2][1].asFloat(), matrix[2][2].asFloat()
ethannicholas50a8dd02016-02-10 05:40:46 -08001702 };
1703 result->set9(values);
1704}
1705
1706static void extract_json_path(Json::Value& path, SkPath* result) {
1707 const char* fillType = path[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE].asCString();
1708 if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_WINDING)) {
1709 result->setFillType(SkPath::kWinding_FillType);
1710 }
1711 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_EVENODD)) {
1712 result->setFillType(SkPath::kEvenOdd_FillType);
1713 }
1714 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING)) {
1715 result->setFillType(SkPath::kInverseWinding_FillType);
1716 }
1717 else if (!strcmp(fillType, SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD)) {
1718 result->setFillType(SkPath::kInverseEvenOdd_FillType);
1719 }
1720 Json::Value verbs = path[SKDEBUGCANVAS_ATTRIBUTE_VERBS];
1721 for (Json::ArrayIndex i = 0; i < verbs.size(); i++) {
1722 Json::Value verb = verbs[i];
1723 if (verb.isString()) {
1724 SkASSERT(!strcmp(verb.asCString(), SKDEBUGCANVAS_VERB_CLOSE));
1725 result->close();
1726 }
1727 else {
1728 if (verb.isMember(SKDEBUGCANVAS_VERB_MOVE)) {
1729 Json::Value move = verb[SKDEBUGCANVAS_VERB_MOVE];
1730 result->moveTo(move[0].asFloat(), move[1].asFloat());
1731 }
1732 else if (verb.isMember(SKDEBUGCANVAS_VERB_LINE)) {
1733 Json::Value line = verb[SKDEBUGCANVAS_VERB_LINE];
1734 result->lineTo(line[0].asFloat(), line[1].asFloat());
1735 }
1736 else if (verb.isMember(SKDEBUGCANVAS_VERB_QUAD)) {
1737 Json::Value quad = verb[SKDEBUGCANVAS_VERB_QUAD];
1738 result->quadTo(quad[0][0].asFloat(), quad[0][1].asFloat(),
1739 quad[1][0].asFloat(), quad[1][1].asFloat());
1740 }
1741 else if (verb.isMember(SKDEBUGCANVAS_VERB_CUBIC)) {
1742 Json::Value cubic = verb[SKDEBUGCANVAS_VERB_CUBIC];
1743 result->cubicTo(cubic[0][0].asFloat(), cubic[0][1].asFloat(),
1744 cubic[1][0].asFloat(), cubic[1][1].asFloat(),
1745 cubic[2][0].asFloat(), cubic[2][1].asFloat());
1746 }
1747 else if (verb.isMember(SKDEBUGCANVAS_VERB_CONIC)) {
1748 Json::Value conic = verb[SKDEBUGCANVAS_VERB_CONIC];
1749 result->conicTo(conic[0][0].asFloat(), conic[0][1].asFloat(),
1750 conic[1][0].asFloat(), conic[1][1].asFloat(),
1751 conic[2].asFloat());
1752 }
1753 else {
1754 SkASSERT(false);
1755 }
1756 }
1757 }
1758}
1759
Brian Osmanc25e2692018-03-12 10:57:28 -04001760static void extract_json_region(Json::Value& region, SkRegion* result) {
1761 SkPath path;
1762 extract_json_path(region, &path);
1763 result->setPath(path, SkRegion(path.getBounds().roundOut()));
1764}
1765
Mike Reedc1f77742016-12-09 09:00:50 -05001766SkClipOp get_json_clipop(Json::Value& jsonOp) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001767 const char* op = jsonOp.asCString();
1768 if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001769 return kDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001770 }
1771 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_INTERSECT)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001772 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001773 }
1774 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_UNION)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001775 return kUnion_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001776 }
1777 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_XOR)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001778 return kXOR_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001779 }
1780 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001781 return kReverseDifference_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001782 }
1783 else if (!strcmp(op, SKDEBUGCANVAS_REGIONOP_REPLACE)) {
Mike Reedc1f77742016-12-09 09:00:50 -05001784 return kReplace_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001785 }
1786 SkASSERT(false);
Mike Reedc1f77742016-12-09 09:00:50 -05001787 return kIntersect_SkClipOp;
ethannicholas50a8dd02016-02-10 05:40:46 -08001788}
1789
Brian Osmanc25e2692018-03-12 10:57:28 -04001790SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001791 fColor = color;
1792 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
1793}
1794
1795void SkClearCommand::execute(SkCanvas* canvas) const {
1796 canvas->clear(fColor);
1797}
1798
ethannicholasf62a8b72016-02-11 10:35:21 -08001799Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1800 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001801 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001802 return result;
1803}
1804
ethannicholasf62a8b72016-02-11 10:35:21 -08001805 SkClearCommand* SkClearCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001806 Json::Value color = command[SKDEBUGCANVAS_ATTRIBUTE_COLOR];
1807 return new SkClearCommand(get_json_color(color));
1808}
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001809
Mike Reedc1f77742016-12-09 09:00:50 -05001810SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001811 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001812 fPath = path;
1813 fOp = op;
1814 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001815
robertphillips@google.com91217d02013-03-17 18:33:46 +00001816 fInfo.push(SkObjectParser::PathToString(path));
reed73603f32016-09-20 08:42:38 -07001817 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.com91217d02013-03-17 18:33:46 +00001818 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001819}
1820
fmalita8c89c522014-11-08 16:18:56 -08001821void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001822 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001823}
1824
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001825bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001826 render_path(canvas, fPath);
1827 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001828}
1829
ethannicholasf62a8b72016-02-11 10:35:21 -08001830Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1831 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001832 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001833 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1834 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1835 return result;
1836}
1837
halcanary9d524f22016-03-29 09:03:52 -07001838SkClipPathCommand* SkClipPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001839 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001840 SkPath path;
1841 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
reed73603f32016-09-20 08:42:38 -07001842 return new SkClipPathCommand(path, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001843 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1844}
1845
Mike Reedc1f77742016-12-09 09:00:50 -05001846SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001847 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001848 fRegion = region;
1849 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001850
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001851 fInfo.push(SkObjectParser::RegionToString(region));
reed73603f32016-09-20 08:42:38 -07001852 fInfo.push(SkObjectParser::ClipOpToString(op));
chudy@google.com902ebe52012-06-29 14:21:22 +00001853}
1854
fmalita8c89c522014-11-08 16:18:56 -08001855void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001856 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001857}
1858
ethannicholasf62a8b72016-02-11 10:35:21 -08001859Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1860 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001861 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001862 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1863 return result;
1864}
1865
halcanary9d524f22016-03-29 09:03:52 -07001866SkClipRegionCommand* SkClipRegionCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001867 UrlDataManager& urlDataManager) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001868 SkRegion region;
1869 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
1870 return new SkClipRegionCommand(region,
1871 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001872}
1873
Mike Reedc1f77742016-12-09 09:00:50 -05001874SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001875 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001876 fRect = rect;
1877 fOp = op;
1878 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001879
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001880 fInfo.push(SkObjectParser::RectToString(rect));
reed73603f32016-09-20 08:42:38 -07001881 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001882 fInfo.push(SkObjectParser::BoolToString(doAA));
chudy@google.com902ebe52012-06-29 14:21:22 +00001883}
1884
fmalita8c89c522014-11-08 16:18:56 -08001885void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001886 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001887}
1888
ethannicholasf62a8b72016-02-11 10:35:21 -08001889Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1890 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001891 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001892 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1893 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001894
1895 SkString desc;
1896 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1897
ethannicholas50a8dd02016-02-10 05:40:46 -08001898 return result;
1899}
1900
halcanary9d524f22016-03-29 09:03:52 -07001901SkClipRectCommand* SkClipRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001902 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001903 SkRect rect;
1904 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
reed73603f32016-09-20 08:42:38 -07001905 return new SkClipRectCommand(rect, get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001906 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1907}
1908
Mike Reedc1f77742016-12-09 09:00:50 -05001909SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001910 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001911 fRRect = rrect;
1912 fOp = op;
1913 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001914
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001915 fInfo.push(SkObjectParser::RRectToString(rrect));
reed73603f32016-09-20 08:42:38 -07001916 fInfo.push(SkObjectParser::ClipOpToString(op));
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001917 fInfo.push(SkObjectParser::BoolToString(doAA));
robertphillips@google.com67baba42013-01-02 20:20:31 +00001918}
1919
fmalita8c89c522014-11-08 16:18:56 -08001920void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001921 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001922}
1923
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001924bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001925 render_rrect(canvas, fRRect);
1926 return true;
1927}
1928
ethannicholasf62a8b72016-02-11 10:35:21 -08001929Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1930 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001931 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1932 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1933 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1934 return result;
1935}
1936
halcanary9d524f22016-03-29 09:03:52 -07001937SkClipRRectCommand* SkClipRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08001938 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001939 SkRRect rrect;
1940 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rrect);
halcanary9d524f22016-03-29 09:03:52 -07001941 return new SkClipRRectCommand(rrect,
reed73603f32016-09-20 08:42:38 -07001942 get_json_clipop(command[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP]),
ethannicholas50a8dd02016-02-10 05:40:46 -08001943 command[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS].asBool());
1944}
1945
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001946SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001947 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001948 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001949
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001950 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00001951}
1952
fmalita8c89c522014-11-08 16:18:56 -08001953void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001954 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001955}
1956
ethannicholasf62a8b72016-02-11 10:35:21 -08001957Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1958 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001959 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001960 return result;
1961}
1962
ethannicholasf62a8b72016-02-11 10:35:21 -08001963SkConcatCommand* SkConcatCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001964 SkMatrix matrix;
1965 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
1966 return new SkConcatCommand(matrix);
1967}
1968
reed97660cc2016-06-28 18:54:19 -07001969////
1970
1971SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1972 sk_sp<SkData> value)
1973 : INHERITED(kDrawAnnotation_OpType)
1974 , fRect(rect)
1975 , fKey(key)
1976 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07001977{
1978 SkString str;
1979 str.appendf("Key: %s Value: ", key);
1980 if (fValue && fValue->size()) {
1981 str.append((const char*) fValue->bytes(), fValue->size());
1982 } else {
1983 str.appendf("no value");
1984 }
1985 str.appendf("\n");
1986 fInfo.push(new SkString(str));
1987}
reed97660cc2016-06-28 18:54:19 -07001988
1989void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1990 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1991}
1992
1993Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1994 Json::Value result = INHERITED::toJSON(urlDataManager);
1995
1996 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1997 result["key"] = Json::Value(fKey.c_str());
1998 if (fValue.get()) {
1999 // TODO: dump out the "value"
2000 }
reed67f62fa2016-06-29 11:36:34 -07002001
2002 SkString desc;
2003 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
2004 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
2005
reed97660cc2016-06-28 18:54:19 -07002006 return result;
2007}
2008
2009SkDrawAnnotationCommand* SkDrawAnnotationCommand::fromJSON(Json::Value& command,
2010 UrlDataManager& urlDataManager) {
2011 SkRect rect;
2012 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &rect);
2013 sk_sp<SkData> data(nullptr); // TODO: extract "value" from the Json
2014 return new SkDrawAnnotationCommand(rect, command["key"].asCString(), data);
2015}
2016
2017////
2018
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002019SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07002020 const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002021 : INHERITED(kDrawBitmap_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002022 fBitmap = bitmap;
2023 fLeft = left;
2024 fTop = top;
bsalomon49f085d2014-09-05 13:34:00 -07002025 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002026 fPaint = *paint;
2027 fPaintPtr = &fPaint;
2028 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002029 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002030 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002031
2032 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2033 fInfo.push(SkObjectParser::ScalarToString(left, "SkScalar left: "));
2034 fInfo.push(SkObjectParser::ScalarToString(top, "SkScalar top: "));
bsalomon49f085d2014-09-05 13:34:00 -07002035 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002036 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002037 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002038}
2039
fmalita8c89c522014-11-08 16:18:56 -08002040void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002041 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002042}
2043
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002044bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002045 render_bitmap(canvas, fBitmap);
2046 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002047}
2048
ethannicholasf62a8b72016-02-11 10:35:21 -08002049Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
2050 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002051 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002052 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002053 Json::Value command(Json::objectValue);
2054 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002055 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002056 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002057 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002058 }
2059 }
2060 return result;
2061}
2062
halcanary9d524f22016-03-29 09:03:52 -07002063SkDrawBitmapCommand* SkDrawBitmapCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002064 UrlDataManager& urlDataManager) {
2065 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002066 if (bitmap == nullptr) {
2067 return nullptr;
2068 }
2069 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2070 SkPaint* paintPtr;
2071 SkPaint paint;
2072 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002073 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002074 paintPtr = &paint;
2075 }
2076 else {
2077 paintPtr = nullptr;
2078 }
halcanary9d524f22016-03-29 09:03:52 -07002079 SkDrawBitmapCommand* result = new SkDrawBitmapCommand(*bitmap, point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002080 point[1].asFloat(), paintPtr);
2081 delete bitmap;
2082 return result;
2083}
2084
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002085SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00002086 const SkRect& dst, const SkPaint* paint)
robertphillips9bafc302015-02-13 11:13:00 -08002087 : INHERITED(kDrawBitmapNine_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002088 fBitmap = bitmap;
2089 fCenter = center;
2090 fDst = dst;
bsalomon49f085d2014-09-05 13:34:00 -07002091 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002092 fPaint = *paint;
2093 fPaintPtr = &fPaint;
2094 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002095 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002096 }
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002097
2098 fInfo.push(SkObjectParser::BitmapToString(bitmap));
2099 fInfo.push(SkObjectParser::IRectToString(center));
2100 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07002101 if (paint) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002102 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002103 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002104}
2105
fmalita8c89c522014-11-08 16:18:56 -08002106void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00002107 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaintPtr);
chudy@google.com902ebe52012-06-29 14:21:22 +00002108}
2109
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002110bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08002111 SkRect tmp = SkRect::Make(fCenter);
2112 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002113 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002114}
2115
ethannicholasf62a8b72016-02-11 10:35:21 -08002116Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2117 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002118 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002119 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002120 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08002121 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07002122 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002123 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002124 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002125 }
2126 }
2127 return result;
2128}
2129
halcanary9d524f22016-03-29 09:03:52 -07002130SkDrawBitmapNineCommand* SkDrawBitmapNineCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002131 UrlDataManager& urlDataManager) {
2132 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002133 if (bitmap == nullptr) {
2134 return nullptr;
2135 }
2136 SkIRect center;
2137 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2138 SkRect dst;
2139 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2140 SkPaint* paintPtr;
2141 SkPaint paint;
2142 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002143 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002144 paintPtr = &paint;
2145 }
2146 else {
2147 paintPtr = nullptr;
2148 }
2149 SkDrawBitmapNineCommand* result = new SkDrawBitmapNineCommand(*bitmap, center, dst, paintPtr);
2150 delete bitmap;
2151 return result;
2152}
2153
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002154SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002155 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07002156 SkCanvas::SrcRectConstraint constraint)
robertphillips9bafc302015-02-13 11:13:00 -08002157 : INHERITED(kDrawBitmapRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002158 fBitmap = bitmap;
bsalomon49f085d2014-09-05 13:34:00 -07002159 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002160 fSrc = *src;
2161 } else {
2162 fSrc.setEmpty();
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002163 }
robertphillips@google.com91217d02013-03-17 18:33:46 +00002164 fDst = dst;
2165
bsalomon49f085d2014-09-05 13:34:00 -07002166 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002167 fPaint = *paint;
2168 fPaintPtr = &fPaint;
2169 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07002170 fPaintPtr = nullptr;
robertphillips@google.com91217d02013-03-17 18:33:46 +00002171 }
reeda5517e22015-07-14 10:54:12 -07002172 fConstraint = constraint;
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00002173
robertphillips@google.com91217d02013-03-17 18:33:46 +00002174 fInfo.push(SkObjectParser::BitmapToString(bitmap));
bsalomon49f085d2014-09-05 13:34:00 -07002175 if (src) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002176 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2177 }
2178 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
bsalomon49f085d2014-09-05 13:34:00 -07002179 if (paint) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002180 fInfo.push(SkObjectParser::PaintToString(*paint));
robertphillips@google.comb83b6b42013-01-22 14:32:09 +00002181 }
reeda5517e22015-07-14 10:54:12 -07002182 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
chudy@google.com902ebe52012-06-29 14:21:22 +00002183}
2184
fmalita8c89c522014-11-08 16:18:56 -08002185void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
reede47829b2015-08-06 10:02:53 -07002186 canvas->legacy_drawBitmapRect(fBitmap, this->srcRect(), fDst, fPaintPtr, fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002187}
2188
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002189bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002190 render_bitmap(canvas, fBitmap, this->srcRect());
2191 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00002192}
2193
ethannicholasf62a8b72016-02-11 10:35:21 -08002194Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2195 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002196 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002197 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002198 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
2199 if (!fSrc.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07002200 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(fSrc);
ethannicholas50a8dd02016-02-10 05:40:46 -08002201 }
brianosmanfad98562016-05-04 11:06:28 -07002202 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002203 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07002204 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002205 }
2206 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2207 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2208 }
2209 }
reed67f62fa2016-06-29 11:36:34 -07002210
2211 SkString desc;
2212 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2213
ethannicholas50a8dd02016-02-10 05:40:46 -08002214 return result;
2215}
2216
halcanary9d524f22016-03-29 09:03:52 -07002217SkDrawBitmapRectCommand* SkDrawBitmapRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002218 UrlDataManager& urlDataManager) {
2219 SkBitmap* bitmap = load_bitmap(command[SKDEBUGCANVAS_ATTRIBUTE_BITMAP], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002220 if (bitmap == nullptr) {
2221 return nullptr;
2222 }
2223 SkRect dst;
2224 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2225 SkPaint* paintPtr;
2226 SkPaint paint;
2227 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002228 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002229 paintPtr = &paint;
2230 }
2231 else {
2232 paintPtr = nullptr;
2233 }
2234 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002235 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002236 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2237 constraint = SkCanvas::kStrict_SrcRectConstraint;
2238 }
2239 else {
2240 constraint = SkCanvas::kFast_SrcRectConstraint;
2241 }
2242 SkRect* srcPtr;
2243 SkRect src;
2244 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2245 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2246 srcPtr = &src;
2247 }
2248 else {
2249 srcPtr = nullptr;
2250 }
2251 SkDrawBitmapRectCommand* result = new SkDrawBitmapRectCommand(*bitmap, srcPtr, dst, paintPtr,
2252 constraint);
2253 delete bitmap;
2254 return result;
2255}
2256
fmalita651c9202015-07-22 10:23:01 -07002257SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
2258 const SkPaint* paint)
2259 : INHERITED(kDrawImage_OpType)
2260 , fImage(SkRef(image))
2261 , fLeft(left)
2262 , fTop(top) {
2263
fmalita7361bf02015-10-29 12:13:48 -07002264 fInfo.push(SkObjectParser::ImageToString(image));
2265 fInfo.push(SkObjectParser::ScalarToString(left, "Left: "));
2266 fInfo.push(SkObjectParser::ScalarToString(top, "Top: "));
2267
fmalita651c9202015-07-22 10:23:01 -07002268 if (paint) {
2269 fPaint.set(*paint);
fmalita7361bf02015-10-29 12:13:48 -07002270 fInfo.push(SkObjectParser::PaintToString(*paint));
fmalita651c9202015-07-22 10:23:01 -07002271 }
2272}
2273
2274void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002275 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07002276}
2277
2278bool SkDrawImageCommand::render(SkCanvas* canvas) const {
2279 SkAutoCanvasRestore acr(canvas, true);
2280 canvas->clear(0xFFFFFFFF);
2281
2282 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
2283 SkIntToScalar(fImage->width()),
2284 SkIntToScalar(fImage->height())));
2285 this->execute(canvas);
2286 return true;
2287}
2288
ethannicholasf62a8b72016-02-11 10:35:21 -08002289Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
2290 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002291 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002292 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002293 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07002294 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08002295 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002296 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002297 }
msarett0ac1bec2016-08-29 09:15:33 -07002298
2299 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
2300 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
2301 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
2302 switch (fImage->alphaType()) {
2303 case kOpaque_SkAlphaType:
2304 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
2305 break;
2306 case kPremul_SkAlphaType:
2307 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
2308 break;
2309 case kUnpremul_SkAlphaType:
2310 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
2311 break;
2312 default:
2313 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
2314 break;
2315 }
ethannicholas50a8dd02016-02-10 05:40:46 -08002316 }
2317 return result;
2318}
2319
halcanary9d524f22016-03-29 09:03:52 -07002320SkDrawImageCommand* SkDrawImageCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002321 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002322 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002323 if (image == nullptr) {
2324 return nullptr;
2325 }
2326 Json::Value point = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2327 SkPaint* paintPtr;
2328 SkPaint paint;
2329 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002330 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002331 paintPtr = &paint;
2332 }
2333 else {
2334 paintPtr = nullptr;
2335 }
reed9ce9d672016-03-17 10:51:11 -07002336 SkDrawImageCommand* result = new SkDrawImageCommand(image.get(), point[0].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08002337 point[1].asFloat(), paintPtr);
ethannicholas50a8dd02016-02-10 05:40:46 -08002338 return result;
2339}
2340
Stan Ilievac42aeb2017-01-12 16:20:50 -05002341SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
2342 const SkCanvas::Lattice& lattice,
2343 const SkRect& dst, const SkPaint* paint)
2344 : INHERITED(kDrawImageLattice_OpType)
2345 , fImage(SkRef(image))
2346 , fLattice(lattice)
2347 , fDst(dst) {
2348
2349 fInfo.push(SkObjectParser::ImageToString(image));
2350 fInfo.push(SkObjectParser::LatticeToString(lattice));
2351 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2352 if (paint) {
2353 fPaint.set(*paint);
2354 fInfo.push(SkObjectParser::PaintToString(*paint));
2355 }
2356}
2357
2358void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
2359 SkLatticeIter iter(fLattice, fDst);
2360 SkRect srcR, dstR;
2361 while (iter.next(&srcR, &dstR)) {
2362 canvas->legacy_drawImageRect(fImage.get(), &srcR, dstR,
2363 fPaint.getMaybeNull(), SkCanvas::kStrict_SrcRectConstraint);
2364 }
2365}
2366
2367bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
2368 SkAutoCanvasRestore acr(canvas, true);
2369 canvas->clear(0xFFFFFFFF);
2370
2371 xlate_and_scale_to_bounds(canvas, fDst);
2372
2373 this->execute(canvas);
2374 return true;
2375}
2376
2377Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
2378 Json::Value result = INHERITED::toJSON(urlDataManager);
2379 Json::Value encoded;
2380 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002381 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
Stan Ilievac42aeb2017-01-12 16:20:50 -05002382 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
2383 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2384 if (fPaint.isValid()) {
2385 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
2386 }
2387 }
2388
2389 SkString desc;
2390 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2391
2392 return result;
2393}
2394
Brian Osmanc25e2692018-03-12 10:57:28 -04002395SkDrawImageLatticeCommand* SkDrawImageLatticeCommand::fromJSON(Json::Value& command,
2396 UrlDataManager& urlDataManager) {
2397 SkDEBUGFAIL("Not implemented yet.");
2398 return nullptr;
2399}
2400
fmalita651c9202015-07-22 10:23:01 -07002401SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
2402 const SkRect& dst, const SkPaint* paint,
2403 SkCanvas::SrcRectConstraint constraint)
2404 : INHERITED(kDrawImageRect_OpType)
2405 , fImage(SkRef(image))
2406 , fDst(dst)
2407 , fConstraint(constraint) {
2408
2409 if (src) {
2410 fSrc.set(*src);
2411 }
2412
2413 if (paint) {
2414 fPaint.set(*paint);
2415 }
robertphillips80af6452015-08-24 08:27:38 -07002416
2417 fInfo.push(SkObjectParser::ImageToString(image));
2418 if (src) {
2419 fInfo.push(SkObjectParser::RectToString(*src, "Src: "));
2420 }
2421 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2422 if (paint) {
2423 fInfo.push(SkObjectParser::PaintToString(*paint));
2424 }
2425 fInfo.push(SkObjectParser::IntToString(fConstraint, "Constraint: "));
fmalita651c9202015-07-22 10:23:01 -07002426}
2427
2428void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04002429 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
2430 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07002431}
2432
2433bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
2434 SkAutoCanvasRestore acr(canvas, true);
2435 canvas->clear(0xFFFFFFFF);
2436
2437 xlate_and_scale_to_bounds(canvas, fDst);
2438
2439 this->execute(canvas);
2440 return true;
2441}
2442
ethannicholasf62a8b72016-02-11 10:35:21 -08002443Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2444 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002445 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08002446 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04002447 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
ethannicholas50a8dd02016-02-10 05:40:46 -08002448 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002449 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002450 }
brianosmanfad98562016-05-04 11:06:28 -07002451 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08002452 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07002453 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002454 }
2455 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
2456 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
2457 }
2458 }
reed67f62fa2016-06-29 11:36:34 -07002459
2460 SkString desc;
2461 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
2462
ethannicholas50a8dd02016-02-10 05:40:46 -08002463 return result;
2464}
2465
halcanary9d524f22016-03-29 09:03:52 -07002466SkDrawImageRectCommand* SkDrawImageRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002467 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -07002468 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002469 if (image == nullptr) {
2470 return nullptr;
2471 }
2472 SkRect dst;
2473 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2474 SkPaint* paintPtr;
2475 SkPaint paint;
2476 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08002477 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002478 paintPtr = &paint;
2479 }
2480 else {
2481 paintPtr = nullptr;
2482 }
2483 SkCanvas::SrcRectConstraint constraint;
halcanary9d524f22016-03-29 09:03:52 -07002484 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_STRICT) &&
ethannicholas50a8dd02016-02-10 05:40:46 -08002485 command[SKDEBUGCANVAS_ATTRIBUTE_STRICT].asBool()) {
2486 constraint = SkCanvas::kStrict_SrcRectConstraint;
2487 }
2488 else {
2489 constraint = SkCanvas::kFast_SrcRectConstraint;
2490 }
2491 SkRect* srcPtr;
2492 SkRect src;
2493 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_SRC)) {
2494 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_SRC], &src);
2495 srcPtr = &src;
2496 }
2497 else {
2498 srcPtr = nullptr;
2499 }
reed9ce9d672016-03-17 10:51:11 -07002500 SkDrawImageRectCommand* result = new SkDrawImageRectCommand(image.get(), srcPtr, dst, paintPtr,
ethannicholas50a8dd02016-02-10 05:40:46 -08002501 constraint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002502 return result;
2503}
2504
Brian Osmanc25e2692018-03-12 10:57:28 -04002505SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
2506 const SkRect& dst, const SkPaint* paint)
2507 : INHERITED(kDrawImageNine_OpType)
2508 , fImage(SkRef(image))
2509 , fCenter(center)
2510 , fDst(dst) {
2511 if (paint) {
2512 fPaint = *paint;
2513 fPaintPtr = &fPaint;
2514 } else {
2515 fPaintPtr = nullptr;
2516 }
2517
2518 fInfo.push(SkObjectParser::ImageToString(image));
2519 fInfo.push(SkObjectParser::IRectToString(center));
2520 fInfo.push(SkObjectParser::RectToString(dst, "Dst: "));
2521 if (paint) {
2522 fInfo.push(SkObjectParser::PaintToString(*paint));
2523 }
2524}
2525
2526void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
2527 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaintPtr);
2528}
2529
2530bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
2531 SkAutoCanvasRestore acr(canvas, true);
2532 canvas->clear(0xFFFFFFFF);
2533
2534 xlate_and_scale_to_bounds(canvas, fDst);
2535
2536 this->execute(canvas);
2537 return true;
2538}
2539
2540Json::Value SkDrawImageNineCommand::toJSON(UrlDataManager& urlDataManager) const {
2541 Json::Value result = INHERITED::toJSON(urlDataManager);
2542 Json::Value encoded;
2543 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
2544 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
2545 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
2546 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
2547 if (fPaintPtr != nullptr) {
2548 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr, urlDataManager);
2549 }
2550 }
2551 return result;
2552}
2553
2554SkDrawImageNineCommand* SkDrawImageNineCommand::fromJSON(Json::Value& command,
2555 UrlDataManager& urlDataManager) {
2556 sk_sp<SkImage> image = load_image(command[SKDEBUGCANVAS_ATTRIBUTE_IMAGE], urlDataManager);
2557 if (image == nullptr) {
2558 return nullptr;
2559 }
2560 SkIRect center;
2561 extract_json_irect(command[SKDEBUGCANVAS_ATTRIBUTE_CENTER], &center);
2562 SkRect dst;
2563 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_DST], &dst);
2564 SkPaint* paintPtr;
2565 SkPaint paint;
2566 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
2567 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2568 paintPtr = &paint;
2569 } else {
2570 paintPtr = nullptr;
2571 }
2572 SkDrawImageNineCommand* result = new SkDrawImageNineCommand(image.get(), center, dst, paintPtr);
2573 return result;
2574}
2575
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002576SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002577 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002578 fOval = oval;
2579 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002580
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002581 fInfo.push(SkObjectParser::RectToString(oval));
2582 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00002583}
2584
fmalita8c89c522014-11-08 16:18:56 -08002585void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002586 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002587}
2588
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002589bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002590 canvas->clear(0xFFFFFFFF);
2591 canvas->save();
2592
2593 xlate_and_scale_to_bounds(canvas, fOval);
2594
2595 SkPaint p;
2596 p.setColor(SK_ColorBLACK);
2597 p.setStyle(SkPaint::kStroke_Style);
2598
2599 canvas->drawOval(fOval, p);
2600 canvas->restore();
2601
2602 return true;
2603}
2604
ethannicholasf62a8b72016-02-11 10:35:21 -08002605Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
2606 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002607 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2608 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002609 return result;
2610}
2611
halcanary9d524f22016-03-29 09:03:52 -07002612SkDrawOvalCommand* SkDrawOvalCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002613 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002614 SkRect coords;
2615 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2616 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002617 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002618 return new SkDrawOvalCommand(coords, paint);
2619}
2620
bsalomonac3aa242016-08-19 11:25:19 -07002621SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
2622 bool useCenter, const SkPaint& paint)
Brian Osmanc25e2692018-03-12 10:57:28 -04002623 : INHERITED(kDrawArc_OpType) {
bsalomonac3aa242016-08-19 11:25:19 -07002624 fOval = oval;
2625 fStartAngle = startAngle;
2626 fSweepAngle = sweepAngle;
2627 fUseCenter = useCenter;
2628 fPaint = paint;
2629
2630 fInfo.push(SkObjectParser::RectToString(oval));
2631 fInfo.push(SkObjectParser::ScalarToString(startAngle, "StartAngle: "));
2632 fInfo.push(SkObjectParser::ScalarToString(sweepAngle, "SweepAngle: "));
2633 fInfo.push(SkObjectParser::BoolToString(useCenter));
2634 fInfo.push(SkObjectParser::PaintToString(paint));
2635}
2636
2637void SkDrawArcCommand::execute(SkCanvas* canvas) const {
2638 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
2639}
2640
2641bool SkDrawArcCommand::render(SkCanvas* canvas) const {
2642 canvas->clear(0xFFFFFFFF);
2643 canvas->save();
2644
2645 xlate_and_scale_to_bounds(canvas, fOval);
2646
2647 SkPaint p;
2648 p.setColor(SK_ColorBLACK);
2649 p.setStyle(SkPaint::kStroke_Style);
2650
2651 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
2652 canvas->restore();
2653
2654 return true;
2655}
2656
2657Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
2658 Json::Value result = INHERITED::toJSON(urlDataManager);
2659 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
2660 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
2661 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
2662 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
2663 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2664 return result;
2665}
2666
2667SkDrawArcCommand* SkDrawArcCommand::fromJSON(Json::Value& command,
2668 UrlDataManager& urlDataManager) {
2669 SkRect coords;
2670 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
2671 SkScalar startAngle = command[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE].asFloat();
2672 SkScalar sweepAngle = command[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE].asFloat();
2673 bool useCenter = command[SKDEBUGCANVAS_ATTRIBUTE_USECENTER].asBool();
2674 SkPaint paint;
2675 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2676 return new SkDrawArcCommand(coords, startAngle, sweepAngle, useCenter, paint);
2677}
2678
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002679SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002680 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002681 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002682
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002683 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002684}
2685
fmalita8c89c522014-11-08 16:18:56 -08002686void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002687 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002688}
2689
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002690bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002691 canvas->clear(0xFFFFFFFF);
2692 canvas->drawPaint(fPaint);
2693 return true;
2694}
2695
ethannicholasf62a8b72016-02-11 10:35:21 -08002696Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
2697 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002698 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002699 return result;
2700}
2701
halcanary9d524f22016-03-29 09:03:52 -07002702SkDrawPaintCommand* SkDrawPaintCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002703 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002704 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002705 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002706 return new SkDrawPaintCommand(paint);
2707}
2708
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002709SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002710 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002711 fPath = path;
2712 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002713
robertphillips@google.com91217d02013-03-17 18:33:46 +00002714 fInfo.push(SkObjectParser::PathToString(path));
2715 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002716}
2717
fmalita8c89c522014-11-08 16:18:56 -08002718void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002719 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002720}
2721
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002722bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002723 render_path(canvas, fPath);
2724 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00002725}
2726
ethannicholasf62a8b72016-02-11 10:35:21 -08002727Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2728 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002729 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2730 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002731 return result;
2732}
2733
halcanary9d524f22016-03-29 09:03:52 -07002734SkDrawPathCommand* SkDrawPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002735 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002736 SkPath path;
2737 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
2738 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002739 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002740 return new SkDrawPathCommand(path, paint);
2741}
2742
Brian Osmanc25e2692018-03-12 10:57:28 -04002743SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
2744 : INHERITED(kDrawRegion_OpType) {
2745 fRegion = region;
2746 fPaint = paint;
2747
2748 fInfo.push(SkObjectParser::RegionToString(region));
2749 fInfo.push(SkObjectParser::PaintToString(paint));
2750}
2751
2752void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
2753 canvas->drawRegion(fRegion, fPaint);
2754}
2755
2756bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
2757 render_region(canvas, fRegion);
2758 return true;
2759}
2760
2761Json::Value SkDrawRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
2762 Json::Value result = INHERITED::toJSON(urlDataManager);
2763 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
2764 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2765 return result;
2766}
2767
2768SkDrawRegionCommand* SkDrawRegionCommand::fromJSON(Json::Value& command,
2769 UrlDataManager& urlDataManager) {
2770 SkRegion region;
2771 extract_json_region(command[SKDEBUGCANVAS_ATTRIBUTE_REGION], &region);
2772 SkPaint paint;
2773 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
2774 return new SkDrawRegionCommand(region, paint);
2775}
2776
fmalita160ebb22015-04-01 20:58:37 -07002777SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
2778 const SkMatrix* matrix,
2779 const SkPaint* paint)
2780 : INHERITED(kBeginDrawPicture_OpType)
2781 , fPicture(SkRef(picture)) {
2782
2783 SkString* str = new SkString;
2784 str->appendf("SkPicture: L: %f T: %f R: %f B: %f",
2785 picture->cullRect().fLeft, picture->cullRect().fTop,
2786 picture->cullRect().fRight, picture->cullRect().fBottom);
2787 fInfo.push(str);
robertphillipsb3f319f2014-08-13 10:46:23 -07002788
bsalomon49f085d2014-09-05 13:34:00 -07002789 if (matrix) {
fmalita160ebb22015-04-01 20:58:37 -07002790 fMatrix.set(*matrix);
robertphillipsb3f319f2014-08-13 10:46:23 -07002791 fInfo.push(SkObjectParser::MatrixToString(*matrix));
2792 }
fmalita160ebb22015-04-01 20:58:37 -07002793
bsalomon49f085d2014-09-05 13:34:00 -07002794 if (paint) {
fmalita160ebb22015-04-01 20:58:37 -07002795 fPaint.set(*paint);
robertphillipsb3f319f2014-08-13 10:46:23 -07002796 fInfo.push(SkObjectParser::PaintToString(*paint));
2797 }
fmalita160ebb22015-04-01 20:58:37 -07002798
2799}
2800
2801void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
2802 if (fPaint.isValid()) {
2803 SkRect bounds = fPicture->cullRect();
2804 if (fMatrix.isValid()) {
2805 fMatrix.get()->mapRect(&bounds);
2806 }
2807 canvas->saveLayer(&bounds, fPaint.get());
2808 }
2809
2810 if (fMatrix.isValid()) {
2811 if (!fPaint.isValid()) {
2812 canvas->save();
2813 }
2814 canvas->concat(*fMatrix.get());
2815 }
chudy@google.com902ebe52012-06-29 14:21:22 +00002816}
2817
fmalita160ebb22015-04-01 20:58:37 -07002818bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002819 canvas->clear(0xFFFFFFFF);
2820 canvas->save();
2821
robertphillipsa8d7f0b2014-08-29 08:03:56 -07002822 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002823
robertphillips9b14f262014-06-04 05:40:44 -07002824 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00002825
2826 canvas->restore();
2827
2828 return true;
2829}
2830
fmalita160ebb22015-04-01 20:58:37 -07002831SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
2832 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
2833
2834void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
2835 if (fRestore) {
2836 canvas->restore();
2837 }
2838}
2839
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002840SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002841 const SkPoint pts[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002842 : INHERITED(kDrawPoints_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002843 fMode = mode;
2844 fCount = count;
2845 fPts = new SkPoint[count];
2846 memcpy(fPts, pts, count * sizeof(SkPoint));
2847 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002848
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002849 fInfo.push(SkObjectParser::PointsToString(pts, count));
2850 fInfo.push(SkObjectParser::ScalarToString(SkIntToScalar((unsigned int)count),
2851 "Points: "));
2852 fInfo.push(SkObjectParser::PointModeToString(mode));
2853 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002854}
2855
fmalita8c89c522014-11-08 16:18:56 -08002856void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002857 canvas->drawPoints(fMode, fCount, fPts, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002858}
2859
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002860bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002861 canvas->clear(0xFFFFFFFF);
2862 canvas->save();
2863
2864 SkRect bounds;
2865
2866 bounds.setEmpty();
2867 for (unsigned int i = 0; i < fCount; ++i) {
Mike Reed185ffe92018-01-08 17:09:54 -05002868 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002869 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00002870
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002871 xlate_and_scale_to_bounds(canvas, bounds);
2872
2873 SkPaint p;
2874 p.setColor(SK_ColorBLACK);
2875 p.setStyle(SkPaint::kStroke_Style);
2876
2877 canvas->drawPoints(fMode, fCount, fPts, p);
2878 canvas->restore();
2879
2880 return true;
2881}
2882
ethannicholasf62a8b72016-02-11 10:35:21 -08002883Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
2884 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002885 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
2886 Json::Value points(Json::arrayValue);
2887 for (size_t i = 0; i < fCount; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002888 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002889 }
2890 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07002891 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002892 return result;
2893}
2894
halcanary9d524f22016-03-29 09:03:52 -07002895SkDrawPointsCommand* SkDrawPointsCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002896 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002897 SkCanvas::PointMode mode;
2898 const char* jsonMode = command[SKDEBUGCANVAS_ATTRIBUTE_MODE].asCString();
2899 if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POINTS)) {
2900 mode = SkCanvas::kPoints_PointMode;
2901 }
2902 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_LINES)) {
2903 mode = SkCanvas::kLines_PointMode;
2904 }
2905 else if (!strcmp(jsonMode, SKDEBUGCANVAS_POINTMODE_POLYGON)) {
2906 mode = SkCanvas::kPolygon_PointMode;
2907 }
2908 else {
2909 SkASSERT(false);
2910 return nullptr;
2911 }
2912 Json::Value jsonPoints = command[SKDEBUGCANVAS_ATTRIBUTE_POINTS];
2913 int count = (int) jsonPoints.size();
2914 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2915 for (int i = 0; i < count; i++) {
2916 points[i] = SkPoint::Make(jsonPoints[i][0].asFloat(), jsonPoints[i][1].asFloat());
2917 }
2918 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002919 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002920 SkDrawPointsCommand* result = new SkDrawPointsCommand(mode, count, points, paint);
2921 sk_free(points);
2922 return result;
2923}
2924
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002925SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002926 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002927 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002928 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00002929
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002930 fText = new char[byteLength];
2931 memcpy(fText, text, byteLength);
2932 fByteLength = byteLength;
2933
2934 fPos = new SkPoint[numPts];
2935 memcpy(fPos, pos, numPts * sizeof(SkPoint));
2936
2937 fPaint = paint;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002938
2939 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
chudy@google.com902ebe52012-06-29 14:21:22 +00002940 // TODO(chudy): Test that this works.
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002941 fInfo.push(SkObjectParser::PointsToString(pos, 1));
2942 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002943}
2944
fmalita8c89c522014-11-08 16:18:56 -08002945void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002946 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002947}
2948
ethannicholasf62a8b72016-02-11 10:35:21 -08002949Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2950 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002951 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002952 ((const char*) fText) + fByteLength);
2953 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08002954 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
2955 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002956 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08002957 }
2958 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07002959 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002960 return result;
2961}
2962
halcanary9d524f22016-03-29 09:03:52 -07002963SkDrawPosTextCommand* SkDrawPosTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08002964 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08002965 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
2966 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08002967 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08002968 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
2969 int count = (int) coords.size();
2970 SkPoint* points = (SkPoint*) sk_malloc_throw(count * sizeof(SkPoint));
2971 for (int i = 0; i < count; i++) {
2972 points[i] = SkPoint::Make(coords[i][0].asFloat(), coords[i][1].asFloat());
2973 }
2974 return new SkDrawPosTextCommand(text, strlen(text), points, paint);
2975}
chudy@google.com902ebe52012-06-29 14:21:22 +00002976
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002977SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
2978 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002979 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002980 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002981 size_t numPts = paint.countText(text, byteLength);
2982
2983 fText = new char[byteLength];
2984 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00002985 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00002986
2987 fXpos = new SkScalar[numPts];
2988 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
2989
robertphillips@google.com91217d02013-03-17 18:33:46 +00002990 fConstY = constY;
2991 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002992
robertphillips@google.com91217d02013-03-17 18:33:46 +00002993 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
2994 fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: "));
2995 fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: "));
2996 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00002997}
2998
fmalita8c89c522014-11-08 16:18:56 -08002999void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003000 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003001}
3002
bungeman51190df2016-03-09 07:42:54 -08003003Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
3004 Json::Value result = INHERITED::toJSON(urlDataManager);
3005 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3006 ((const char*) fText) + fByteLength);
3007 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
3008 Json::Value xpos(Json::arrayValue);
3009 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
3010 for (size_t i = 0; i < numXpos; i++) {
3011 xpos.append(Json::Value(fXpos[i]));
3012 }
3013 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07003014 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08003015 return result;
3016}
3017
3018SkDrawPosTextHCommand* SkDrawPosTextHCommand::fromJSON(Json::Value& command,
3019 UrlDataManager& urlDataManager) {
3020 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3021 SkPaint paint;
3022 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3023 Json::Value jsonXpos = command[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3024 int count = (int) jsonXpos.size();
3025 SkScalar* xpos = (SkScalar*) sk_malloc_throw(count * sizeof(SkScalar));
3026 for (int i = 0; i < count; i++) {
3027 xpos[i] = jsonXpos[i].asFloat();
3028 }
3029 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3030 return new SkDrawPosTextHCommand(text, strlen(text), xpos, y, paint);
3031}
3032
fmalita0d48e412016-01-04 08:08:04 -08003033static const char* gPositioningLabels[] = {
3034 "kDefault_Positioning",
3035 "kHorizontal_Positioning",
3036 "kFull_Positioning",
3037};
3038
fmalita37283c22016-09-13 10:00:23 -07003039SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07003040 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003041 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07003042 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07003043 , fXPos(x)
3044 , fYPos(y)
3045 , fPaint(paint) {
3046
Ben Wagner145dbcd2016-11-03 14:40:50 -04003047 std::unique_ptr<SkString> runsStr(new SkString);
fmalitab7425172014-08-26 07:56:44 -07003048 fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
fmalitaff3106c2014-12-09 05:28:20 -08003049 fInfo.push(SkObjectParser::ScalarToString(y, "YPOS: "));
3050 fInfo.push(SkObjectParser::RectToString(fBlob->bounds(), "Bounds: "));
Ben Wagner145dbcd2016-11-03 14:40:50 -04003051 fInfo.push(runsStr.get());
fmalitab7425172014-08-26 07:56:44 -07003052 fInfo.push(SkObjectParser::PaintToString(paint));
fmalitae77f2da2015-12-08 18:59:18 -08003053
3054 unsigned runs = 0;
3055 SkPaint runPaint(paint);
fmalita02526bd2016-09-14 14:55:59 -07003056 SkTextBlobRunIterator iter(fBlob.get());
fmalitae77f2da2015-12-08 18:59:18 -08003057 while (!iter.done()) {
Ben Wagner145dbcd2016-11-03 14:40:50 -04003058 std::unique_ptr<SkString> tmpStr(new SkString);
fmalita0d48e412016-01-04 08:08:04 -08003059 tmpStr->printf("==== Run [%d] ====", runs++);
3060 fInfo.push(tmpStr.release());
fmalitae77f2da2015-12-08 18:59:18 -08003061
3062 fInfo.push(SkObjectParser::IntToString(iter.glyphCount(), "GlyphCount: "));
fmalita0d48e412016-01-04 08:08:04 -08003063 tmpStr.reset(new SkString("GlyphPositioning: "));
3064 tmpStr->append(gPositioningLabels[iter.positioning()]);
3065 fInfo.push(tmpStr.release());
3066
fmalitae77f2da2015-12-08 18:59:18 -08003067 iter.applyFontToPaint(&runPaint);
3068 fInfo.push(SkObjectParser::PaintToString(runPaint));
3069
3070 iter.next();
3071 }
3072
3073 runsStr->printf("Runs: %d", runs);
3074 // runStr is owned by fInfo at this point.
3075 runsStr.release();
fmalitab7425172014-08-26 07:56:44 -07003076}
3077
fmalita8c89c522014-11-08 16:18:56 -08003078void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07003079 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
3080}
3081
fmalita55773872014-08-29 15:08:20 -07003082bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
3083 canvas->clear(SK_ColorWHITE);
3084 canvas->save();
3085
3086 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
3087 xlate_and_scale_to_bounds(canvas, bounds);
3088
fmalita37283c22016-09-13 10:00:23 -07003089 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07003090
3091 canvas->restore();
3092
3093 return true;
3094}
3095
ethannicholasf62a8b72016-02-11 10:35:21 -08003096Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
3097 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003098 Json::Value runs(Json::arrayValue);
3099 SkTextBlobRunIterator iter(fBlob.get());
3100 while (!iter.done()) {
3101 Json::Value run(Json::objectValue);
3102 Json::Value jsonPositions(Json::arrayValue);
3103 Json::Value jsonGlyphs(Json::arrayValue);
3104 const SkScalar* iterPositions = iter.pos();
3105 const uint16_t* iterGlyphs = iter.glyphs();
3106 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
3107 switch (iter.positioning()) {
3108 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07003109 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
3110 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08003111 break;
3112 case SkTextBlob::kHorizontal_Positioning:
3113 jsonPositions.append(Json::Value(iterPositions[i]));
3114 break;
3115 case SkTextBlob::kDefault_Positioning:
3116 break;
3117 }
3118 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
3119 }
3120 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
3121 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
3122 }
3123 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
3124 SkPaint fontPaint;
3125 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07003126 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
3127 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08003128 runs.append(run);
3129 iter.next();
3130 }
reed6d2c3e72016-07-07 14:10:14 -07003131 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08003132 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
3133 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
3134 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07003135 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07003136 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07003137
3138 SkString desc;
3139 // make the bounds local by applying the x,y
3140 bounds.offset(fXPos, fYPos);
3141 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
3142
ethannicholas50a8dd02016-02-10 05:40:46 -08003143 return result;
3144}
3145
halcanary9d524f22016-03-29 09:03:52 -07003146SkDrawTextBlobCommand* SkDrawTextBlobCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003147 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003148 SkTextBlobBuilder builder;
3149 Json::Value runs = command[SKDEBUGCANVAS_ATTRIBUTE_RUNS];
3150 for (Json::ArrayIndex i = 0 ; i < runs.size(); i++) {
3151 Json::Value run = runs[i];
3152 SkPaint font;
3153 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
ethannicholasf62a8b72016-02-11 10:35:21 -08003154 extract_json_paint(run[SKDEBUGCANVAS_ATTRIBUTE_FONT], urlDataManager, &font);
ethannicholas50a8dd02016-02-10 05:40:46 -08003155 Json::Value glyphs = run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS];
3156 int count = glyphs.size();
3157 Json::Value coords = run[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
3158 SkScalar x = coords[0].asFloat();
3159 SkScalar y = coords[1].asFloat();
reed6d2c3e72016-07-07 14:10:14 -07003160 SkRect bounds;
3161 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &bounds);
3162
ethannicholas50a8dd02016-02-10 05:40:46 -08003163 if (run.isMember(SKDEBUGCANVAS_ATTRIBUTE_POSITIONS)) {
3164 Json::Value positions = run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS];
3165 if (positions.size() > 0 && positions[0].isNumeric()) {
reed6d2c3e72016-07-07 14:10:14 -07003166 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPosH(font, count, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003167 for (int j = 0; j < count; j++) {
3168 buffer.glyphs[j] = glyphs[j].asUInt();
3169 buffer.pos[j] = positions[j].asFloat();
3170 }
3171 }
3172 else {
reed6d2c3e72016-07-07 14:10:14 -07003173 SkTextBlobBuilder::RunBuffer buffer = builder.allocRunPos(font, count, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003174 for (int j = 0; j < count; j++) {
3175 buffer.glyphs[j] = glyphs[j].asUInt();
3176 buffer.pos[j * 2] = positions[j][0].asFloat();
3177 buffer.pos[j * 2 + 1] = positions[j][1].asFloat();
3178 }
3179 }
3180 }
3181 else {
reed6d2c3e72016-07-07 14:10:14 -07003182 SkTextBlobBuilder::RunBuffer buffer = builder.allocRun(font, count, x, y, &bounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003183 for (int j = 0; j < count; j++) {
3184 buffer.glyphs[j] = glyphs[j].asUInt();
3185 }
3186 }
3187 }
3188 SkScalar x = command[SKDEBUGCANVAS_ATTRIBUTE_X].asFloat();
3189 SkScalar y = command[SKDEBUGCANVAS_ATTRIBUTE_Y].asFloat();
3190 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003191 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
fmalita37283c22016-09-13 10:00:23 -07003192 return new SkDrawTextBlobCommand(builder.make(), x, y, paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003193}
3194
robertphillips9bafc302015-02-13 11:13:00 -08003195SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04003196 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08003197 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003198 : INHERITED(kDrawPatch_OpType)
3199 , fBlendMode(bmode)
3200{
robertphillips9bafc302015-02-13 11:13:00 -08003201 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08003202 if (colors != nullptr) {
3203 memcpy(fColors, colors, sizeof(fColors));
3204 fColorsPtr = fColors;
3205 } else {
3206 fColorsPtr = nullptr;
3207 }
3208 if (texCoords != nullptr) {
3209 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
3210 fTexCoordsPtr = fTexCoords;
3211 } else {
3212 fTexCoordsPtr = nullptr;
3213 }
robertphillips9bafc302015-02-13 11:13:00 -08003214 fPaint = paint;
3215
3216 fInfo.push(SkObjectParser::PaintToString(paint));
3217}
3218
3219void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04003220 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08003221}
3222
ethannicholasf62a8b72016-02-11 10:35:21 -08003223Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
3224 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08003225 Json::Value cubics = Json::Value(Json::arrayValue);
3226 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003227 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003228 }
3229 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
3230 if (fColorsPtr != nullptr) {
3231 Json::Value colors = Json::Value(Json::arrayValue);
3232 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003233 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003234 }
3235 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
3236 }
3237 if (fTexCoordsPtr != nullptr) {
3238 Json::Value texCoords = Json::Value(Json::arrayValue);
3239 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07003240 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08003241 }
3242 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
3243 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003244 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08003245 return result;
3246}
3247
halcanary9d524f22016-03-29 09:03:52 -07003248SkDrawPatchCommand* SkDrawPatchCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003249 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08003250 Json::Value jsonCubics = command[SKDEBUGCANVAS_ATTRIBUTE_CUBICS];
3251 SkPoint cubics[12];
3252 for (int i = 0; i < 12; i++) {
3253 cubics[i] = get_json_point(jsonCubics[i]);
3254 }
3255 SkColor* colorsPtr;
3256 SkColor colors[4];
3257 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_COLORS)) {
3258 Json::Value jsonColors = command[SKDEBUGCANVAS_ATTRIBUTE_COLORS];
3259 for (int i = 0; i < 4; i++) {
3260 colors[i] = get_json_color(jsonColors[i]);
3261 }
3262 colorsPtr = colors;
3263 }
3264 else {
3265 colorsPtr = nullptr;
3266 }
3267 SkPoint* texCoordsPtr;
3268 SkPoint texCoords[4];
3269 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS)) {
3270 Json::Value jsonTexCoords = command[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS];
3271 for (int i = 0; i < 4; i++) {
3272 texCoords[i] = get_json_point(jsonTexCoords[i]);
3273 }
3274 texCoordsPtr = texCoords;
3275 }
3276 else {
3277 texCoordsPtr = nullptr;
3278 }
Mike Reed7d954ad2016-10-28 15:42:34 -04003279
3280 SkBlendMode bmode = SkBlendMode::kSrcOver; // TODO: extract from json
3281
ethannicholas1446a9a2016-02-10 14:05:02 -08003282 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003283 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
Mike Reed7d954ad2016-10-28 15:42:34 -04003284 return new SkDrawPatchCommand(cubics, colorsPtr, texCoordsPtr, bmode, paint);
robertphillips9bafc302015-02-13 11:13:00 -08003285}
3286
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003287SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003288 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003289 fRect = rect;
3290 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003291
robertphillips@google.com91217d02013-03-17 18:33:46 +00003292 fInfo.push(SkObjectParser::RectToString(rect));
3293 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003294}
3295
fmalita8c89c522014-11-08 16:18:56 -08003296void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00003297 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003298}
3299
ethannicholasf62a8b72016-02-11 10:35:21 -08003300Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3301 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07003302 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
3303 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07003304
3305 SkString desc;
3306 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
3307
ethannicholas50a8dd02016-02-10 05:40:46 -08003308 return result;
3309}
3310
halcanary9d524f22016-03-29 09:03:52 -07003311SkDrawRectCommand* SkDrawRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003312 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003313 SkRect coords;
3314 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3315 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003316 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003317 return new SkDrawRectCommand(coords, paint);
3318}
3319
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003320SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003321 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003322 fRRect = rrect;
3323 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00003324
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003325 fInfo.push(SkObjectParser::RRectToString(rrect));
3326 fInfo.push(SkObjectParser::PaintToString(paint));
robertphillips@google.com67baba42013-01-02 20:20:31 +00003327}
3328
fmalita8c89c522014-11-08 16:18:56 -08003329void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00003330 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00003331}
3332
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003333bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00003334 render_rrect(canvas, fRRect);
3335 return true;
3336}
3337
ethannicholasf62a8b72016-02-11 10:35:21 -08003338Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3339 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003340 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07003341 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003342 return result;
3343}
3344
halcanary9d524f22016-03-29 09:03:52 -07003345SkDrawRRectCommand* SkDrawRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003346 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003347 SkRRect coords;
3348 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_COORDS], &coords);
3349 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003350 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003351 return new SkDrawRRectCommand(coords, paint);
3352}
3353
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00003354SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003355 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003356 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003357 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003358 fOuter = outer;
3359 fInner = inner;
3360 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003361
3362 fInfo.push(SkObjectParser::RRectToString(outer));
3363 fInfo.push(SkObjectParser::RRectToString(inner));
3364 fInfo.push(SkObjectParser::PaintToString(paint));
3365}
3366
fmalita8c89c522014-11-08 16:18:56 -08003367void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00003368 canvas->drawDRRect(fOuter, fInner, fPaint);
3369}
3370
3371bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
3372 render_drrect(canvas, fOuter, fInner);
3373 return true;
3374}
3375
ethannicholasf62a8b72016-02-11 10:35:21 -08003376Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
3377 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003378 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
3379 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07003380 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003381 return result;
3382}
3383
halcanary9d524f22016-03-29 09:03:52 -07003384SkDrawDRRectCommand* SkDrawDRRectCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003385 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003386 SkRRect outer;
3387 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &outer);
3388 SkRRect inner;
3389 extract_json_rrect(command[SKDEBUGCANVAS_ATTRIBUTE_INNER], &inner);
3390 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003391 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003392 return new SkDrawDRRectCommand(outer, inner, paint);
3393}
3394
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003395SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003396 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003397 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003398 fText = new char[byteLength];
3399 memcpy(fText, text, byteLength);
3400 fByteLength = byteLength;
3401 fX = x;
3402 fY = y;
3403 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003404
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003405 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3406 fInfo.push(SkObjectParser::ScalarToString(x, "SkScalar x: "));
3407 fInfo.push(SkObjectParser::ScalarToString(y, "SkScalar y: "));
3408 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003409}
3410
fmalita8c89c522014-11-08 16:18:56 -08003411void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003412 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003413}
3414
ethannicholasf62a8b72016-02-11 10:35:21 -08003415Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
3416 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003417 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003418 ((const char*) fText) + fByteLength);
3419 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003420 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
3421 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003422 return result;
3423}
3424
halcanary9d524f22016-03-29 09:03:52 -07003425SkDrawTextCommand* SkDrawTextCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003426 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003427 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3428 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003429 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003430 Json::Value coords = command[SKDEBUGCANVAS_ATTRIBUTE_COORDS];
halcanary9d524f22016-03-29 09:03:52 -07003431 return new SkDrawTextCommand(text, strlen(text), coords[0].asFloat(), coords[1].asFloat(),
ethannicholas50a8dd02016-02-10 05:40:46 -08003432 paint);
3433}
3434
reed45561a02016-07-07 12:47:17 -07003435///////////////////////////////////////////////////////////////////////////////////////////////////
3436
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00003437SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
3438 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003439 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08003440 : INHERITED(kDrawTextOnPath_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003441 fText = new char[byteLength];
3442 memcpy(fText, text, byteLength);
3443 fByteLength = byteLength;
3444 fPath = path;
bsalomon49f085d2014-09-05 13:34:00 -07003445 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003446 fMatrix = *matrix;
3447 } else {
3448 fMatrix.setIdentity();
3449 }
3450 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00003451
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003452 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3453 fInfo.push(SkObjectParser::PathToString(path));
bsalomon49f085d2014-09-05 13:34:00 -07003454 if (matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003455 fInfo.push(SkObjectParser::MatrixToString(*matrix));
3456 }
3457 fInfo.push(SkObjectParser::PaintToString(paint));
chudy@google.com902ebe52012-06-29 14:21:22 +00003458}
3459
fmalita8c89c522014-11-08 16:18:56 -08003460void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003461 canvas->drawTextOnPath(fText, fByteLength, fPath,
halcanary96fcdcc2015-08-27 07:41:13 -07003462 fMatrix.isIdentity() ? nullptr : &fMatrix,
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003463 fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003464}
3465
ethannicholasf62a8b72016-02-11 10:35:21 -08003466Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
3467 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07003468 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08003469 ((const char*) fText) + fByteLength);
3470 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07003471 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08003472 if (!fMatrix.isIdentity()) {
joshualittbd724132016-03-03 11:39:38 -08003473 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003474 }
brianosmanfad98562016-05-04 11:06:28 -07003475 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003476 return result;
3477}
3478
halcanary9d524f22016-03-29 09:03:52 -07003479SkDrawTextOnPathCommand* SkDrawTextOnPathCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003480 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003481 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3482 SkPaint paint;
ethannicholasf62a8b72016-02-11 10:35:21 -08003483 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003484 SkPath path;
3485 extract_json_path(command[SKDEBUGCANVAS_ATTRIBUTE_PATH], &path);
3486 SkMatrix* matrixPtr;
3487 SkMatrix matrix;
3488 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_MATRIX)) {
3489 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3490 matrixPtr = &matrix;
3491 }
3492 else {
3493 matrixPtr = nullptr;
3494 }
3495 return new SkDrawTextOnPathCommand(text, strlen(text), path, matrixPtr, paint);
3496}
3497
reed45561a02016-07-07 12:47:17 -07003498///////////////////////////////////////////////////////////////////////////////////////////////////
3499
3500SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
3501 const SkRSXform xform[], const SkRect* cull,
3502 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07003503 : INHERITED(kDrawTextRSXform_OpType)
reed45561a02016-07-07 12:47:17 -07003504{
3505 fText = new char[byteLength];
3506 memcpy(fText, text, byteLength);
3507 fByteLength = byteLength;
3508 int count = paint.countText(text, byteLength);
3509 fXform = new SkRSXform[count];
3510 memcpy(fXform, xform, count * sizeof(SkRSXform));
3511 if (cull) {
3512 fCullStorage = *cull;
3513 fCull = &fCullStorage;
3514 } else {
3515 fCull = nullptr;
3516 }
3517 fPaint = paint;
3518
3519 fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding()));
3520 fInfo.push(SkObjectParser::PaintToString(paint));
3521}
3522
3523void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
3524 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull, fPaint);
3525}
3526
3527Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
3528 Json::Value result = INHERITED::toJSON(urlDataManager);
3529 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
3530 ((const char*) fText) + fByteLength);
3531 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
3532 return result;
3533}
3534
3535SkDrawTextRSXformCommand* SkDrawTextRSXformCommand::fromJSON(Json::Value& command,
3536 UrlDataManager& urlDataManager) {
3537 const char* text = command[SKDEBUGCANVAS_ATTRIBUTE_TEXT].asCString();
3538 size_t byteLength = strlen(text);
3539 SkPaint paint;
3540 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
3541
3542 // TODO: handle xform and cull
3543 int count = paint.countText(text, byteLength);
3544 SkAutoTArray<SkRSXform> xform(count);
3545 for (int i = 0; i < count; ++i) {
3546 xform[i].fSCos = 1;
3547 xform[i].fSSin = xform[i].fTx = xform[i].fTy = 0;
3548 }
3549 return new SkDrawTextRSXformCommand(text, byteLength, &xform[0], nullptr, paint);
3550}
3551
3552///////////////////////////////////////////////////////////////////////////////////////////////////
3553
Mike Reedfed9cfd2017-03-17 12:09:04 -04003554SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003555 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003556 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003557 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04003558 , fBlendMode(bmode)
Mike Reedfed9cfd2017-03-17 12:09:04 -04003559 , fPaint(paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04003560{
chudy@google.com902ebe52012-06-29 14:21:22 +00003561 // TODO(chudy)
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003562 fInfo.push(SkObjectParser::CustomTextToString("To be implemented."));
3563 fInfo.push(SkObjectParser::PaintToString(paint));
3564}
3565
fmalita8c89c522014-11-08 16:18:56 -08003566void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04003567 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00003568}
3569
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003570SkRestoreCommand::SkRestoreCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003571 : INHERITED(kRestore_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003572 fInfo.push(SkObjectParser::CustomTextToString("No Parameters"));
chudy@google.com902ebe52012-06-29 14:21:22 +00003573}
3574
fmalita8c89c522014-11-08 16:18:56 -08003575void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00003576 canvas->restore();
3577}
3578
ethannicholasf62a8b72016-02-11 10:35:21 -08003579SkRestoreCommand* SkRestoreCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003580 return new SkRestoreCommand();
3581}
3582
Florin Malita5f6102d2014-06-30 10:13:28 -04003583SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08003584 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00003585}
3586
fmalita8c89c522014-11-08 16:18:56 -08003587void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04003588 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00003589}
3590
ethannicholasf62a8b72016-02-11 10:35:21 -08003591SkSaveCommand* SkSaveCommand::fromJSON(Json::Value& command, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003592 return new SkSaveCommand();
3593}
3594
reed4960eee2015-12-18 07:09:18 -08003595SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
robertphillips9bafc302015-02-13 11:13:00 -08003596 : INHERITED(kSaveLayer_OpType) {
reed4960eee2015-12-18 07:09:18 -08003597 if (rec.fBounds) {
3598 fBounds = *rec.fBounds;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003599 } else {
3600 fBounds.setEmpty();
3601 }
chudy@google.com902ebe52012-06-29 14:21:22 +00003602
reed4960eee2015-12-18 07:09:18 -08003603 if (rec.fPaint) {
3604 fPaint = *rec.fPaint;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003605 fPaintPtr = &fPaint;
3606 } else {
halcanary96fcdcc2015-08-27 07:41:13 -07003607 fPaintPtr = nullptr;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003608 }
reed4960eee2015-12-18 07:09:18 -08003609 fSaveLayerFlags = rec.fSaveLayerFlags;
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003610
ethannicholas50a8dd02016-02-10 05:40:46 -08003611 if (rec.fBackdrop) {
3612 fBackdrop = rec.fBackdrop;
3613 fBackdrop->ref();
3614 } else {
3615 fBackdrop = nullptr;
3616 }
3617
reed4960eee2015-12-18 07:09:18 -08003618 if (rec.fBounds) {
3619 fInfo.push(SkObjectParser::RectToString(*rec.fBounds, "Bounds: "));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003620 }
reed4960eee2015-12-18 07:09:18 -08003621 if (rec.fPaint) {
3622 fInfo.push(SkObjectParser::PaintToString(*rec.fPaint));
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00003623 }
reed4960eee2015-12-18 07:09:18 -08003624 fInfo.push(SkObjectParser::SaveLayerFlagsToString(fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003625}
3626
ethannicholas50a8dd02016-02-10 05:40:46 -08003627SkSaveLayerCommand::~SkSaveLayerCommand() {
3628 if (fBackdrop != nullptr) {
3629 fBackdrop->unref();
3630 }
3631}
3632
fmalita8c89c522014-11-08 16:18:56 -08003633void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
reed4960eee2015-12-18 07:09:18 -08003634 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.isEmpty() ? nullptr : &fBounds,
3635 fPaintPtr,
3636 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00003637}
3638
fmalita8c89c522014-11-08 16:18:56 -08003639void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) const {
commit-bot@chromium.org1643b2c2014-03-03 23:25:41 +00003640 canvas->save();
3641}
3642
ethannicholasf62a8b72016-02-11 10:35:21 -08003643Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
3644 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003645 if (!fBounds.isEmpty()) {
brianosmanfad98562016-05-04 11:06:28 -07003646 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(fBounds);
ethannicholas50a8dd02016-02-10 05:40:46 -08003647 }
3648 if (fPaintPtr != nullptr) {
brianosmanfad98562016-05-04 11:06:28 -07003649 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaintPtr,
ethannicholasf62a8b72016-02-11 10:35:21 -08003650 urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003651 }
3652 if (fBackdrop != nullptr) {
3653 Json::Value jsonBackdrop;
ethannicholasf62a8b72016-02-11 10:35:21 -08003654 flatten(fBackdrop, &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003655 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
3656 }
3657 if (fSaveLayerFlags != 0) {
3658 SkDebugf("unsupported: saveLayer flags\n");
3659 SkASSERT(false);
3660 }
3661 return result;
3662}
3663
halcanary9d524f22016-03-29 09:03:52 -07003664SkSaveLayerCommand* SkSaveLayerCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003665 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003666 SkCanvas::SaveLayerRec rec;
3667 SkRect bounds;
3668 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BOUNDS)) {
3669 extract_json_rect(command[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS], &bounds);
3670 rec.fBounds = &bounds;
3671 }
3672 SkPaint paint;
3673 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_PAINT)) {
ethannicholasf62a8b72016-02-11 10:35:21 -08003674 extract_json_paint(command[SKDEBUGCANVAS_ATTRIBUTE_PAINT], urlDataManager, &paint);
ethannicholas50a8dd02016-02-10 05:40:46 -08003675 rec.fPaint = &paint;
3676 }
3677 if (command.isMember(SKDEBUGCANVAS_ATTRIBUTE_BACKDROP)) {
3678 Json::Value backdrop = command[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP];
ethannicholasf62a8b72016-02-11 10:35:21 -08003679 rec.fBackdrop = (SkImageFilter*) load_flattenable(backdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08003680 }
3681 SkSaveLayerCommand* result = new SkSaveLayerCommand(rec);
3682 if (rec.fBackdrop != nullptr) {
3683 rec.fBackdrop->unref();
3684 }
3685 return result;
3686}
3687
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00003688SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08003689 : INHERITED(kSetMatrix_OpType) {
robertphillips70171682014-10-16 14:28:28 -07003690 fUserMatrix.reset();
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003691 fMatrix = matrix;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00003692 fInfo.push(SkObjectParser::MatrixToString(matrix));
chudy@google.com902ebe52012-06-29 14:21:22 +00003693}
3694
robertphillips70171682014-10-16 14:28:28 -07003695void SkSetMatrixCommand::setUserMatrix(const SkMatrix& userMatrix) {
3696 fUserMatrix = userMatrix;
3697}
3698
fmalita8c89c522014-11-08 16:18:56 -08003699void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
robertphillips70171682014-10-16 14:28:28 -07003700 SkMatrix temp = SkMatrix::Concat(fUserMatrix, fMatrix);
3701 canvas->setMatrix(temp);
chudy@google.com902ebe52012-06-29 14:21:22 +00003702}
3703
ethannicholasf62a8b72016-02-11 10:35:21 -08003704Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
3705 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08003706 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08003707 return result;
3708}
3709
halcanary9d524f22016-03-29 09:03:52 -07003710SkSetMatrixCommand* SkSetMatrixCommand::fromJSON(Json::Value& command,
ethannicholasf62a8b72016-02-11 10:35:21 -08003711 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08003712 SkMatrix matrix;
3713 extract_json_matrix(command[SKDEBUGCANVAS_ATTRIBUTE_MATRIX], &matrix);
3714 return new SkSetMatrixCommand(matrix);
3715}