blob: 001911c975146073df4d38ec18c51faf63ca703b [file] [log] [blame]
chudy@google.com902ebe52012-06-29 14:21:22 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
chudy@google.com902ebe52012-06-29 14:21:22 +00008#include "SkDrawCommand.h"
joshualitt6b3cf732016-02-17 11:20:26 -08009
halcanarya73d76a2016-10-17 13:19:02 -070010#include "png.h"
11
Hal Canary95e3c052017-01-11 12:44:43 -050012#include "SkAutoMalloc.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080013#include "SkColorFilter.h"
14#include "SkDashPathEffect.h"
15#include "SkImageFilter.h"
brianosmanfad98562016-05-04 11:06:28 -070016#include "SkJsonWriteBuffer.h"
Mike Reed80747ef2018-01-23 15:29:32 -050017#include "SkMaskFilterBase.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080018#include "SkPaintDefaults.h"
19#include "SkPathEffect.h"
robertphillips9bafc302015-02-13 11:13:00 -080020#include "SkPicture.h"
Mike Reedfadbfcd2017-12-06 16:09:20 -050021#include "SkReadBuffer.h"
Mike Reed185ffe92018-01-08 17:09:54 -050022#include "SkRectPriv.h"
fmalitab7425172014-08-26 07:56:44 -070023#include "SkTextBlob.h"
fmalitae77f2da2015-12-08 18:59:18 -080024#include "SkTextBlobRunIterator.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080025#include "SkTHash.h"
26#include "SkTypeface.h"
ethannicholas50a8dd02016-02-10 05:40:46 -080027#include "SkWriteBuffer.h"
msaretta5cf4f42016-06-30 10:06:51 -070028#include "picture_utils.h"
Mike Reedebfce6d2016-12-12 10:02:12 -050029#include "SkClipOpPriv.h"
Stan Ilievac42aeb2017-01-12 16:20:50 -050030#include <SkLatticeIter.h>
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -040031#include <SkShadowFlags.h>
ethannicholas50a8dd02016-02-10 05:40:46 -080032
ethannicholas50a8dd02016-02-10 05:40:46 -080033#define SKDEBUGCANVAS_ATTRIBUTE_COMMAND "command"
ethannicholas807dcab2016-02-23 06:53:37 -080034#define SKDEBUGCANVAS_ATTRIBUTE_VISIBLE "visible"
ethannicholas50a8dd02016-02-10 05:40:46 -080035#define SKDEBUGCANVAS_ATTRIBUTE_MATRIX "matrix"
vjiaoblacke5de1302016-07-13 14:05:28 -070036#define SKDEBUGCANVAS_ATTRIBUTE_DRAWDEPTHTRANS "drawDepthTranslation"
ethannicholas50a8dd02016-02-10 05:40:46 -080037#define SKDEBUGCANVAS_ATTRIBUTE_COORDS "coords"
halcanaryf412f092016-08-25 11:10:41 -070038#define SKDEBUGCANVAS_ATTRIBUTE_HINTING "hinting"
ethannicholas50a8dd02016-02-10 05:40:46 -080039#define SKDEBUGCANVAS_ATTRIBUTE_BOUNDS "bounds"
40#define SKDEBUGCANVAS_ATTRIBUTE_PAINT "paint"
41#define SKDEBUGCANVAS_ATTRIBUTE_OUTER "outer"
42#define SKDEBUGCANVAS_ATTRIBUTE_INNER "inner"
43#define SKDEBUGCANVAS_ATTRIBUTE_MODE "mode"
44#define SKDEBUGCANVAS_ATTRIBUTE_POINTS "points"
45#define SKDEBUGCANVAS_ATTRIBUTE_PATH "path"
46#define SKDEBUGCANVAS_ATTRIBUTE_TEXT "text"
47#define SKDEBUGCANVAS_ATTRIBUTE_COLOR "color"
48#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Florin Malita82d80872017-06-06 16:58:40 -040049#define SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE "blendMode"
ethannicholas50a8dd02016-02-10 05:40:46 -080050#define SKDEBUGCANVAS_ATTRIBUTE_STYLE "style"
51#define SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH "strokeWidth"
52#define SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER "strokeMiter"
ethannicholas1446a9a2016-02-10 14:05:02 -080053#define SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN "strokeJoin"
ethannicholas50a8dd02016-02-10 05:40:46 -080054#define SKDEBUGCANVAS_ATTRIBUTE_CAP "cap"
55#define SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS "antiAlias"
ethannicholas1446a9a2016-02-10 14:05:02 -080056#define SKDEBUGCANVAS_ATTRIBUTE_DITHER "dither"
Ben Wagner78f1f5a2017-06-23 14:35:07 -040057#define SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT "fakeBoldText"
58#define SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT "linearText"
59#define SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT "subpixelText"
60#define SKDEBUGCANVAS_ATTRIBUTE_DEVKERNTEXT "devKernText"
61#define SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT "lcdRenderText"
62#define SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT "embeddedBitmapText"
63#define SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING "forceAutoHinting"
64#define SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT "verticalText"
ethannicholas50a8dd02016-02-10 05:40:46 -080065#define SKDEBUGCANVAS_ATTRIBUTE_REGION "region"
66#define SKDEBUGCANVAS_ATTRIBUTE_REGIONOP "op"
67#define SKDEBUGCANVAS_ATTRIBUTE_EDGESTYLE "edgeStyle"
68#define SKDEBUGCANVAS_ATTRIBUTE_DEVICEREGION "deviceRegion"
69#define SKDEBUGCANVAS_ATTRIBUTE_BLUR "blur"
70#define SKDEBUGCANVAS_ATTRIBUTE_SIGMA "sigma"
71#define SKDEBUGCANVAS_ATTRIBUTE_QUALITY "quality"
72#define SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN "textAlign"
73#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE "textSize"
74#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX "textScaleX"
75#define SKDEBUGCANVAS_ATTRIBUTE_TEXTSKEWX "textSkewX"
76#define SKDEBUGCANVAS_ATTRIBUTE_DASHING "dashing"
77#define SKDEBUGCANVAS_ATTRIBUTE_INTERVALS "intervals"
78#define SKDEBUGCANVAS_ATTRIBUTE_PHASE "phase"
79#define SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE "fillType"
80#define SKDEBUGCANVAS_ATTRIBUTE_VERBS "verbs"
81#define SKDEBUGCANVAS_ATTRIBUTE_NAME "name"
ethannicholasf62a8b72016-02-11 10:35:21 -080082#define SKDEBUGCANVAS_ATTRIBUTE_DATA "data"
brianosmanfad98562016-05-04 11:06:28 -070083#define SKDEBUGCANVAS_ATTRIBUTE_VALUES "values"
ethannicholas50a8dd02016-02-10 05:40:46 -080084#define SKDEBUGCANVAS_ATTRIBUTE_SHADER "shader"
85#define SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT "pathEffect"
86#define SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER "maskFilter"
87#define SKDEBUGCANVAS_ATTRIBUTE_XFERMODE "xfermode"
ethannicholas1446a9a2016-02-10 14:05:02 -080088#define SKDEBUGCANVAS_ATTRIBUTE_LOOPER "looper"
ethannicholas50a8dd02016-02-10 05:40:46 -080089#define SKDEBUGCANVAS_ATTRIBUTE_BACKDROP "backdrop"
90#define SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER "colorfilter"
91#define SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER "imagefilter"
92#define SKDEBUGCANVAS_ATTRIBUTE_IMAGE "image"
93#define SKDEBUGCANVAS_ATTRIBUTE_BITMAP "bitmap"
94#define SKDEBUGCANVAS_ATTRIBUTE_SRC "src"
95#define SKDEBUGCANVAS_ATTRIBUTE_DST "dst"
96#define SKDEBUGCANVAS_ATTRIBUTE_CENTER "center"
97#define SKDEBUGCANVAS_ATTRIBUTE_STRICT "strict"
98#define SKDEBUGCANVAS_ATTRIBUTE_DESCRIPTION "description"
99#define SKDEBUGCANVAS_ATTRIBUTE_X "x"
100#define SKDEBUGCANVAS_ATTRIBUTE_Y "y"
101#define SKDEBUGCANVAS_ATTRIBUTE_RUNS "runs"
102#define SKDEBUGCANVAS_ATTRIBUTE_POSITIONS "positions"
103#define SKDEBUGCANVAS_ATTRIBUTE_GLYPHS "glyphs"
104#define SKDEBUGCANVAS_ATTRIBUTE_FONT "font"
105#define SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE "typeface"
ethannicholas1446a9a2016-02-10 14:05:02 -0800106#define SKDEBUGCANVAS_ATTRIBUTE_CUBICS "cubics"
107#define SKDEBUGCANVAS_ATTRIBUTE_COLORS "colors"
108#define SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS "textureCoords"
109#define SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY "filterQuality"
bsalomonac3aa242016-08-19 11:25:19 -0700110#define SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE "startAngle"
111#define SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE "sweepAngle"
112#define SKDEBUGCANVAS_ATTRIBUTE_USECENTER "useCenter"
jcgregorioee0c5552016-06-30 09:18:27 -0700113#define SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC "shortDesc"
msarett0ac1bec2016-08-29 09:15:33 -0700114#define SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID "uniqueID"
115#define SKDEBUGCANVAS_ATTRIBUTE_WIDTH "width"
116#define SKDEBUGCANVAS_ATTRIBUTE_HEIGHT "height"
117#define SKDEBUGCANVAS_ATTRIBUTE_ALPHA "alpha"
Stan Ilievac42aeb2017-01-12 16:20:50 -0500118#define SKDEBUGCANVAS_ATTRIBUTE_LATTICE "lattice"
119#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT "xCount"
120#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT "yCount"
121#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS "xDivs"
122#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS "yDivs"
123#define SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS "flags"
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400124#define SKDEBUGCANVAS_ATTRIBUTE_ZPLANE "zPlane"
125#define SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION "lightPositions"
126#define SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR "ambientColor"
127#define SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR "spotColor"
128#define SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS "lightRadius"
reed67f62fa2016-06-29 11:36:34 -0700129
ethannicholas50a8dd02016-02-10 05:40:46 -0800130#define SKDEBUGCANVAS_VERB_MOVE "move"
131#define SKDEBUGCANVAS_VERB_LINE "line"
132#define SKDEBUGCANVAS_VERB_QUAD "quad"
133#define SKDEBUGCANVAS_VERB_CUBIC "cubic"
134#define SKDEBUGCANVAS_VERB_CONIC "conic"
135#define SKDEBUGCANVAS_VERB_CLOSE "close"
136
137#define SKDEBUGCANVAS_STYLE_FILL "fill"
138#define SKDEBUGCANVAS_STYLE_STROKE "stroke"
139#define SKDEBUGCANVAS_STYLE_STROKEANDFILL "strokeAndFill"
140
141#define SKDEBUGCANVAS_POINTMODE_POINTS "points"
142#define SKDEBUGCANVAS_POINTMODE_LINES "lines"
143#define SKDEBUGCANVAS_POINTMODE_POLYGON "polygon"
144
145#define SKDEBUGCANVAS_REGIONOP_DIFFERENCE "difference"
146#define SKDEBUGCANVAS_REGIONOP_INTERSECT "intersect"
147#define SKDEBUGCANVAS_REGIONOP_UNION "union"
148#define SKDEBUGCANVAS_REGIONOP_XOR "xor"
149#define SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE "reverseDifference"
150#define SKDEBUGCANVAS_REGIONOP_REPLACE "replace"
151
152#define SKDEBUGCANVAS_BLURSTYLE_NORMAL "normal"
153#define SKDEBUGCANVAS_BLURSTYLE_SOLID "solid"
154#define SKDEBUGCANVAS_BLURSTYLE_OUTER "outer"
155#define SKDEBUGCANVAS_BLURSTYLE_INNER "inner"
156
157#define SKDEBUGCANVAS_BLURQUALITY_LOW "low"
158#define SKDEBUGCANVAS_BLURQUALITY_HIGH "high"
159
160#define SKDEBUGCANVAS_ALIGN_LEFT "left"
161#define SKDEBUGCANVAS_ALIGN_CENTER "center"
162#define SKDEBUGCANVAS_ALIGN_RIGHT "right"
163
164#define SKDEBUGCANVAS_FILLTYPE_WINDING "winding"
165#define SKDEBUGCANVAS_FILLTYPE_EVENODD "evenOdd"
166#define SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING "inverseWinding"
167#define SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD "inverseEvenOdd"
168
169#define SKDEBUGCANVAS_CAP_BUTT "butt"
170#define SKDEBUGCANVAS_CAP_ROUND "round"
171#define SKDEBUGCANVAS_CAP_SQUARE "square"
172
ethannicholas1446a9a2016-02-10 14:05:02 -0800173#define SKDEBUGCANVAS_MITER_JOIN "miter"
174#define SKDEBUGCANVAS_ROUND_JOIN "round"
175#define SKDEBUGCANVAS_BEVEL_JOIN "bevel"
176
ethannicholas50a8dd02016-02-10 05:40:46 -0800177#define SKDEBUGCANVAS_COLORTYPE_ARGB4444 "ARGB4444"
178#define SKDEBUGCANVAS_COLORTYPE_RGBA8888 "RGBA8888"
179#define SKDEBUGCANVAS_COLORTYPE_BGRA8888 "BGRA8888"
180#define SKDEBUGCANVAS_COLORTYPE_565 "565"
181#define SKDEBUGCANVAS_COLORTYPE_GRAY8 "Gray8"
182#define SKDEBUGCANVAS_COLORTYPE_INDEX8 "Index8"
183#define SKDEBUGCANVAS_COLORTYPE_ALPHA8 "Alpha8"
184
185#define SKDEBUGCANVAS_ALPHATYPE_OPAQUE "opaque"
186#define SKDEBUGCANVAS_ALPHATYPE_PREMUL "premul"
187#define SKDEBUGCANVAS_ALPHATYPE_UNPREMUL "unpremul"
msarett0ac1bec2016-08-29 09:15:33 -0700188#define SKDEBUGCANVAS_ALPHATYPE_UNKNOWN "unknown"
ethannicholas50a8dd02016-02-10 05:40:46 -0800189
ethannicholas1446a9a2016-02-10 14:05:02 -0800190#define SKDEBUGCANVAS_FILTERQUALITY_NONE "none"
191#define SKDEBUGCANVAS_FILTERQUALITY_LOW "low"
192#define SKDEBUGCANVAS_FILTERQUALITY_MEDIUM "medium"
193#define SKDEBUGCANVAS_FILTERQUALITY_HIGH "high"
194
halcanaryf412f092016-08-25 11:10:41 -0700195#define SKDEBUGCANVAS_HINTING_NONE "none"
196#define SKDEBUGCANVAS_HINTING_SLIGHT "slight"
197#define SKDEBUGCANVAS_HINTING_NORMAL "normal"
198#define SKDEBUGCANVAS_HINTING_FULL "full"
199
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400200#define SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC "transparentOccluder"
201#define SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY "geometricOnly"
202
reed67f62fa2016-06-29 11:36:34 -0700203static SkString* str_append(SkString* str, const SkRect& r) {
204 str->appendf(" [%g %g %g %g]", r.left(), r.top(), r.right(), r.bottom());
205 return str;
206}
207
robertphillips9bafc302015-02-13 11:13:00 -0800208SkDrawCommand::SkDrawCommand(OpType type)
209 : fOpType(type)
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000210 , fVisible(true) {
211}
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";
Brian Osman78a76482018-05-18 16:59:13 -0400224 case kDrawBitmapLattice_OpType: return "DrawBitmapLattice";
robertphillips9bafc302015-02-13 11:13:00 -0800225 case kDrawBitmapNine_OpType: return "DrawBitmapNine";
226 case kDrawBitmapRect_OpType: return "DrawBitmapRect";
robertphillips9bafc302015-02-13 11:13:00 -0800227 case kDrawDRRect_OpType: return "DrawDRRect";
fmalita651c9202015-07-22 10:23:01 -0700228 case kDrawImage_OpType: return "DrawImage";
Stan Ilievac42aeb2017-01-12 16:20:50 -0500229 case kDrawImageLattice_OpType: return "DrawImageLattice";
Brian Osmanc25e2692018-03-12 10:57:28 -0400230 case kDrawImageNine_OpType: return "DrawImageNine";
fmalita651c9202015-07-22 10:23:01 -0700231 case kDrawImageRect_OpType: return "DrawImageRect";
robertphillips9bafc302015-02-13 11:13:00 -0800232 case kDrawOval_OpType: return "DrawOval";
233 case kDrawPaint_OpType: return "DrawPaint";
234 case kDrawPatch_OpType: return "DrawPatch";
235 case kDrawPath_OpType: return "DrawPath";
Brian Osmanc25e2692018-03-12 10:57:28 -0400236 case kDrawArc_OpType: return "DrawArc";
robertphillips9bafc302015-02-13 11:13:00 -0800237 case kDrawPoints_OpType: return "DrawPoints";
238 case kDrawPosText_OpType: return "DrawPosText";
239 case kDrawPosTextH_OpType: return "DrawPosTextH";
240 case kDrawRect_OpType: return "DrawRect";
241 case kDrawRRect_OpType: return "DrawRRect";
Brian Osmanc25e2692018-03-12 10:57:28 -0400242 case kDrawRegion_OpType: return "DrawRegion";
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400243 case kDrawShadow_OpType: return "DrawShadow";
robertphillips9bafc302015-02-13 11:13:00 -0800244 case kDrawText_OpType: return "DrawText";
245 case kDrawTextBlob_OpType: return "DrawTextBlob";
246 case kDrawTextOnPath_OpType: return "DrawTextOnPath";
reed63f30d92016-07-07 16:32:51 -0700247 case kDrawTextRSXform_OpType: return "DrawTextRSXform";
robertphillips9bafc302015-02-13 11:13:00 -0800248 case kDrawVertices_OpType: return "DrawVertices";
Brian Osman616f1cb2018-05-29 11:23:35 -0400249 case kDrawAtlas_OpType: return "DrawAtlas";
fmalita160ebb22015-04-01 20:58:37 -0700250 case kEndDrawPicture_OpType: return "EndDrawPicture";
robertphillips9bafc302015-02-13 11:13:00 -0800251 case kRestore_OpType: return "Restore";
252 case kSave_OpType: return "Save";
253 case kSaveLayer_OpType: return "SaveLayer";
254 case kSetMatrix_OpType: return "SetMatrix";
chudy@google.com902ebe52012-06-29 14:21:22 +0000255 default:
robertphillips9bafc302015-02-13 11:13:00 -0800256 SkDebugf("OpType error 0x%08x\n", type);
chudy@google.com902ebe52012-06-29 14:21:22 +0000257 SkASSERT(0);
258 break;
259 }
260 SkDEBUGFAIL("DrawType UNUSED\n");
halcanary96fcdcc2015-08-27 07:41:13 -0700261 return nullptr;
chudy@google.com902ebe52012-06-29 14:21:22 +0000262}
263
ethannicholasf62a8b72016-02-11 10:35:21 -0800264Json::Value SkDrawCommand::toJSON(UrlDataManager& urlDataManager) const {
ethannicholas50a8dd02016-02-10 05:40:46 -0800265 Json::Value result;
266 result[SKDEBUGCANVAS_ATTRIBUTE_COMMAND] = this->GetCommandString(fOpType);
ethannicholas807dcab2016-02-23 06:53:37 -0800267 result[SKDEBUGCANVAS_ATTRIBUTE_VISIBLE] = Json::Value(this->isVisible());
ethannicholas50a8dd02016-02-10 05:40:46 -0800268 return result;
269}
270
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000271namespace {
272
273void xlate_and_scale_to_bounds(SkCanvas* canvas, const SkRect& bounds) {
Mike Reed3661bc92017-02-22 13:21:42 -0500274 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000275
276 static const SkScalar kInsetFrac = 0.9f; // Leave a border around object
277
278 canvas->translate(size.fWidth/2.0f, size.fHeight/2.0f);
279 if (bounds.width() > bounds.height()) {
280 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.width()),
281 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.width()));
282 } else {
283 canvas->scale(SkDoubleToScalar((kInsetFrac*size.fWidth)/bounds.height()),
284 SkDoubleToScalar((kInsetFrac*size.fHeight)/bounds.height()));
285 }
286 canvas->translate(-bounds.centerX(), -bounds.centerY());
287}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000288
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000289
290void render_path(SkCanvas* canvas, const SkPath& path) {
291 canvas->clear(0xFFFFFFFF);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000292
293 const SkRect& bounds = path.getBounds();
fmalitab0cd8b72015-10-06 07:24:03 -0700294 if (bounds.isEmpty()) {
295 return;
296 }
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000297
fmalitab0cd8b72015-10-06 07:24:03 -0700298 SkAutoCanvasRestore acr(canvas, true);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000299 xlate_and_scale_to_bounds(canvas, bounds);
300
301 SkPaint p;
302 p.setColor(SK_ColorBLACK);
303 p.setStyle(SkPaint::kStroke_Style);
304
305 canvas->drawPath(path, p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000306}
307
Brian Osmanc25e2692018-03-12 10:57:28 -0400308void render_region(SkCanvas* canvas, const SkRegion& region) {
309 canvas->clear(0xFFFFFFFF);
310
311 const SkIRect& bounds = region.getBounds();
312 if (bounds.isEmpty()) {
313 return;
314 }
315
316 SkAutoCanvasRestore acr(canvas, true);
Brian Osman99b63402018-03-13 10:19:27 -0400317 xlate_and_scale_to_bounds(canvas, SkRect::Make(bounds));
Brian Osmanc25e2692018-03-12 10:57:28 -0400318
319 SkPaint p;
320 p.setColor(SK_ColorBLACK);
321 p.setStyle(SkPaint::kStroke_Style);
322
323 canvas->drawRegion(region, p);
324}
325
halcanary96fcdcc2015-08-27 07:41:13 -0700326void render_bitmap(SkCanvas* canvas, const SkBitmap& input, const SkRect* srcRect = nullptr) {
Mike Reed3661bc92017-02-22 13:21:42 -0500327 const SkISize& size = canvas->getBaseLayerSize();
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000328
329 SkScalar xScale = SkIntToScalar(size.fWidth-2) / input.width();
330 SkScalar yScale = SkIntToScalar(size.fHeight-2) / input.height();
331
332 if (input.width() > input.height()) {
333 yScale *= input.height() / (float) input.width();
334 } else {
335 xScale *= input.width() / (float) input.height();
336 }
337
338 SkRect dst = SkRect::MakeXYWH(SK_Scalar1, SK_Scalar1,
339 xScale * input.width(),
340 yScale * input.height());
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000341
robertphillips96a5cff2015-09-24 06:56:27 -0700342 static const int kNumBlocks = 8;
343
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000344 canvas->clear(0xFFFFFFFF);
robertphillips96a5cff2015-09-24 06:56:27 -0700345 SkISize block = {
346 canvas->imageInfo().width()/kNumBlocks,
347 canvas->imageInfo().height()/kNumBlocks
348 };
349 for (int y = 0; y < kNumBlocks; ++y) {
350 for (int x = 0; x < kNumBlocks; ++x) {
351 SkPaint paint;
352 paint.setColor((x+y)%2 ? SK_ColorLTGRAY : SK_ColorDKGRAY);
353 SkRect r = SkRect::MakeXYWH(SkIntToScalar(x*block.width()),
354 SkIntToScalar(y*block.height()),
355 SkIntToScalar(block.width()),
356 SkIntToScalar(block.height()));
357 canvas->drawRect(r, paint);
358 }
359 }
360
reede47829b2015-08-06 10:02:53 -0700361 canvas->drawBitmapRect(input, dst, nullptr);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000362
bsalomon49f085d2014-09-05 13:34:00 -0700363 if (srcRect) {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000364 SkRect r = SkRect::MakeLTRB(srcRect->fLeft * xScale + SK_Scalar1,
365 srcRect->fTop * yScale + SK_Scalar1,
366 srcRect->fRight * xScale + SK_Scalar1,
367 srcRect->fBottom * yScale + SK_Scalar1);
368 SkPaint p;
369 p.setColor(SK_ColorRED);
370 p.setStyle(SkPaint::kStroke_Style);
371
372 canvas->drawRect(r, p);
373 }
374}
375
376void render_rrect(SkCanvas* canvas, const SkRRect& rrect) {
377 canvas->clear(0xFFFFFFFF);
378 canvas->save();
379
380 const SkRect& bounds = rrect.getBounds();
381
382 xlate_and_scale_to_bounds(canvas, bounds);
383
384 SkPaint p;
385 p.setColor(SK_ColorBLACK);
386 p.setStyle(SkPaint::kStroke_Style);
387
388 canvas->drawRRect(rrect, p);
389 canvas->restore();
390}
skia.committer@gmail.coma0090832013-06-07 07:01:06 +0000391
commit-bot@chromium.org3d305202014-02-24 17:28:55 +0000392void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) {
393 canvas->clear(0xFFFFFFFF);
394 canvas->save();
395
396 const SkRect& bounds = outer.getBounds();
397
398 xlate_and_scale_to_bounds(canvas, bounds);
399
400 SkPaint p;
401 p.setColor(SK_ColorBLACK);
402 p.setStyle(SkPaint::kStroke_Style);
403
404 canvas->drawDRRect(outer, inner, p);
405 canvas->restore();
406}
407
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400408void render_shadow(SkCanvas* canvas, const SkPath& path, SkDrawShadowRec rec) {
409 canvas->clear(0xFFFFFFFF);
410
411 const SkRect& bounds = path.getBounds();
412 if (bounds.isEmpty()) {
413 return;
414 }
415
416 SkAutoCanvasRestore acr(canvas, true);
417 xlate_and_scale_to_bounds(canvas, bounds);
418
419 rec.fAmbientColor = SK_ColorBLACK;
420 rec.fSpotColor = SK_ColorBLACK;
421 canvas->private_draw_shadow_rec(path, rec);
422}
423
Florin Malita82d80872017-06-06 16:58:40 -0400424static const char* const gBlendModeMap[] = {
425 "clear",
426 "src",
427 "dst",
428 "srcOver",
429 "dstOver",
430 "srcIn",
431 "dstIn",
432 "srcOut",
433 "dstOut",
434 "srcATop",
435 "dstATop",
436 "xor",
437 "plus",
438 "modulate",
439
440 "screen",
441
442 "overlay",
443 "darken",
444 "lighten",
445 "colorDodge",
446 "colorBurn",
447 "hardLight",
448 "softLight",
449 "difference",
450 "exclusion",
451 "multiply",
452
453 "hue",
454 "saturation",
455 "color",
456 "luminosity",
457};
458
459static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLastMode) + 1,
460 "blendMode mismatch");
461static_assert(SK_ARRAY_COUNT(gBlendModeMap) == static_cast<size_t>(SkBlendMode::kLuminosity) + 1,
462 "blendMode mismatch");
463
464void apply_paint_blend_mode(const SkPaint& paint, Json::Value* target) {
465 const auto mode = paint.getBlendMode();
466 if (mode != SkBlendMode::kSrcOver) {
467 SkASSERT(static_cast<size_t>(mode) < SK_ARRAY_COUNT(gBlendModeMap));
468 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLENDMODE] =
469 Json::Value(gBlendModeMap[static_cast<size_t>(mode)]);
470 }
471}
472
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +0000473};
474
brianosmanfad98562016-05-04 11:06:28 -0700475Json::Value SkDrawCommand::MakeJsonColor(const SkColor color) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800476 Json::Value result(Json::arrayValue);
477 result.append(Json::Value(SkColorGetA(color)));
478 result.append(Json::Value(SkColorGetR(color)));
479 result.append(Json::Value(SkColorGetG(color)));
480 result.append(Json::Value(SkColorGetB(color)));
481 return result;
482}
483
brianosman97bbf822016-09-25 13:15:58 -0700484Json::Value SkDrawCommand::MakeJsonColor4f(const SkColor4f& color) {
485 Json::Value result(Json::arrayValue);
486 result.append(Json::Value(color.fA));
487 result.append(Json::Value(color.fR));
488 result.append(Json::Value(color.fG));
489 result.append(Json::Value(color.fB));
490 return result;
491}
492
brianosmanfad98562016-05-04 11:06:28 -0700493Json::Value SkDrawCommand::MakeJsonPoint(const SkPoint& point) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800494 Json::Value result(Json::arrayValue);
495 result.append(Json::Value(point.x()));
496 result.append(Json::Value(point.y()));
497 return result;
498}
499
brianosmanfad98562016-05-04 11:06:28 -0700500Json::Value SkDrawCommand::MakeJsonPoint(SkScalar x, SkScalar y) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800501 Json::Value result(Json::arrayValue);
502 result.append(Json::Value(x));
503 result.append(Json::Value(y));
504 return result;
505}
506
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -0400507Json::Value SkDrawCommand::MakeJsonPoint3(const SkPoint3& point) {
508 Json::Value result(Json::arrayValue);
509 result.append(Json::Value(point.x()));
510 result.append(Json::Value(point.y()));
511 result.append(Json::Value(point.z()));
512 return result;
513}
514
brianosmanfad98562016-05-04 11:06:28 -0700515Json::Value SkDrawCommand::MakeJsonRect(const SkRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800516 Json::Value result(Json::arrayValue);
517 result.append(Json::Value(rect.left()));
518 result.append(Json::Value(rect.top()));
519 result.append(Json::Value(rect.right()));
520 result.append(Json::Value(rect.bottom()));
521 return result;
522}
523
joshualittbd724132016-03-03 11:39:38 -0800524Json::Value SkDrawCommand::MakeJsonIRect(const SkIRect& rect) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800525 Json::Value result(Json::arrayValue);
526 result.append(Json::Value(rect.left()));
527 result.append(Json::Value(rect.top()));
528 result.append(Json::Value(rect.right()));
529 result.append(Json::Value(rect.bottom()));
530 return result;
531}
532
533static Json::Value make_json_rrect(const SkRRect& rrect) {
534 Json::Value result(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700535 result.append(SkDrawCommand::MakeJsonRect(rrect.rect()));
536 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperLeft_Corner)));
537 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kUpperRight_Corner)));
538 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerRight_Corner)));
539 result.append(SkDrawCommand::MakeJsonPoint(rrect.radii(SkRRect::kLowerLeft_Corner)));
ethannicholas50a8dd02016-02-10 05:40:46 -0800540 return result;
541}
542
joshualittbd724132016-03-03 11:39:38 -0800543Json::Value SkDrawCommand::MakeJsonMatrix(const SkMatrix& matrix) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800544 Json::Value result(Json::arrayValue);
545 Json::Value row1(Json::arrayValue);
546 row1.append(Json::Value(matrix[0]));
547 row1.append(Json::Value(matrix[1]));
548 row1.append(Json::Value(matrix[2]));
549 result.append(row1);
550 Json::Value row2(Json::arrayValue);
551 row2.append(Json::Value(matrix[3]));
552 row2.append(Json::Value(matrix[4]));
553 row2.append(Json::Value(matrix[5]));
554 result.append(row2);
555 Json::Value row3(Json::arrayValue);
556 row3.append(Json::Value(matrix[6]));
557 row3.append(Json::Value(matrix[7]));
558 row3.append(Json::Value(matrix[8]));
559 result.append(row3);
560 return result;
561}
ethannicholas1446a9a2016-02-10 14:05:02 -0800562
vjiaoblacke5de1302016-07-13 14:05:28 -0700563Json::Value SkDrawCommand::MakeJsonScalar(SkScalar z) {
564 Json::Value result(z);
565 return result;
566}
567
brianosmanfad98562016-05-04 11:06:28 -0700568Json::Value SkDrawCommand::MakeJsonPath(const SkPath& path) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800569 Json::Value result(Json::objectValue);
570 switch (path.getFillType()) {
571 case SkPath::kWinding_FillType:
572 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_WINDING;
573 break;
574 case SkPath::kEvenOdd_FillType:
575 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_EVENODD;
576 break;
577 case SkPath::kInverseWinding_FillType:
578 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEWINDING;
579 break;
580 case SkPath::kInverseEvenOdd_FillType:
581 result[SKDEBUGCANVAS_ATTRIBUTE_FILLTYPE] = SKDEBUGCANVAS_FILLTYPE_INVERSEEVENODD;
582 break;
halcanary9d524f22016-03-29 09:03:52 -0700583 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800584 Json::Value verbs(Json::arrayValue);
585 SkPath::Iter iter(path, false);
586 SkPoint pts[4];
587 SkPath::Verb verb;
588 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
589 switch (verb) {
590 case SkPath::kLine_Verb: {
591 Json::Value line(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700592 line[SKDEBUGCANVAS_VERB_LINE] = MakeJsonPoint(pts[1]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800593 verbs.append(line);
594 break;
595 }
596 case SkPath::kQuad_Verb: {
597 Json::Value quad(Json::objectValue);
598 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700599 coords.append(MakeJsonPoint(pts[1]));
600 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800601 quad[SKDEBUGCANVAS_VERB_QUAD] = coords;
602 verbs.append(quad);
603 break;
604 }
605 case SkPath::kCubic_Verb: {
606 Json::Value cubic(Json::objectValue);
607 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700608 coords.append(MakeJsonPoint(pts[1]));
609 coords.append(MakeJsonPoint(pts[2]));
610 coords.append(MakeJsonPoint(pts[3]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800611 cubic[SKDEBUGCANVAS_VERB_CUBIC] = coords;
612 verbs.append(cubic);
613 break;
614 }
615 case SkPath::kConic_Verb: {
616 Json::Value conic(Json::objectValue);
617 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -0700618 coords.append(MakeJsonPoint(pts[1]));
619 coords.append(MakeJsonPoint(pts[2]));
ethannicholas50a8dd02016-02-10 05:40:46 -0800620 coords.append(Json::Value(iter.conicWeight()));
621 conic[SKDEBUGCANVAS_VERB_CONIC] = coords;
622 verbs.append(conic);
623 break;
624 }
625 case SkPath::kMove_Verb: {
626 Json::Value move(Json::objectValue);
brianosmanfad98562016-05-04 11:06:28 -0700627 move[SKDEBUGCANVAS_VERB_MOVE] = MakeJsonPoint(pts[0]);
ethannicholas50a8dd02016-02-10 05:40:46 -0800628 verbs.append(move);
629 break;
630 }
631 case SkPath::kClose_Verb:
632 verbs.append(Json::Value(SKDEBUGCANVAS_VERB_CLOSE));
633 break;
634 case SkPath::kDone_Verb:
635 break;
636 }
637 }
638 result[SKDEBUGCANVAS_ATTRIBUTE_VERBS] = verbs;
639 return result;
640}
641
brianosmanfad98562016-05-04 11:06:28 -0700642Json::Value SkDrawCommand::MakeJsonRegion(const SkRegion& region) {
Brian Osmanc25e2692018-03-12 10:57:28 -0400643 // TODO: Actually serialize the rectangles, rather than just devolving to path
644 SkPath path;
645 region.getBoundaryPath(&path);
646 return MakeJsonPath(path);
ethannicholas50a8dd02016-02-10 05:40:46 -0800647}
648
Mike Reedc1f77742016-12-09 09:00:50 -0500649static Json::Value make_json_regionop(SkClipOp op) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800650 switch (op) {
Mike Reedc1f77742016-12-09 09:00:50 -0500651 case kDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800652 return Json::Value(SKDEBUGCANVAS_REGIONOP_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500653 case kIntersect_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800654 return Json::Value(SKDEBUGCANVAS_REGIONOP_INTERSECT);
Mike Reedc1f77742016-12-09 09:00:50 -0500655 case kUnion_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800656 return Json::Value(SKDEBUGCANVAS_REGIONOP_UNION);
Mike Reedc1f77742016-12-09 09:00:50 -0500657 case kXOR_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800658 return Json::Value(SKDEBUGCANVAS_REGIONOP_XOR);
Mike Reedc1f77742016-12-09 09:00:50 -0500659 case kReverseDifference_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800660 return Json::Value(SKDEBUGCANVAS_REGIONOP_REVERSE_DIFFERENCE);
Mike Reedc1f77742016-12-09 09:00:50 -0500661 case kReplace_SkClipOp:
ethannicholas50a8dd02016-02-10 05:40:46 -0800662 return Json::Value(SKDEBUGCANVAS_REGIONOP_REPLACE);
663 default:
664 SkASSERT(false);
665 return Json::Value("<invalid region op>");
666 };
667}
668
669static Json::Value make_json_pointmode(SkCanvas::PointMode mode) {
670 switch (mode) {
671 case SkCanvas::kPoints_PointMode:
672 return Json::Value(SKDEBUGCANVAS_POINTMODE_POINTS);
673 case SkCanvas::kLines_PointMode:
674 return Json::Value(SKDEBUGCANVAS_POINTMODE_LINES);
halcanary9d524f22016-03-29 09:03:52 -0700675 case SkCanvas::kPolygon_PointMode:
ethannicholas50a8dd02016-02-10 05:40:46 -0800676 return Json::Value(SKDEBUGCANVAS_POINTMODE_POLYGON);
677 default:
678 SkASSERT(false);
679 return Json::Value("<invalid point mode>");
680 };
681}
682
halcanary9d524f22016-03-29 09:03:52 -0700683static void store_scalar(Json::Value* target, const char* key, SkScalar value,
ethannicholasbd3dae82016-02-10 12:10:00 -0800684 SkScalar defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800685 if (value != defaultValue) {
686 (*target)[key] = Json::Value(value);
687 }
688}
689
ethannicholasbd3dae82016-02-10 12:10:00 -0800690static void store_bool(Json::Value* target, const char* key, bool value, bool defaultValue) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800691 if (value != defaultValue) {
692 (*target)[key] = Json::Value(value);
693 }
694}
695
halcanary9d524f22016-03-29 09:03:52 -0700696static void encode_data(const void* bytes, size_t count, const char* contentType,
ethannicholasf62a8b72016-02-11 10:35:21 -0800697 UrlDataManager& urlDataManager, Json::Value* target) {
bungeman38d909e2016-08-02 14:40:46 -0700698 sk_sp<SkData> data(SkData::MakeWithCopy(bytes, count));
699 SkString url = urlDataManager.addData(data.get(), contentType);
ethannicholasf62a8b72016-02-11 10:35:21 -0800700 *target = Json::Value(url.c_str());
ethannicholas50a8dd02016-02-10 05:40:46 -0800701}
702
brianosmanfad98562016-05-04 11:06:28 -0700703void SkDrawCommand::flatten(const SkFlattenable* flattenable, Json::Value* target,
704 UrlDataManager& urlDataManager) {
705 SkBinaryWriteBuffer buffer;
ethannicholasf62a8b72016-02-11 10:35:21 -0800706 flattenable->flatten(buffer);
707 void* data = sk_malloc_throw(buffer.bytesWritten());
708 buffer.writeToMemory(data);
709 Json::Value jsonData;
710 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager, &jsonData);
711 Json::Value jsonFlattenable;
712 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_NAME] = Json::Value(flattenable->getTypeName());
713 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
brianosmanfad98562016-05-04 11:06:28 -0700714
715 SkJsonWriteBuffer jsonBuffer(&urlDataManager);
716 flattenable->flatten(jsonBuffer);
717 jsonFlattenable[SKDEBUGCANVAS_ATTRIBUTE_VALUES] = jsonBuffer.getValue();
718
ethannicholasf62a8b72016-02-11 10:35:21 -0800719 (*target) = jsonFlattenable;
720 sk_free(data);
ethannicholas50a8dd02016-02-10 05:40:46 -0800721}
722
ethannicholasf67531f2016-03-21 10:19:39 -0700723static void write_png_callback(png_structp png_ptr, png_bytep data, png_size_t length) {
724 SkWStream* out = (SkWStream*) png_get_io_ptr(png_ptr);
725 out->write(data, length);
726}
727
halcanarya73d76a2016-10-17 13:19:02 -0700728void SkDrawCommand::WritePNG(const uint8_t* rgba, unsigned width, unsigned height,
msaretta5cf4f42016-06-30 10:06:51 -0700729 SkWStream& out, bool isOpaque) {
Ben Wagnera93a14a2017-08-28 10:34:05 -0400730 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700731 SkASSERT(png != nullptr);
732 png_infop info_ptr = png_create_info_struct(png);
733 SkASSERT(info_ptr != nullptr);
734 if (setjmp(png_jmpbuf(png))) {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400735 SK_ABORT("png encode error");
ethannicholasf67531f2016-03-21 10:19:39 -0700736 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400737 png_set_write_fn(png, &out, write_png_callback, nullptr);
msaretta5cf4f42016-06-30 10:06:51 -0700738 int colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA;
739 png_set_IHDR(png, info_ptr, width, height, 8, colorType, PNG_INTERLACE_NONE,
ethannicholasf67531f2016-03-21 10:19:39 -0700740 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
741 png_set_compression_level(png, 1);
742 png_bytepp rows = (png_bytepp) sk_malloc_throw(height * sizeof(png_byte*));
msaretta5cf4f42016-06-30 10:06:51 -0700743 png_bytep pixels = (png_bytep) sk_malloc_throw(width * height * 4);
ethannicholasf67531f2016-03-21 10:19:39 -0700744 for (png_size_t y = 0; y < height; ++y) {
halcanarya73d76a2016-10-17 13:19:02 -0700745 const uint8_t* src = rgba + y * width * 4;
msaretta5cf4f42016-06-30 10:06:51 -0700746 rows[y] = pixels + y * width * 4;
ethannicholasf67531f2016-03-21 10:19:39 -0700747 for (png_size_t x = 0; x < width; ++x) {
msaretta5cf4f42016-06-30 10:06:51 -0700748 rows[y][x * 4] = src[x * 4];
749 rows[y][x * 4 + 1] = src[x * 4 + 1];
750 rows[y][x * 4 + 2] = src[x * 4 + 2];
751 rows[y][x * 4 + 3] = src[x * 4 + 3];
ethannicholasf67531f2016-03-21 10:19:39 -0700752 }
753 }
msaretta5cf4f42016-06-30 10:06:51 -0700754 png_write_info(png, info_ptr);
755 if (isOpaque) {
756 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
757 }
ethannicholasf67531f2016-03-21 10:19:39 -0700758 png_set_filter(png, 0, PNG_NO_FILTERS);
msaretta5cf4f42016-06-30 10:06:51 -0700759 png_write_image(png, &rows[0]);
Ben Wagnera93a14a2017-08-28 10:34:05 -0400760 png_destroy_write_struct(&png, nullptr);
ethannicholasf67531f2016-03-21 10:19:39 -0700761 sk_free(rows);
762 sk_free(pixels);
763}
764
brianosmanfad98562016-05-04 11:06:28 -0700765bool SkDrawCommand::flatten(const SkImage& image, Json::Value* target,
766 UrlDataManager& urlDataManager) {
ethannicholasf67531f2016-03-21 10:19:39 -0700767 size_t rowBytes = 4 * image.width();
Hal Canary95e3c052017-01-11 12:44:43 -0500768 SkAutoMalloc buffer(rowBytes * image.height());
halcanary9d524f22016-03-29 09:03:52 -0700769 SkImageInfo dstInfo = SkImageInfo::Make(image.width(), image.height(),
ethannicholasf67531f2016-03-21 10:19:39 -0700770 kN32_SkColorType, kPremul_SkAlphaType);
771 if (!image.readPixels(dstInfo, buffer.get(), rowBytes, 0, 0)) {
772 SkDebugf("readPixels failed\n");
773 return false;
ethannicholas50a8dd02016-02-10 05:40:46 -0800774 }
msaretta5cf4f42016-06-30 10:06:51 -0700775
776 SkBitmap bm;
777 bm.installPixels(dstInfo, buffer.get(), rowBytes);
778 sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bm);
779
ethannicholasf67531f2016-03-21 10:19:39 -0700780 SkDynamicMemoryWStream out;
halcanarya73d76a2016-10-17 13:19:02 -0700781 SkDrawCommand::WritePNG(encodedBitmap->bytes(), image.width(), image.height(),
msaretta5cf4f42016-06-30 10:06:51 -0700782 out, false);
reed42943c82016-09-12 12:01:44 -0700783 sk_sp<SkData> encoded = out.detachAsData();
ethannicholasf62a8b72016-02-11 10:35:21 -0800784 Json::Value jsonData;
785 encode_data(encoded->data(), encoded->size(), "image/png", urlDataManager, &jsonData);
786 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
ethannicholas50a8dd02016-02-10 05:40:46 -0800787 return true;
788}
789
790static const char* color_type_name(SkColorType colorType) {
791 switch (colorType) {
792 case kARGB_4444_SkColorType:
793 return SKDEBUGCANVAS_COLORTYPE_ARGB4444;
794 case kRGBA_8888_SkColorType:
795 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
796 case kBGRA_8888_SkColorType:
797 return SKDEBUGCANVAS_COLORTYPE_BGRA8888;
798 case kRGB_565_SkColorType:
799 return SKDEBUGCANVAS_COLORTYPE_565;
800 case kGray_8_SkColorType:
801 return SKDEBUGCANVAS_COLORTYPE_GRAY8;
ethannicholas50a8dd02016-02-10 05:40:46 -0800802 case kAlpha_8_SkColorType:
803 return SKDEBUGCANVAS_COLORTYPE_ALPHA8;
804 default:
805 SkASSERT(false);
806 return SKDEBUGCANVAS_COLORTYPE_RGBA8888;
807 }
808}
809
810static const char* alpha_type_name(SkAlphaType alphaType) {
811 switch (alphaType) {
812 case kOpaque_SkAlphaType:
813 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
814 case kPremul_SkAlphaType:
815 return SKDEBUGCANVAS_ALPHATYPE_PREMUL;
816 case kUnpremul_SkAlphaType:
817 return SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
818 default:
819 SkASSERT(false);
820 return SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
821 }
822}
823
brianosmanfad98562016-05-04 11:06:28 -0700824bool SkDrawCommand::flatten(const SkBitmap& bitmap, Json::Value* target,
825 UrlDataManager& urlDataManager) {
reed9ce9d672016-03-17 10:51:11 -0700826 sk_sp<SkImage> image(SkImage::MakeFromBitmap(bitmap));
ethannicholas50a8dd02016-02-10 05:40:46 -0800827 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = Json::Value(color_type_name(bitmap.colorType()));
828 (*target)[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = Json::Value(alpha_type_name(bitmap.alphaType()));
ethannicholasf62a8b72016-02-11 10:35:21 -0800829 bool success = flatten(*image, target, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800830 return success;
831}
832
halcanaryf412f092016-08-25 11:10:41 -0700833static void apply_paint_hinting(const SkPaint& paint, Json::Value* target) {
834 SkPaint::Hinting hinting = paint.getHinting();
835 if (hinting != SkPaintDefaults_Hinting) {
836 switch (hinting) {
837 case SkPaint::kNo_Hinting:
838 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NONE;
839 break;
840 case SkPaint::kSlight_Hinting:
841 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_SLIGHT;
842 break;
843 case SkPaint::kNormal_Hinting:
844 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_NORMAL;
845 break;
846 case SkPaint::kFull_Hinting:
847 (*target)[SKDEBUGCANVAS_ATTRIBUTE_HINTING] = SKDEBUGCANVAS_HINTING_FULL;
848 break;
849 }
850 }
851}
852
ethannicholas50a8dd02016-02-10 05:40:46 -0800853static void apply_paint_color(const SkPaint& paint, Json::Value* target) {
854 SkColor color = paint.getColor();
855 if (color != SK_ColorBLACK) {
856 Json::Value colorValue(Json::arrayValue);
857 colorValue.append(Json::Value(SkColorGetA(color)));
858 colorValue.append(Json::Value(SkColorGetR(color)));
859 colorValue.append(Json::Value(SkColorGetG(color)));
860 colorValue.append(Json::Value(SkColorGetB(color)));
861 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = colorValue;;
862 }
863}
864
865static void apply_paint_style(const SkPaint& paint, Json::Value* target) {
866 SkPaint::Style style = paint.getStyle();
867 if (style != SkPaint::kFill_Style) {
868 switch (style) {
869 case SkPaint::kStroke_Style: {
870 Json::Value stroke(SKDEBUGCANVAS_STYLE_STROKE);
871 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = stroke;
872 break;
873 }
874 case SkPaint::kStrokeAndFill_Style: {
875 Json::Value strokeAndFill(SKDEBUGCANVAS_STYLE_STROKEANDFILL);
876 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = strokeAndFill;
877 break;
878 }
879 default: SkASSERT(false);
880 }
881 }
882}
883
884static void apply_paint_cap(const SkPaint& paint, Json::Value* target) {
885 SkPaint::Cap cap = paint.getStrokeCap();
886 if (cap != SkPaint::kDefault_Cap) {
887 switch (cap) {
ethannicholas1446a9a2016-02-10 14:05:02 -0800888 case SkPaint::kButt_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -0800889 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_BUTT);
890 break;
ethannicholas1446a9a2016-02-10 14:05:02 -0800891 case SkPaint::kRound_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -0800892 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_ROUND);
893 break;
ethannicholas1446a9a2016-02-10 14:05:02 -0800894 case SkPaint::kSquare_Cap:
ethannicholas50a8dd02016-02-10 05:40:46 -0800895 (*target)[SKDEBUGCANVAS_ATTRIBUTE_CAP] = Json::Value(SKDEBUGCANVAS_CAP_SQUARE);
896 break;
ethannicholas50a8dd02016-02-10 05:40:46 -0800897 default: SkASSERT(false);
898 }
899 }
900}
ethannicholas1446a9a2016-02-10 14:05:02 -0800901
902static void apply_paint_join(const SkPaint& paint, Json::Value* target) {
903 SkPaint::Join join = paint.getStrokeJoin();
904 if (join != SkPaint::kDefault_Join) {
905 switch (join) {
906 case SkPaint::kMiter_Join:
907 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
908 SKDEBUGCANVAS_MITER_JOIN);
909 break;
910 case SkPaint::kRound_Join:
911 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
912 SKDEBUGCANVAS_ROUND_JOIN);
913 break;
914 case SkPaint::kBevel_Join:
915 (*target)[SKDEBUGCANVAS_ATTRIBUTE_STROKEJOIN] = Json::Value(
916 SKDEBUGCANVAS_BEVEL_JOIN);
917 break;
918 default: SkASSERT(false);
919 }
920 }
921}
922
923static void apply_paint_filterquality(const SkPaint& paint, Json::Value* target) {
924 SkFilterQuality quality = paint.getFilterQuality();
925 switch (quality) {
926 case kNone_SkFilterQuality:
927 break;
928 case kLow_SkFilterQuality:
929 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
930 SKDEBUGCANVAS_FILTERQUALITY_LOW);
931 break;
932 case kMedium_SkFilterQuality:
933 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
934 SKDEBUGCANVAS_FILTERQUALITY_MEDIUM);
935 break;
936 case kHigh_SkFilterQuality:
937 (*target)[SKDEBUGCANVAS_ATTRIBUTE_FILTERQUALITY] = Json::Value(
938 SKDEBUGCANVAS_FILTERQUALITY_HIGH);
939 break;
940 }
941}
942
halcanary9d524f22016-03-29 09:03:52 -0700943static void apply_paint_maskfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -0800944 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800945 SkMaskFilter* maskFilter = paint.getMaskFilter();
946 if (maskFilter != nullptr) {
Mike Reed80747ef2018-01-23 15:29:32 -0500947 SkMaskFilterBase::BlurRec blurRec;
948 if (as_MFB(maskFilter)->asABlur(&blurRec)) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800949 Json::Value blur(Json::objectValue);
950 blur[SKDEBUGCANVAS_ATTRIBUTE_SIGMA] = Json::Value(blurRec.fSigma);
951 switch (blurRec.fStyle) {
952 case SkBlurStyle::kNormal_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -0800953 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
954 SKDEBUGCANVAS_BLURSTYLE_NORMAL);
ethannicholas50a8dd02016-02-10 05:40:46 -0800955 break;
956 case SkBlurStyle::kSolid_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -0800957 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
958 SKDEBUGCANVAS_BLURSTYLE_SOLID);
ethannicholas50a8dd02016-02-10 05:40:46 -0800959 break;
960 case SkBlurStyle::kOuter_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -0800961 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
962 SKDEBUGCANVAS_BLURSTYLE_OUTER);
ethannicholas50a8dd02016-02-10 05:40:46 -0800963 break;
964 case SkBlurStyle::kInner_SkBlurStyle:
ethannicholas1446a9a2016-02-10 14:05:02 -0800965 blur[SKDEBUGCANVAS_ATTRIBUTE_STYLE] = Json::Value(
966 SKDEBUGCANVAS_BLURSTYLE_INNER);
ethannicholas50a8dd02016-02-10 05:40:46 -0800967 break;
968 default:
969 SkASSERT(false);
970 }
ethannicholas50a8dd02016-02-10 05:40:46 -0800971 (*target)[SKDEBUGCANVAS_ATTRIBUTE_BLUR] = blur;
972 } else {
973 Json::Value jsonMaskFilter;
brianosmanfad98562016-05-04 11:06:28 -0700974 SkDrawCommand::flatten(maskFilter, &jsonMaskFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -0800975 (*target)[SKDEBUGCANVAS_ATTRIBUTE_MASKFILTER] = jsonMaskFilter;
976 }
977 }
978}
979
halcanary9d524f22016-03-29 09:03:52 -0700980static void apply_paint_patheffect(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -0800981 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -0800982 SkPathEffect* pathEffect = paint.getPathEffect();
983 if (pathEffect != nullptr) {
984 SkPathEffect::DashInfo dashInfo;
985 SkPathEffect::DashType dashType = pathEffect->asADash(&dashInfo);
986 if (dashType == SkPathEffect::kDash_DashType) {
987 dashInfo.fIntervals = (SkScalar*) sk_malloc_throw(dashInfo.fCount * sizeof(SkScalar));
988 pathEffect->asADash(&dashInfo);
989 Json::Value dashing(Json::objectValue);
990 Json::Value intervals(Json::arrayValue);
991 for (int32_t i = 0; i < dashInfo.fCount; i++) {
992 intervals.append(Json::Value(dashInfo.fIntervals[i]));
993 }
994 sk_free(dashInfo.fIntervals);
995 dashing[SKDEBUGCANVAS_ATTRIBUTE_INTERVALS] = intervals;
996 dashing[SKDEBUGCANVAS_ATTRIBUTE_PHASE] = dashInfo.fPhase;
997 (*target)[SKDEBUGCANVAS_ATTRIBUTE_DASHING] = dashing;
998 } else {
999 Json::Value jsonPathEffect;
brianosmanfad98562016-05-04 11:06:28 -07001000 SkDrawCommand::flatten(pathEffect, &jsonPathEffect, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001001 (*target)[SKDEBUGCANVAS_ATTRIBUTE_PATHEFFECT] = jsonPathEffect;
1002 }
1003 }
1004}
halcanary9d524f22016-03-29 09:03:52 -07001005
ethannicholas50a8dd02016-02-10 05:40:46 -08001006static void apply_paint_textalign(const SkPaint& paint, Json::Value* target) {
1007 SkPaint::Align textAlign = paint.getTextAlign();
1008 if (textAlign != SkPaint::kLeft_Align) {
1009 switch (textAlign) {
1010 case SkPaint::kCenter_Align: {
1011 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_CENTER;
1012 break;
1013 }
1014 case SkPaint::kRight_Align: {
1015 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TEXTALIGN] = SKDEBUGCANVAS_ALIGN_RIGHT;
1016 break;
1017 }
1018 default: SkASSERT(false);
1019 }
1020 }
1021}
1022
halcanary9d524f22016-03-29 09:03:52 -07001023static void apply_paint_typeface(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001024 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001025 SkTypeface* typeface = paint.getTypeface();
1026 if (typeface != nullptr) {
ethannicholasf62a8b72016-02-11 10:35:21 -08001027 Json::Value jsonTypeface;
1028 SkDynamicMemoryWStream buffer;
1029 typeface->serialize(&buffer);
1030 void* data = sk_malloc_throw(buffer.bytesWritten());
1031 buffer.copyTo(data);
1032 Json::Value jsonData;
halcanary9d524f22016-03-29 09:03:52 -07001033 encode_data(data, buffer.bytesWritten(), "application/octet-stream", urlDataManager,
ethannicholasf62a8b72016-02-11 10:35:21 -08001034 &jsonData);
1035 jsonTypeface[SKDEBUGCANVAS_ATTRIBUTE_DATA] = jsonData;
1036 sk_free(data);
1037 (*target)[SKDEBUGCANVAS_ATTRIBUTE_TYPEFACE] = jsonTypeface;
ethannicholas50a8dd02016-02-10 05:40:46 -08001038 }
1039}
1040
halcanary9d524f22016-03-29 09:03:52 -07001041static void apply_paint_shader(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001042 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001043 SkFlattenable* shader = paint.getShader();
1044 if (shader != nullptr) {
1045 Json::Value jsonShader;
brianosmanfad98562016-05-04 11:06:28 -07001046 SkDrawCommand::flatten(shader, &jsonShader, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001047 (*target)[SKDEBUGCANVAS_ATTRIBUTE_SHADER] = jsonShader;
1048 }
1049}
1050
ethannicholasf62a8b72016-02-11 10:35:21 -08001051static void apply_paint_imagefilter(const SkPaint& paint, Json::Value* target,
1052 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001053 SkFlattenable* imageFilter = paint.getImageFilter();
1054 if (imageFilter != nullptr) {
1055 Json::Value jsonImageFilter;
brianosmanfad98562016-05-04 11:06:28 -07001056 SkDrawCommand::flatten(imageFilter, &jsonImageFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001057 (*target)[SKDEBUGCANVAS_ATTRIBUTE_IMAGEFILTER] = jsonImageFilter;
1058 }
1059}
1060
halcanary9d524f22016-03-29 09:03:52 -07001061static void apply_paint_colorfilter(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001062 UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001063 SkFlattenable* colorFilter = paint.getColorFilter();
1064 if (colorFilter != nullptr) {
1065 Json::Value jsonColorFilter;
brianosmanfad98562016-05-04 11:06:28 -07001066 SkDrawCommand::flatten(colorFilter, &jsonColorFilter, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001067 (*target)[SKDEBUGCANVAS_ATTRIBUTE_COLORFILTER] = jsonColorFilter;
1068 }
1069}
1070
halcanary9d524f22016-03-29 09:03:52 -07001071static void apply_paint_looper(const SkPaint& paint, Json::Value* target,
ethannicholasf62a8b72016-02-11 10:35:21 -08001072 UrlDataManager& urlDataManager) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001073 SkFlattenable* looper = paint.getLooper();
1074 if (looper != nullptr) {
1075 Json::Value jsonLooper;
brianosmanfad98562016-05-04 11:06:28 -07001076 SkDrawCommand::flatten(looper, &jsonLooper, urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08001077 (*target)[SKDEBUGCANVAS_ATTRIBUTE_LOOPER] = jsonLooper;
1078 }
1079}
1080
brianosmanfad98562016-05-04 11:06:28 -07001081Json::Value SkDrawCommand::MakeJsonPaint(const SkPaint& paint, UrlDataManager& urlDataManager) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001082 Json::Value result(Json::objectValue);
1083 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEWIDTH, paint.getStrokeWidth(), 0.0f);
halcanary9d524f22016-03-29 09:03:52 -07001084 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_STROKEMITER, paint.getStrokeMiter(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001085 SkPaintDefaults_MiterLimit);
1086 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS, paint.isAntiAlias(), false);
ethannicholas1446a9a2016-02-10 14:05:02 -08001087 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_DITHER, paint.isDither(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001088 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_FAKEBOLDTEXT, paint.isFakeBoldText(), false);
1089 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LINEARTEXT, paint.isLinearText(), false);
1090 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_SUBPIXELTEXT, paint.isSubpixelText(), false);
Ben Wagner78f1f5a2017-06-23 14:35:07 -04001091 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_LCDRENDERTEXT, paint.isLCDRenderText(), false);
1092 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_EMBEDDEDBITMAPTEXT, paint.isEmbeddedBitmapText(), false);
1093 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_AUTOHINTING, paint.isAutohinted(), false);
1094 store_bool(&result, SKDEBUGCANVAS_ATTRIBUTE_VERTICALTEXT, paint.isVerticalText(), false);
1095 //kGenA8FromLCD_Flag
1096
halcanary9d524f22016-03-29 09:03:52 -07001097 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSIZE, paint.getTextSize(),
ethannicholas50a8dd02016-02-10 05:40:46 -08001098 SkPaintDefaults_TextSize);
1099 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextScaleX(), SK_Scalar1);
1100 store_scalar(&result, SKDEBUGCANVAS_ATTRIBUTE_TEXTSCALEX, paint.getTextSkewX(), 0.0f);
halcanaryf412f092016-08-25 11:10:41 -07001101 apply_paint_hinting(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001102 apply_paint_color(paint, &result);
1103 apply_paint_style(paint, &result);
Florin Malita82d80872017-06-06 16:58:40 -04001104 apply_paint_blend_mode(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001105 apply_paint_cap(paint, &result);
ethannicholas1446a9a2016-02-10 14:05:02 -08001106 apply_paint_join(paint, &result);
1107 apply_paint_filterquality(paint, &result);
ethannicholas50a8dd02016-02-10 05:40:46 -08001108 apply_paint_textalign(paint, &result);
ethannicholasf62a8b72016-02-11 10:35:21 -08001109 apply_paint_patheffect(paint, &result, urlDataManager);
1110 apply_paint_maskfilter(paint, &result, urlDataManager);
1111 apply_paint_shader(paint, &result, urlDataManager);
ethannicholasf62a8b72016-02-11 10:35:21 -08001112 apply_paint_looper(paint, &result, urlDataManager);
1113 apply_paint_imagefilter(paint, &result, urlDataManager);
1114 apply_paint_colorfilter(paint, &result, urlDataManager);
1115 apply_paint_typeface(paint, &result, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001116 return result;
1117}
1118
Stan Ilievac42aeb2017-01-12 16:20:50 -05001119Json::Value SkDrawCommand::MakeJsonLattice(const SkCanvas::Lattice& lattice) {
1120 Json::Value result(Json::objectValue);
1121 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXCOUNT] = Json::Value(lattice.fXCount);
1122 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYCOUNT] = Json::Value(lattice.fYCount);
1123 if (nullptr != lattice.fBounds) {
1124 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonIRect(*lattice.fBounds);
1125 }
1126 Json::Value XDivs(Json::arrayValue);
1127 for (int i = 0; i < lattice.fXCount; i++) {
1128 XDivs.append(Json::Value(lattice.fXDivs[i]));
1129 }
1130 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEXDIVS] = XDivs;
1131 Json::Value YDivs(Json::arrayValue);
1132 for (int i = 0; i < lattice.fYCount; i++) {
1133 YDivs.append(Json::Value(lattice.fYDivs[i]));
1134 }
1135 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEYDIVS] = YDivs;
Stan Ilievca8c0952017-12-11 13:01:58 -05001136 if (nullptr != lattice.fRectTypes) {
Stan Ilievac42aeb2017-01-12 16:20:50 -05001137 Json::Value flags(Json::arrayValue);
1138 int flagCount = 0;
1139 for (int row = 0; row < lattice.fYCount+1; row++) {
1140 Json::Value flagsRow(Json::arrayValue);
1141 for (int column = 0; column < lattice.fXCount+1; column++) {
Stan Ilievca8c0952017-12-11 13:01:58 -05001142 flagsRow.append(Json::Value(lattice.fRectTypes[flagCount++]));
Stan Ilievac42aeb2017-01-12 16:20:50 -05001143 }
1144 flags.append(flagsRow);
1145 }
1146 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICEFLAGS] = flags;
1147 }
1148 return result;
1149}
1150
Brian Osmanc25e2692018-03-12 10:57:28 -04001151SkClearCommand::SkClearCommand(SkColor color) : INHERITED(kClear_OpType) {
ethannicholas1446a9a2016-02-10 14:05:02 -08001152 fColor = color;
ethannicholas1446a9a2016-02-10 14:05:02 -08001153}
1154
1155void SkClearCommand::execute(SkCanvas* canvas) const {
1156 canvas->clear(fColor);
1157}
1158
ethannicholasf62a8b72016-02-11 10:35:21 -08001159Json::Value SkClearCommand::toJSON(UrlDataManager& urlDataManager) const {
1160 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001161 result[SKDEBUGCANVAS_ATTRIBUTE_COLOR] = MakeJsonColor(fColor);
ethannicholas1446a9a2016-02-10 14:05:02 -08001162 return result;
1163}
1164
Mike Reedc1f77742016-12-09 09:00:50 -05001165SkClipPathCommand::SkClipPathCommand(const SkPath& path, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001166 : INHERITED(kClipPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001167 fPath = path;
1168 fOp = op;
1169 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001170}
1171
fmalita8c89c522014-11-08 16:18:56 -08001172void SkClipPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001173 canvas->clipPath(fPath, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001174}
1175
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001176bool SkClipPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001177 render_path(canvas, fPath);
1178 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001179}
1180
ethannicholasf62a8b72016-02-11 10:35:21 -08001181Json::Value SkClipPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1182 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001183 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
ethannicholas50a8dd02016-02-10 05:40:46 -08001184 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1185 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = fDoAA;
1186 return result;
1187}
1188
Mike Reedc1f77742016-12-09 09:00:50 -05001189SkClipRegionCommand::SkClipRegionCommand(const SkRegion& region, SkClipOp op)
robertphillips9bafc302015-02-13 11:13:00 -08001190 : INHERITED(kClipRegion_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001191 fRegion = region;
1192 fOp = op;
chudy@google.com902ebe52012-06-29 14:21:22 +00001193}
1194
fmalita8c89c522014-11-08 16:18:56 -08001195void SkClipRegionCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001196 canvas->clipRegion(fRegion, fOp);
chudy@google.com902ebe52012-06-29 14:21:22 +00001197}
1198
ethannicholasf62a8b72016-02-11 10:35:21 -08001199Json::Value SkClipRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1200 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001201 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
ethannicholas50a8dd02016-02-10 05:40:46 -08001202 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1203 return result;
1204}
1205
Mike Reedc1f77742016-12-09 09:00:50 -05001206SkClipRectCommand::SkClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001207 : INHERITED(kClipRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001208 fRect = rect;
1209 fOp = op;
1210 fDoAA = doAA;
chudy@google.com902ebe52012-06-29 14:21:22 +00001211}
1212
fmalita8c89c522014-11-08 16:18:56 -08001213void SkClipRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001214 canvas->clipRect(fRect, fOp, fDoAA);
chudy@google.com902ebe52012-06-29 14:21:22 +00001215}
1216
ethannicholasf62a8b72016-02-11 10:35:21 -08001217Json::Value SkClipRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1218 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001219 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
ethannicholas50a8dd02016-02-10 05:40:46 -08001220 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1221 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
reed67f62fa2016-06-29 11:36:34 -07001222
1223 SkString desc;
1224 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
1225
ethannicholas50a8dd02016-02-10 05:40:46 -08001226 return result;
1227}
1228
Mike Reedc1f77742016-12-09 09:00:50 -05001229SkClipRRectCommand::SkClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA)
robertphillips9bafc302015-02-13 11:13:00 -08001230 : INHERITED(kClipRRect_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001231 fRRect = rrect;
1232 fOp = op;
1233 fDoAA = doAA;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001234}
1235
fmalita8c89c522014-11-08 16:18:56 -08001236void SkClipRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001237 canvas->clipRRect(fRRect, fOp, fDoAA);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001238}
1239
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001240bool SkClipRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001241 render_rrect(canvas, fRRect);
1242 return true;
1243}
1244
ethannicholasf62a8b72016-02-11 10:35:21 -08001245Json::Value SkClipRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1246 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001247 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
1248 result[SKDEBUGCANVAS_ATTRIBUTE_REGIONOP] = make_json_regionop(fOp);
1249 result[SKDEBUGCANVAS_ATTRIBUTE_ANTIALIAS] = Json::Value(fDoAA);
1250 return result;
1251}
1252
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001253SkConcatCommand::SkConcatCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08001254 : INHERITED(kConcat_OpType) {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001255 fMatrix = matrix;
chudy@google.com902ebe52012-06-29 14:21:22 +00001256}
1257
fmalita8c89c522014-11-08 16:18:56 -08001258void SkConcatCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com24bfdac2013-03-22 16:33:31 +00001259 canvas->concat(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00001260}
1261
ethannicholasf62a8b72016-02-11 10:35:21 -08001262Json::Value SkConcatCommand::toJSON(UrlDataManager& urlDataManager) const {
1263 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08001264 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08001265 return result;
1266}
1267
reed97660cc2016-06-28 18:54:19 -07001268////
1269
1270SkDrawAnnotationCommand::SkDrawAnnotationCommand(const SkRect& rect, const char key[],
1271 sk_sp<SkData> value)
1272 : INHERITED(kDrawAnnotation_OpType)
1273 , fRect(rect)
1274 , fKey(key)
1275 , fValue(std::move(value))
robertphillipsfb409232016-06-29 10:28:11 -07001276{
robertphillipsfb409232016-06-29 10:28:11 -07001277}
reed97660cc2016-06-28 18:54:19 -07001278
1279void SkDrawAnnotationCommand::execute(SkCanvas* canvas) const {
1280 canvas->drawAnnotation(fRect, fKey.c_str(), fValue);
1281}
1282
1283Json::Value SkDrawAnnotationCommand::toJSON(UrlDataManager& urlDataManager) const {
1284 Json::Value result = INHERITED::toJSON(urlDataManager);
1285
1286 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
1287 result["key"] = Json::Value(fKey.c_str());
1288 if (fValue.get()) {
1289 // TODO: dump out the "value"
1290 }
reed67f62fa2016-06-29 11:36:34 -07001291
1292 SkString desc;
1293 str_append(&desc, fRect)->appendf(" %s", fKey.c_str());
1294 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(desc.c_str());
1295
reed97660cc2016-06-28 18:54:19 -07001296 return result;
1297}
1298
reed97660cc2016-06-28 18:54:19 -07001299////
1300
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001301SkDrawBitmapCommand::SkDrawBitmapCommand(const SkBitmap& bitmap, SkScalar left, SkScalar top,
robertphillipsb3f319f2014-08-13 10:46:23 -07001302 const SkPaint* paint)
Brian Osman8363be12018-05-29 13:38:07 -04001303 : INHERITED(kDrawBitmap_OpType)
1304 , fBitmap(bitmap)
1305 , fLeft(left)
1306 , fTop(top)
1307 , fPaint(paint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00001308
fmalita8c89c522014-11-08 16:18:56 -08001309void SkDrawBitmapCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04001310 canvas->drawBitmap(fBitmap, fLeft, fTop, fPaint.getMaybeNull());
chudy@google.com902ebe52012-06-29 14:21:22 +00001311}
1312
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001313bool SkDrawBitmapCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001314 render_bitmap(canvas, fBitmap);
1315 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001316}
1317
ethannicholasf62a8b72016-02-11 10:35:21 -08001318Json::Value SkDrawBitmapCommand::toJSON(UrlDataManager& urlDataManager) const {
1319 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001320 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08001321 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001322 Json::Value command(Json::objectValue);
1323 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07001324 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
Brian Osman8363be12018-05-29 13:38:07 -04001325 if (fPaint.isValid()) {
1326 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001327 }
1328 }
1329 return result;
1330}
1331
Brian Osman78a76482018-05-18 16:59:13 -04001332SkDrawBitmapLatticeCommand::SkDrawBitmapLatticeCommand(const SkBitmap& bitmap,
1333 const SkCanvas::Lattice& lattice,
1334 const SkRect& dst, const SkPaint* paint)
1335 : INHERITED(kDrawBitmapLattice_OpType)
1336 , fBitmap(bitmap)
1337 , fLattice(lattice)
Brian Osman8363be12018-05-29 13:38:07 -04001338 , fDst(dst)
1339 , fPaint(paint) {}
Brian Osman78a76482018-05-18 16:59:13 -04001340
1341void SkDrawBitmapLatticeCommand::execute(SkCanvas* canvas) const {
1342 canvas->drawBitmapLattice(fBitmap, fLattice, fDst, fPaint.getMaybeNull());
1343}
1344
1345bool SkDrawBitmapLatticeCommand::render(SkCanvas* canvas) const {
1346 SkAutoCanvasRestore acr(canvas, true);
1347 canvas->clear(0xFFFFFFFF);
1348
1349 xlate_and_scale_to_bounds(canvas, fDst);
1350
1351 this->execute(canvas);
1352 return true;
1353}
1354
1355Json::Value SkDrawBitmapLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
1356 Json::Value result = INHERITED::toJSON(urlDataManager);
1357 Json::Value encoded;
1358 if (flatten(fBitmap, &encoded, urlDataManager)) {
1359 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
1360 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
1361 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
1362 if (fPaint.isValid()) {
1363 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
1364 }
1365 }
1366
1367 SkString desc;
1368 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
1369
1370 return result;
1371}
1372
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001373SkDrawBitmapNineCommand::SkDrawBitmapNineCommand(const SkBitmap& bitmap, const SkIRect& center,
skia.committer@gmail.comdb35dab2014-03-27 03:02:48 +00001374 const SkRect& dst, const SkPaint* paint)
Brian Osman8363be12018-05-29 13:38:07 -04001375 : INHERITED(kDrawBitmapNine_OpType)
1376 , fBitmap(bitmap)
1377 , fCenter(center)
1378 , fDst(dst)
1379 , fPaint(paint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00001380
fmalita8c89c522014-11-08 16:18:56 -08001381void SkDrawBitmapNineCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04001382 canvas->drawBitmapNine(fBitmap, fCenter, fDst, fPaint.getMaybeNull());
chudy@google.com902ebe52012-06-29 14:21:22 +00001383}
1384
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001385bool SkDrawBitmapNineCommand::render(SkCanvas* canvas) const {
robertphillips2b829822015-11-18 12:59:42 -08001386 SkRect tmp = SkRect::Make(fCenter);
1387 render_bitmap(canvas, fBitmap, &tmp);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001388 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001389}
1390
ethannicholasf62a8b72016-02-11 10:35:21 -08001391Json::Value SkDrawBitmapNineCommand::toJSON(UrlDataManager& urlDataManager) const {
1392 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001393 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08001394 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001395 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
joshualittbd724132016-03-03 11:39:38 -08001396 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
brianosmanfad98562016-05-04 11:06:28 -07001397 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
Brian Osman8363be12018-05-29 13:38:07 -04001398 if (fPaint.isValid()) {
1399 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001400 }
1401 }
1402 return result;
1403}
1404
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001405SkDrawBitmapRectCommand::SkDrawBitmapRectCommand(const SkBitmap& bitmap, const SkRect* src,
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +00001406 const SkRect& dst, const SkPaint* paint,
reeda5517e22015-07-14 10:54:12 -07001407 SkCanvas::SrcRectConstraint constraint)
Brian Osman8363be12018-05-29 13:38:07 -04001408 : INHERITED(kDrawBitmapRect_OpType)
1409 , fBitmap(bitmap)
1410 , fSrc(src)
1411 , fDst(dst)
1412 , fPaint(paint)
1413 , fConstraint(constraint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00001414
fmalita8c89c522014-11-08 16:18:56 -08001415void SkDrawBitmapRectCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04001416 canvas->legacy_drawBitmapRect(fBitmap, fSrc.getMaybeNull(), fDst, fPaint.getMaybeNull(),
1417 fConstraint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001418}
1419
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001420bool SkDrawBitmapRectCommand::render(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04001421 render_bitmap(canvas, fBitmap, fSrc.getMaybeNull());
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001422 return true;
robertphillips@google.com53ec73d2012-11-26 13:09:17 +00001423}
1424
ethannicholasf62a8b72016-02-11 10:35:21 -08001425Json::Value SkDrawBitmapRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1426 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001427 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08001428 if (flatten(fBitmap, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001429 result[SKDEBUGCANVAS_ATTRIBUTE_BITMAP] = encoded;
Brian Osman8363be12018-05-29 13:38:07 -04001430 if (fSrc.isValid()) {
1431 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08001432 }
brianosmanfad98562016-05-04 11:06:28 -07001433 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
Brian Osman8363be12018-05-29 13:38:07 -04001434 if (fPaint.isValid()) {
1435 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001436 }
1437 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1438 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
1439 }
1440 }
reed67f62fa2016-06-29 11:36:34 -07001441
1442 SkString desc;
1443 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
1444
ethannicholas50a8dd02016-02-10 05:40:46 -08001445 return result;
1446}
1447
fmalita651c9202015-07-22 10:23:01 -07001448SkDrawImageCommand::SkDrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
1449 const SkPaint* paint)
1450 : INHERITED(kDrawImage_OpType)
1451 , fImage(SkRef(image))
1452 , fLeft(left)
Brian Osman8363be12018-05-29 13:38:07 -04001453 , fTop(top)
1454 , fPaint(paint) {}
fmalita651c9202015-07-22 10:23:01 -07001455
1456void SkDrawImageCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04001457 canvas->drawImage(fImage.get(), fLeft, fTop, fPaint.getMaybeNull());
fmalita651c9202015-07-22 10:23:01 -07001458}
1459
1460bool SkDrawImageCommand::render(SkCanvas* canvas) const {
1461 SkAutoCanvasRestore acr(canvas, true);
1462 canvas->clear(0xFFFFFFFF);
1463
1464 xlate_and_scale_to_bounds(canvas, SkRect::MakeXYWH(fLeft, fTop,
1465 SkIntToScalar(fImage->width()),
1466 SkIntToScalar(fImage->height())));
1467 this->execute(canvas);
1468 return true;
1469}
1470
ethannicholasf62a8b72016-02-11 10:35:21 -08001471Json::Value SkDrawImageCommand::toJSON(UrlDataManager& urlDataManager) const {
1472 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001473 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08001474 if (flatten(*fImage, &encoded, urlDataManager)) {
ethannicholas50a8dd02016-02-10 05:40:46 -08001475 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
brianosmanfad98562016-05-04 11:06:28 -07001476 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fLeft, fTop);
ethannicholas50a8dd02016-02-10 05:40:46 -08001477 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07001478 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001479 }
msarett0ac1bec2016-08-29 09:15:33 -07001480
1481 result[SKDEBUGCANVAS_ATTRIBUTE_UNIQUE_ID] = fImage->uniqueID();
1482 result[SKDEBUGCANVAS_ATTRIBUTE_WIDTH] = fImage->width();
1483 result[SKDEBUGCANVAS_ATTRIBUTE_HEIGHT] = fImage->height();
1484 switch (fImage->alphaType()) {
1485 case kOpaque_SkAlphaType:
1486 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_OPAQUE;
1487 break;
1488 case kPremul_SkAlphaType:
1489 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_PREMUL;
1490 break;
1491 case kUnpremul_SkAlphaType:
1492 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNPREMUL;
1493 break;
1494 default:
1495 result[SKDEBUGCANVAS_ATTRIBUTE_ALPHA] = SKDEBUGCANVAS_ALPHATYPE_UNKNOWN;
1496 break;
1497 }
ethannicholas50a8dd02016-02-10 05:40:46 -08001498 }
1499 return result;
1500}
1501
Stan Ilievac42aeb2017-01-12 16:20:50 -05001502SkDrawImageLatticeCommand::SkDrawImageLatticeCommand(const SkImage* image,
1503 const SkCanvas::Lattice& lattice,
1504 const SkRect& dst, const SkPaint* paint)
1505 : INHERITED(kDrawImageLattice_OpType)
1506 , fImage(SkRef(image))
1507 , fLattice(lattice)
Brian Osman8363be12018-05-29 13:38:07 -04001508 , fDst(dst)
1509 , fPaint(paint) {}
Stan Ilievac42aeb2017-01-12 16:20:50 -05001510
1511void SkDrawImageLatticeCommand::execute(SkCanvas* canvas) const {
Brian Osman78a76482018-05-18 16:59:13 -04001512 canvas->drawImageLattice(fImage.get(), fLattice, fDst, fPaint.getMaybeNull());
Stan Ilievac42aeb2017-01-12 16:20:50 -05001513}
1514
1515bool SkDrawImageLatticeCommand::render(SkCanvas* canvas) const {
1516 SkAutoCanvasRestore acr(canvas, true);
1517 canvas->clear(0xFFFFFFFF);
1518
1519 xlate_and_scale_to_bounds(canvas, fDst);
1520
1521 this->execute(canvas);
1522 return true;
1523}
1524
1525Json::Value SkDrawImageLatticeCommand::toJSON(UrlDataManager& urlDataManager) const {
1526 Json::Value result = INHERITED::toJSON(urlDataManager);
1527 Json::Value encoded;
1528 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001529 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
Stan Ilievac42aeb2017-01-12 16:20:50 -05001530 result[SKDEBUGCANVAS_ATTRIBUTE_LATTICE] = MakeJsonLattice(fLattice);
1531 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
1532 if (fPaint.isValid()) {
1533 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
1534 }
1535 }
1536
1537 SkString desc;
1538 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
1539
1540 return result;
1541}
1542
fmalita651c9202015-07-22 10:23:01 -07001543SkDrawImageRectCommand::SkDrawImageRectCommand(const SkImage* image, const SkRect* src,
1544 const SkRect& dst, const SkPaint* paint,
1545 SkCanvas::SrcRectConstraint constraint)
1546 : INHERITED(kDrawImageRect_OpType)
1547 , fImage(SkRef(image))
Brian Osman8363be12018-05-29 13:38:07 -04001548 , fSrc(src)
fmalita651c9202015-07-22 10:23:01 -07001549 , fDst(dst)
Brian Osman8363be12018-05-29 13:38:07 -04001550 , fPaint(paint)
1551 , fConstraint(constraint) {}
fmalita651c9202015-07-22 10:23:01 -07001552
1553void SkDrawImageRectCommand::execute(SkCanvas* canvas) const {
Hal Canary1b612a82016-11-03 16:26:13 -04001554 canvas->legacy_drawImageRect(fImage.get(), fSrc.getMaybeNull(), fDst,
1555 fPaint.getMaybeNull(), fConstraint);
fmalita651c9202015-07-22 10:23:01 -07001556}
1557
1558bool SkDrawImageRectCommand::render(SkCanvas* canvas) const {
1559 SkAutoCanvasRestore acr(canvas, true);
1560 canvas->clear(0xFFFFFFFF);
1561
1562 xlate_and_scale_to_bounds(canvas, fDst);
1563
1564 this->execute(canvas);
1565 return true;
1566}
1567
ethannicholasf62a8b72016-02-11 10:35:21 -08001568Json::Value SkDrawImageRectCommand::toJSON(UrlDataManager& urlDataManager) const {
1569 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001570 Json::Value encoded;
ethannicholasf62a8b72016-02-11 10:35:21 -08001571 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
Brian Osmanc25e2692018-03-12 10:57:28 -04001572 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
ethannicholas50a8dd02016-02-10 05:40:46 -08001573 if (fSrc.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07001574 result[SKDEBUGCANVAS_ATTRIBUTE_SRC] = MakeJsonRect(*fSrc.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08001575 }
brianosmanfad98562016-05-04 11:06:28 -07001576 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
ethannicholas50a8dd02016-02-10 05:40:46 -08001577 if (fPaint.isValid()) {
brianosmanfad98562016-05-04 11:06:28 -07001578 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001579 }
1580 if (fConstraint == SkCanvas::kStrict_SrcRectConstraint) {
1581 result[SKDEBUGCANVAS_ATTRIBUTE_STRICT] = Json::Value(true);
1582 }
1583 }
reed67f62fa2016-06-29 11:36:34 -07001584
1585 SkString desc;
1586 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fDst)->c_str());
1587
ethannicholas50a8dd02016-02-10 05:40:46 -08001588 return result;
1589}
1590
Brian Osmanc25e2692018-03-12 10:57:28 -04001591SkDrawImageNineCommand::SkDrawImageNineCommand(const SkImage* image, const SkIRect& center,
1592 const SkRect& dst, const SkPaint* paint)
Brian Osman8363be12018-05-29 13:38:07 -04001593 : INHERITED(kDrawImageNine_OpType)
1594 , fImage(SkRef(image))
1595 , fCenter(center)
1596 , fDst(dst)
1597 , fPaint(paint) {}
Brian Osmanc25e2692018-03-12 10:57:28 -04001598
1599void SkDrawImageNineCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04001600 canvas->drawImageNine(fImage.get(), fCenter, fDst, fPaint.getMaybeNull());
Brian Osmanc25e2692018-03-12 10:57:28 -04001601}
1602
1603bool SkDrawImageNineCommand::render(SkCanvas* canvas) const {
1604 SkAutoCanvasRestore acr(canvas, true);
1605 canvas->clear(0xFFFFFFFF);
1606
1607 xlate_and_scale_to_bounds(canvas, fDst);
1608
1609 this->execute(canvas);
1610 return true;
1611}
1612
1613Json::Value SkDrawImageNineCommand::toJSON(UrlDataManager& urlDataManager) const {
1614 Json::Value result = INHERITED::toJSON(urlDataManager);
1615 Json::Value encoded;
1616 if (flatten(*fImage.get(), &encoded, urlDataManager)) {
1617 result[SKDEBUGCANVAS_ATTRIBUTE_IMAGE] = encoded;
1618 result[SKDEBUGCANVAS_ATTRIBUTE_CENTER] = MakeJsonIRect(fCenter);
1619 result[SKDEBUGCANVAS_ATTRIBUTE_DST] = MakeJsonRect(fDst);
Brian Osman8363be12018-05-29 13:38:07 -04001620 if (fPaint.isValid()) {
1621 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
Brian Osmanc25e2692018-03-12 10:57:28 -04001622 }
1623 }
1624 return result;
1625}
1626
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001627SkDrawOvalCommand::SkDrawOvalCommand(const SkRect& oval, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001628 : INHERITED(kDrawOval_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001629 fOval = oval;
1630 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00001631}
1632
fmalita8c89c522014-11-08 16:18:56 -08001633void SkDrawOvalCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001634 canvas->drawOval(fOval, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00001635}
1636
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001637bool SkDrawOvalCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001638 canvas->clear(0xFFFFFFFF);
1639 canvas->save();
1640
1641 xlate_and_scale_to_bounds(canvas, fOval);
1642
1643 SkPaint p;
1644 p.setColor(SK_ColorBLACK);
1645 p.setStyle(SkPaint::kStroke_Style);
1646
1647 canvas->drawOval(fOval, p);
1648 canvas->restore();
1649
1650 return true;
1651}
1652
ethannicholasf62a8b72016-02-11 10:35:21 -08001653Json::Value SkDrawOvalCommand::toJSON(UrlDataManager& urlDataManager) const {
1654 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001655 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
1656 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001657 return result;
1658}
1659
bsalomonac3aa242016-08-19 11:25:19 -07001660SkDrawArcCommand::SkDrawArcCommand(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
1661 bool useCenter, const SkPaint& paint)
Brian Osmanc25e2692018-03-12 10:57:28 -04001662 : INHERITED(kDrawArc_OpType) {
bsalomonac3aa242016-08-19 11:25:19 -07001663 fOval = oval;
1664 fStartAngle = startAngle;
1665 fSweepAngle = sweepAngle;
1666 fUseCenter = useCenter;
1667 fPaint = paint;
bsalomonac3aa242016-08-19 11:25:19 -07001668}
1669
1670void SkDrawArcCommand::execute(SkCanvas* canvas) const {
1671 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, fPaint);
1672}
1673
1674bool SkDrawArcCommand::render(SkCanvas* canvas) const {
1675 canvas->clear(0xFFFFFFFF);
1676 canvas->save();
1677
1678 xlate_and_scale_to_bounds(canvas, fOval);
1679
1680 SkPaint p;
1681 p.setColor(SK_ColorBLACK);
1682 p.setStyle(SkPaint::kStroke_Style);
1683
1684 canvas->drawArc(fOval, fStartAngle, fSweepAngle, fUseCenter, p);
1685 canvas->restore();
1686
1687 return true;
1688}
1689
1690Json::Value SkDrawArcCommand::toJSON(UrlDataManager& urlDataManager) const {
1691 Json::Value result = INHERITED::toJSON(urlDataManager);
1692 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fOval);
1693 result[SKDEBUGCANVAS_ATTRIBUTE_STARTANGLE] = MakeJsonScalar(fStartAngle);
1694 result[SKDEBUGCANVAS_ATTRIBUTE_SWEEPANGLE] = MakeJsonScalar(fSweepAngle);
1695 result[SKDEBUGCANVAS_ATTRIBUTE_USECENTER] = fUseCenter;
1696 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
1697 return result;
1698}
1699
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001700SkDrawPaintCommand::SkDrawPaintCommand(const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001701 : INHERITED(kDrawPaint_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001702 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00001703}
1704
fmalita8c89c522014-11-08 16:18:56 -08001705void SkDrawPaintCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001706 canvas->drawPaint(fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001707}
1708
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001709bool SkDrawPaintCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001710 canvas->clear(0xFFFFFFFF);
1711 canvas->drawPaint(fPaint);
1712 return true;
1713}
1714
ethannicholasf62a8b72016-02-11 10:35:21 -08001715Json::Value SkDrawPaintCommand::toJSON(UrlDataManager& urlDataManager) const {
1716 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001717 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001718 return result;
1719}
1720
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001721SkDrawPathCommand::SkDrawPathCommand(const SkPath& path, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001722 : INHERITED(kDrawPath_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001723 fPath = path;
1724 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00001725}
1726
fmalita8c89c522014-11-08 16:18:56 -08001727void SkDrawPathCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001728 canvas->drawPath(fPath, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001729}
1730
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001731bool SkDrawPathCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001732 render_path(canvas, fPath);
1733 return true;
robertphillips@google.com6dec8fc2012-11-21 17:11:02 +00001734}
1735
ethannicholasf62a8b72016-02-11 10:35:21 -08001736Json::Value SkDrawPathCommand::toJSON(UrlDataManager& urlDataManager) const {
1737 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07001738 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
1739 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001740 return result;
1741}
1742
Brian Osmanc25e2692018-03-12 10:57:28 -04001743SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
1744 : INHERITED(kDrawRegion_OpType) {
1745 fRegion = region;
1746 fPaint = paint;
Brian Osmanc25e2692018-03-12 10:57:28 -04001747}
1748
1749void SkDrawRegionCommand::execute(SkCanvas* canvas) const {
1750 canvas->drawRegion(fRegion, fPaint);
1751}
1752
1753bool SkDrawRegionCommand::render(SkCanvas* canvas) const {
1754 render_region(canvas, fRegion);
1755 return true;
1756}
1757
1758Json::Value SkDrawRegionCommand::toJSON(UrlDataManager& urlDataManager) const {
1759 Json::Value result = INHERITED::toJSON(urlDataManager);
1760 result[SKDEBUGCANVAS_ATTRIBUTE_REGION] = MakeJsonRegion(fRegion);
1761 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
1762 return result;
1763}
1764
fmalita160ebb22015-04-01 20:58:37 -07001765SkBeginDrawPictureCommand::SkBeginDrawPictureCommand(const SkPicture* picture,
1766 const SkMatrix* matrix,
1767 const SkPaint* paint)
1768 : INHERITED(kBeginDrawPicture_OpType)
Brian Osman8363be12018-05-29 13:38:07 -04001769 , fPicture(SkRef(picture))
1770 , fMatrix(matrix)
1771 , fPaint(paint) {}
fmalita160ebb22015-04-01 20:58:37 -07001772
1773void SkBeginDrawPictureCommand::execute(SkCanvas* canvas) const {
1774 if (fPaint.isValid()) {
1775 SkRect bounds = fPicture->cullRect();
1776 if (fMatrix.isValid()) {
1777 fMatrix.get()->mapRect(&bounds);
1778 }
1779 canvas->saveLayer(&bounds, fPaint.get());
1780 }
1781
1782 if (fMatrix.isValid()) {
1783 if (!fPaint.isValid()) {
1784 canvas->save();
1785 }
1786 canvas->concat(*fMatrix.get());
1787 }
chudy@google.com902ebe52012-06-29 14:21:22 +00001788}
1789
fmalita160ebb22015-04-01 20:58:37 -07001790bool SkBeginDrawPictureCommand::render(SkCanvas* canvas) const {
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00001791 canvas->clear(0xFFFFFFFF);
1792 canvas->save();
1793
robertphillipsa8d7f0b2014-08-29 08:03:56 -07001794 xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00001795
robertphillips9b14f262014-06-04 05:40:44 -07001796 canvas->drawPicture(fPicture.get());
commit-bot@chromium.orge898e9c2013-11-21 17:08:12 +00001797
1798 canvas->restore();
1799
1800 return true;
1801}
1802
fmalita160ebb22015-04-01 20:58:37 -07001803SkEndDrawPictureCommand::SkEndDrawPictureCommand(bool restore)
1804 : INHERITED(kEndDrawPicture_OpType) , fRestore(restore) { }
1805
1806void SkEndDrawPictureCommand::execute(SkCanvas* canvas) const {
1807 if (fRestore) {
1808 canvas->restore();
1809 }
1810}
1811
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001812SkDrawPointsCommand::SkDrawPointsCommand(SkCanvas::PointMode mode, size_t count,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001813 const SkPoint pts[], const SkPaint& paint)
Brian Osman8363be12018-05-29 13:38:07 -04001814 : INHERITED(kDrawPoints_OpType)
1815 , fMode(mode)
1816 , fPts(pts, count)
1817 , fPaint(paint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00001818
fmalita8c89c522014-11-08 16:18:56 -08001819void SkDrawPointsCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04001820 canvas->drawPoints(fMode, fPts.count(), fPts.begin(), fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001821}
1822
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001823bool SkDrawPointsCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001824 canvas->clear(0xFFFFFFFF);
1825 canvas->save();
1826
1827 SkRect bounds;
1828
1829 bounds.setEmpty();
Brian Osman8363be12018-05-29 13:38:07 -04001830 for (int i = 0; i < fPts.count(); ++i) {
Mike Reed185ffe92018-01-08 17:09:54 -05001831 SkRectPriv::GrowToInclude(&bounds, fPts[i]);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001832 }
skia.committer@gmail.coma0090832013-06-07 07:01:06 +00001833
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001834 xlate_and_scale_to_bounds(canvas, bounds);
1835
1836 SkPaint p;
1837 p.setColor(SK_ColorBLACK);
1838 p.setStyle(SkPaint::kStroke_Style);
1839
Brian Osman8363be12018-05-29 13:38:07 -04001840 canvas->drawPoints(fMode, fPts.count(), fPts.begin(), p);
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00001841 canvas->restore();
1842
1843 return true;
1844}
1845
ethannicholasf62a8b72016-02-11 10:35:21 -08001846Json::Value SkDrawPointsCommand::toJSON(UrlDataManager& urlDataManager) const {
1847 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001848 result[SKDEBUGCANVAS_ATTRIBUTE_MODE] = make_json_pointmode(fMode);
1849 Json::Value points(Json::arrayValue);
Brian Osman8363be12018-05-29 13:38:07 -04001850 for (int i = 0; i < fPts.count(); i++) {
brianosmanfad98562016-05-04 11:06:28 -07001851 points.append(MakeJsonPoint(fPts[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001852 }
1853 result[SKDEBUGCANVAS_ATTRIBUTE_POINTS] = points;
brianosmanfad98562016-05-04 11:06:28 -07001854 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001855 return result;
1856}
1857
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001858SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001859 const SkPoint pos[], const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001860 : INHERITED(kDrawPosText_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001861 size_t numPts = paint.countText(text, byteLength);
chudy@google.com902ebe52012-06-29 14:21:22 +00001862
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001863 fText = new char[byteLength];
1864 memcpy(fText, text, byteLength);
1865 fByteLength = byteLength;
1866
1867 fPos = new SkPoint[numPts];
1868 memcpy(fPos, pos, numPts * sizeof(SkPoint));
1869
1870 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00001871}
1872
fmalita8c89c522014-11-08 16:18:56 -08001873void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001874 canvas->drawPosText(fText, fByteLength, fPos, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001875}
1876
ethannicholasf62a8b72016-02-11 10:35:21 -08001877Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
1878 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07001879 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08001880 ((const char*) fText) + fByteLength);
1881 Json::Value coords(Json::arrayValue);
bungeman51190df2016-03-09 07:42:54 -08001882 size_t numCoords = fPaint.textToGlyphs(fText, fByteLength, nullptr);
1883 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07001884 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001885 }
1886 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07001887 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001888 return result;
1889}
1890
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001891SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
1892 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001893 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001894 : INHERITED(kDrawPosTextH_OpType) {
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001895 size_t numPts = paint.countText(text, byteLength);
1896
1897 fText = new char[byteLength];
1898 memcpy(fText, text, byteLength);
robertphillips@google.com91217d02013-03-17 18:33:46 +00001899 fByteLength = byteLength;
robertphillips@google.coma3a09ab2013-03-22 12:25:30 +00001900
1901 fXpos = new SkScalar[numPts];
1902 memcpy(fXpos, xpos, numPts * sizeof(SkScalar));
1903
robertphillips@google.com91217d02013-03-17 18:33:46 +00001904 fConstY = constY;
1905 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00001906}
1907
fmalita8c89c522014-11-08 16:18:56 -08001908void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00001909 canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001910}
1911
bungeman51190df2016-03-09 07:42:54 -08001912Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
1913 Json::Value result = INHERITED::toJSON(urlDataManager);
1914 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
1915 ((const char*) fText) + fByteLength);
1916 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
1917 Json::Value xpos(Json::arrayValue);
1918 size_t numXpos = fPaint.textToGlyphs(fText, fByteLength, nullptr);
1919 for (size_t i = 0; i < numXpos; i++) {
1920 xpos.append(Json::Value(fXpos[i]));
1921 }
1922 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07001923 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08001924 return result;
1925}
1926
fmalita37283c22016-09-13 10:00:23 -07001927SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07001928 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001929 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07001930 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07001931 , fXPos(x)
1932 , fYPos(y)
Brian Osman255735e2018-04-06 14:51:42 -04001933 , fPaint(paint) {}
fmalitab7425172014-08-26 07:56:44 -07001934
fmalita8c89c522014-11-08 16:18:56 -08001935void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07001936 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
1937}
1938
fmalita55773872014-08-29 15:08:20 -07001939bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
1940 canvas->clear(SK_ColorWHITE);
1941 canvas->save();
1942
1943 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
1944 xlate_and_scale_to_bounds(canvas, bounds);
1945
fmalita37283c22016-09-13 10:00:23 -07001946 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07001947
1948 canvas->restore();
1949
1950 return true;
1951}
1952
ethannicholasf62a8b72016-02-11 10:35:21 -08001953Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
1954 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001955 Json::Value runs(Json::arrayValue);
1956 SkTextBlobRunIterator iter(fBlob.get());
1957 while (!iter.done()) {
1958 Json::Value run(Json::objectValue);
1959 Json::Value jsonPositions(Json::arrayValue);
1960 Json::Value jsonGlyphs(Json::arrayValue);
1961 const SkScalar* iterPositions = iter.pos();
1962 const uint16_t* iterGlyphs = iter.glyphs();
1963 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
1964 switch (iter.positioning()) {
1965 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07001966 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
1967 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001968 break;
1969 case SkTextBlob::kHorizontal_Positioning:
1970 jsonPositions.append(Json::Value(iterPositions[i]));
1971 break;
1972 case SkTextBlob::kDefault_Positioning:
1973 break;
1974 }
1975 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
1976 }
1977 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
1978 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
1979 }
1980 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
1981 SkPaint fontPaint;
1982 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07001983 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
1984 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08001985 runs.append(run);
1986 iter.next();
1987 }
reed6d2c3e72016-07-07 14:10:14 -07001988 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08001989 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
1990 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
1991 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07001992 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07001993 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07001994
1995 SkString desc;
1996 // make the bounds local by applying the x,y
1997 bounds.offset(fXPos, fYPos);
1998 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
1999
ethannicholas50a8dd02016-02-10 05:40:46 -08002000 return result;
2001}
2002
robertphillips9bafc302015-02-13 11:13:00 -08002003SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04002004 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08002005 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04002006 : INHERITED(kDrawPatch_OpType)
2007 , fBlendMode(bmode)
2008{
robertphillips9bafc302015-02-13 11:13:00 -08002009 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08002010 if (colors != nullptr) {
2011 memcpy(fColors, colors, sizeof(fColors));
2012 fColorsPtr = fColors;
2013 } else {
2014 fColorsPtr = nullptr;
2015 }
2016 if (texCoords != nullptr) {
2017 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
2018 fTexCoordsPtr = fTexCoords;
2019 } else {
2020 fTexCoordsPtr = nullptr;
2021 }
robertphillips9bafc302015-02-13 11:13:00 -08002022 fPaint = paint;
robertphillips9bafc302015-02-13 11:13:00 -08002023}
2024
2025void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04002026 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08002027}
2028
ethannicholasf62a8b72016-02-11 10:35:21 -08002029Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
2030 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08002031 Json::Value cubics = Json::Value(Json::arrayValue);
2032 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002033 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08002034 }
2035 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
2036 if (fColorsPtr != nullptr) {
2037 Json::Value colors = Json::Value(Json::arrayValue);
2038 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002039 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08002040 }
2041 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
2042 }
2043 if (fTexCoordsPtr != nullptr) {
2044 Json::Value texCoords = Json::Value(Json::arrayValue);
2045 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002046 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08002047 }
2048 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
2049 }
Mike Reed7d954ad2016-10-28 15:42:34 -04002050 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08002051 return result;
2052}
2053
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002054SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002055 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002056 fRect = rect;
2057 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002058}
2059
fmalita8c89c522014-11-08 16:18:56 -08002060void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002061 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002062}
2063
ethannicholasf62a8b72016-02-11 10:35:21 -08002064Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2065 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002066 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
2067 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07002068
2069 SkString desc;
2070 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
2071
ethannicholas50a8dd02016-02-10 05:40:46 -08002072 return result;
2073}
2074
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002075SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002076 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002077 fRRect = rrect;
2078 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002079}
2080
fmalita8c89c522014-11-08 16:18:56 -08002081void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00002082 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002083}
2084
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002085bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002086 render_rrect(canvas, fRRect);
2087 return true;
2088}
2089
ethannicholasf62a8b72016-02-11 10:35:21 -08002090Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2091 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002092 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07002093 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002094 return result;
2095}
2096
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00002097SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002098 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002099 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002100 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002101 fOuter = outer;
2102 fInner = inner;
2103 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002104}
2105
fmalita8c89c522014-11-08 16:18:56 -08002106void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002107 canvas->drawDRRect(fOuter, fInner, fPaint);
2108}
2109
2110bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
2111 render_drrect(canvas, fOuter, fInner);
2112 return true;
2113}
2114
ethannicholasf62a8b72016-02-11 10:35:21 -08002115Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2116 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002117 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
2118 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07002119 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002120 return result;
2121}
2122
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04002123SkDrawShadowCommand::SkDrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
2124 : INHERITED(kDrawShadow_OpType) {
2125 fPath = path;
2126 fShadowRec = rec;
2127}
2128
2129void SkDrawShadowCommand::execute(SkCanvas* canvas) const {
2130 canvas->private_draw_shadow_rec(fPath, fShadowRec);
2131}
2132
2133bool SkDrawShadowCommand::render(SkCanvas* canvas) const {
2134 render_shadow(canvas, fPath, fShadowRec);
2135 return true;
2136}
2137
2138Json::Value SkDrawShadowCommand::toJSON(UrlDataManager& urlDataManager) const {
2139 Json::Value result = INHERITED::toJSON(urlDataManager);
2140 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2141
2142 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
2143 bool transparentOccluder =
2144 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
2145
2146 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2147 result[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE] = MakeJsonPoint3(fShadowRec.fZPlaneParams);
2148 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION] = MakeJsonPoint3(fShadowRec.fLightPos);
2149 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS] = MakeJsonScalar(fShadowRec.fLightRadius);
2150 result[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR] = MakeJsonColor(fShadowRec.fAmbientColor);
2151 result[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR] = MakeJsonColor(fShadowRec.fSpotColor);
2152 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
2153 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
2154 return result;
2155}
2156
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002157SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002158 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002159 : INHERITED(kDrawText_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002160 fText = new char[byteLength];
2161 memcpy(fText, text, byteLength);
2162 fByteLength = byteLength;
2163 fX = x;
2164 fY = y;
2165 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002166}
2167
fmalita8c89c522014-11-08 16:18:56 -08002168void SkDrawTextCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002169 canvas->drawText(fText, fByteLength, fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002170}
2171
ethannicholasf62a8b72016-02-11 10:35:21 -08002172Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2173 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002174 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002175 ((const char*) fText) + fByteLength);
2176 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07002177 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
2178 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002179 return result;
2180}
2181
reed45561a02016-07-07 12:47:17 -07002182///////////////////////////////////////////////////////////////////////////////////////////////////
2183
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002184SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
2185 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002186 const SkPaint& paint)
Brian Osman8363be12018-05-29 13:38:07 -04002187 : INHERITED(kDrawTextOnPath_OpType)
2188 , fMatrix(matrix) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002189 fText = new char[byteLength];
2190 memcpy(fText, text, byteLength);
2191 fByteLength = byteLength;
2192 fPath = path;
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002193 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002194}
2195
fmalita8c89c522014-11-08 16:18:56 -08002196void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04002197 canvas->drawTextOnPath(fText, fByteLength, fPath, fMatrix.getMaybeNull(), fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002198}
2199
ethannicholasf62a8b72016-02-11 10:35:21 -08002200Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2201 Json::Value result = INHERITED::toJSON(urlDataManager);
halcanary9d524f22016-03-29 09:03:52 -07002202 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
ethannicholas50a8dd02016-02-10 05:40:46 -08002203 ((const char*) fText) + fByteLength);
2204 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07002205 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
Brian Osman8363be12018-05-29 13:38:07 -04002206 if (fMatrix.isValid()) {
2207 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(*fMatrix.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002208 }
brianosmanfad98562016-05-04 11:06:28 -07002209 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002210 return result;
2211}
2212
reed45561a02016-07-07 12:47:17 -07002213///////////////////////////////////////////////////////////////////////////////////////////////////
2214
2215SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
2216 const SkRSXform xform[], const SkRect* cull,
2217 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07002218 : INHERITED(kDrawTextRSXform_OpType)
Brian Osman8363be12018-05-29 13:38:07 -04002219 , fCull(cull)
reed45561a02016-07-07 12:47:17 -07002220{
2221 fText = new char[byteLength];
2222 memcpy(fText, text, byteLength);
2223 fByteLength = byteLength;
2224 int count = paint.countText(text, byteLength);
2225 fXform = new SkRSXform[count];
2226 memcpy(fXform, xform, count * sizeof(SkRSXform));
reed45561a02016-07-07 12:47:17 -07002227 fPaint = paint;
reed45561a02016-07-07 12:47:17 -07002228}
2229
2230void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04002231 canvas->drawTextRSXform(fText, fByteLength, fXform, fCull.getMaybeNull(), fPaint);
reed45561a02016-07-07 12:47:17 -07002232}
2233
2234Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
2235 Json::Value result = INHERITED::toJSON(urlDataManager);
2236 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = Json::Value((const char*) fText,
2237 ((const char*) fText) + fByteLength);
2238 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2239 return result;
2240}
2241
reed45561a02016-07-07 12:47:17 -07002242///////////////////////////////////////////////////////////////////////////////////////////////////
2243
Mike Reedfed9cfd2017-03-17 12:09:04 -04002244SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002245 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04002246 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04002247 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04002248 , fBlendMode(bmode)
Brian Osman255735e2018-04-06 14:51:42 -04002249 , fPaint(paint) {}
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002250
fmalita8c89c522014-11-08 16:18:56 -08002251void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04002252 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002253}
2254
Brian Osman616f1cb2018-05-29 11:23:35 -04002255///////////////////////////////////////////////////////////////////////////////////////////////////
2256
2257SkDrawAtlasCommand::SkDrawAtlasCommand(const SkImage* image, const SkRSXform xform[],
2258 const SkRect tex[], const SkColor colors[], int count,
2259 SkBlendMode bmode, const SkRect* cull,
2260 const SkPaint* paint)
2261 : INHERITED(kDrawAtlas_OpType)
2262 , fImage(SkRef(image))
2263 , fXform(xform, count)
2264 , fTex(tex, count)
2265 , fColors(colors, colors ? count : 0)
2266 , fBlendMode(bmode)
2267 , fCull(cull)
2268 , fPaint(paint) {}
2269
2270void SkDrawAtlasCommand::execute(SkCanvas* canvas) const {
2271 canvas->drawAtlas(fImage.get(), fXform.begin(), fTex.begin(),
2272 fColors.isEmpty() ? nullptr : fColors.begin(), fXform.count(), fBlendMode,
2273 fCull.getMaybeNull(), fPaint.getMaybeNull());
2274}
2275
2276///////////////////////////////////////////////////////////////////////////////////////////////////
2277
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002278SkRestoreCommand::SkRestoreCommand()
Brian Osman255735e2018-04-06 14:51:42 -04002279 : INHERITED(kRestore_OpType) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00002280
fmalita8c89c522014-11-08 16:18:56 -08002281void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00002282 canvas->restore();
2283}
2284
Florin Malita5f6102d2014-06-30 10:13:28 -04002285SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08002286 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00002287}
2288
fmalita8c89c522014-11-08 16:18:56 -08002289void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04002290 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00002291}
2292
reed4960eee2015-12-18 07:09:18 -08002293SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
Brian Osman8363be12018-05-29 13:38:07 -04002294 : INHERITED(kSaveLayer_OpType)
2295 , fBounds(rec.fBounds)
2296 , fPaint(rec.fPaint)
2297 , fBackdrop(SkSafeRef(rec.fBackdrop))
2298 , fSaveLayerFlags(rec.fSaveLayerFlags) {}
ethannicholas50a8dd02016-02-10 05:40:46 -08002299
fmalita8c89c522014-11-08 16:18:56 -08002300void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04002301 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.getMaybeNull(), fPaint.getMaybeNull(),
reed4960eee2015-12-18 07:09:18 -08002302 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00002303}
2304
ethannicholasf62a8b72016-02-11 10:35:21 -08002305Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
2306 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman8363be12018-05-29 13:38:07 -04002307 if (fBounds.isValid()) {
2308 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(*fBounds.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002309 }
Brian Osman8363be12018-05-29 13:38:07 -04002310 if (fPaint.isValid()) {
2311 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002312 }
2313 if (fBackdrop != nullptr) {
2314 Json::Value jsonBackdrop;
Brian Osman8363be12018-05-29 13:38:07 -04002315 flatten(fBackdrop.get(), &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002316 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
2317 }
2318 if (fSaveLayerFlags != 0) {
2319 SkDebugf("unsupported: saveLayer flags\n");
2320 SkASSERT(false);
2321 }
2322 return result;
2323}
2324
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002325SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08002326 : INHERITED(kSetMatrix_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002327 fMatrix = matrix;
robertphillips70171682014-10-16 14:28:28 -07002328}
2329
fmalita8c89c522014-11-08 16:18:56 -08002330void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
Brian Osman255735e2018-04-06 14:51:42 -04002331 canvas->setMatrix(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00002332}
2333
ethannicholasf62a8b72016-02-11 10:35:21 -08002334Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
2335 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08002336 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08002337 return result;
2338}