blob: 215328603ffca0e4bd2ad109df5a5865c526939b [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
Brian Osman65197ff2018-05-29 14:25:39 -04001858static Json::Value make_json_text(sk_sp<SkData> text) {
1859 return Json::Value((const char*)text->data(), (const char*)text->data() + text->size());
chudy@google.com902ebe52012-06-29 14:21:22 +00001860}
1861
Brian Osman65197ff2018-05-29 14:25:39 -04001862SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength,
1863 const SkPoint pos[], const SkPaint& paint)
1864 : INHERITED(kDrawPosText_OpType)
1865 , fText(SkData::MakeWithCopy(text, byteLength))
1866 , fPos(pos, paint.countText(text, byteLength))
1867 , fPaint(paint) {}
1868
fmalita8c89c522014-11-08 16:18:56 -08001869void SkDrawPosTextCommand::execute(SkCanvas* canvas) const {
Brian Osman65197ff2018-05-29 14:25:39 -04001870 canvas->drawPosText(fText->data(), fText->size(), fPos.begin(), fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001871}
1872
ethannicholasf62a8b72016-02-11 10:35:21 -08001873Json::Value SkDrawPosTextCommand::toJSON(UrlDataManager& urlDataManager) const {
1874 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman65197ff2018-05-29 14:25:39 -04001875 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = make_json_text(fText);
ethannicholas50a8dd02016-02-10 05:40:46 -08001876 Json::Value coords(Json::arrayValue);
Brian Osman65197ff2018-05-29 14:25:39 -04001877 size_t numCoords = fPaint.textToGlyphs(fText->data(), fText->size(), nullptr);
bungeman51190df2016-03-09 07:42:54 -08001878 for (size_t i = 0; i < numCoords; i++) {
brianosmanfad98562016-05-04 11:06:28 -07001879 coords.append(MakeJsonPoint(fPos[i]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001880 }
1881 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = coords;
brianosmanfad98562016-05-04 11:06:28 -07001882 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001883 return result;
1884}
1885
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00001886SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength,
1887 const SkScalar xpos[], SkScalar constY,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00001888 const SkPaint& paint)
Brian Osman65197ff2018-05-29 14:25:39 -04001889 : INHERITED(kDrawPosTextH_OpType)
1890 , fText(SkData::MakeWithCopy(text, byteLength))
1891 , fXpos(xpos, paint.countText(text, byteLength))
1892 , fConstY(constY)
1893 , fPaint(paint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00001894
fmalita8c89c522014-11-08 16:18:56 -08001895void SkDrawPosTextHCommand::execute(SkCanvas* canvas) const {
Brian Osman65197ff2018-05-29 14:25:39 -04001896 canvas->drawPosTextH(fText->data(), fText->size(), fXpos.begin(), fConstY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00001897}
1898
bungeman51190df2016-03-09 07:42:54 -08001899Json::Value SkDrawPosTextHCommand::toJSON(UrlDataManager& urlDataManager) const {
1900 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman65197ff2018-05-29 14:25:39 -04001901 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = make_json_text(fText);
bungeman51190df2016-03-09 07:42:54 -08001902 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fConstY);
1903 Json::Value xpos(Json::arrayValue);
Brian Osman65197ff2018-05-29 14:25:39 -04001904 size_t numXpos = fPaint.textToGlyphs(fText->data(), fText->size(), nullptr);
bungeman51190df2016-03-09 07:42:54 -08001905 for (size_t i = 0; i < numXpos; i++) {
1906 xpos.append(Json::Value(fXpos[i]));
1907 }
1908 result[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = xpos;
brianosmanfad98562016-05-04 11:06:28 -07001909 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
bungeman51190df2016-03-09 07:42:54 -08001910 return result;
1911}
1912
fmalita37283c22016-09-13 10:00:23 -07001913SkDrawTextBlobCommand::SkDrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y,
fmalitab7425172014-08-26 07:56:44 -07001914 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08001915 : INHERITED(kDrawTextBlob_OpType)
fmalita37283c22016-09-13 10:00:23 -07001916 , fBlob(std::move(blob))
fmalitab7425172014-08-26 07:56:44 -07001917 , fXPos(x)
1918 , fYPos(y)
Brian Osman255735e2018-04-06 14:51:42 -04001919 , fPaint(paint) {}
fmalitab7425172014-08-26 07:56:44 -07001920
fmalita8c89c522014-11-08 16:18:56 -08001921void SkDrawTextBlobCommand::execute(SkCanvas* canvas) const {
fmalitab7425172014-08-26 07:56:44 -07001922 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
1923}
1924
fmalita55773872014-08-29 15:08:20 -07001925bool SkDrawTextBlobCommand::render(SkCanvas* canvas) const {
1926 canvas->clear(SK_ColorWHITE);
1927 canvas->save();
1928
1929 SkRect bounds = fBlob->bounds().makeOffset(fXPos, fYPos);
1930 xlate_and_scale_to_bounds(canvas, bounds);
1931
fmalita37283c22016-09-13 10:00:23 -07001932 canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
fmalita55773872014-08-29 15:08:20 -07001933
1934 canvas->restore();
1935
1936 return true;
1937}
1938
ethannicholasf62a8b72016-02-11 10:35:21 -08001939Json::Value SkDrawTextBlobCommand::toJSON(UrlDataManager& urlDataManager) const {
1940 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08001941 Json::Value runs(Json::arrayValue);
1942 SkTextBlobRunIterator iter(fBlob.get());
1943 while (!iter.done()) {
1944 Json::Value run(Json::objectValue);
1945 Json::Value jsonPositions(Json::arrayValue);
1946 Json::Value jsonGlyphs(Json::arrayValue);
1947 const SkScalar* iterPositions = iter.pos();
1948 const uint16_t* iterGlyphs = iter.glyphs();
1949 for (uint32_t i = 0; i < iter.glyphCount(); i++) {
1950 switch (iter.positioning()) {
1951 case SkTextBlob::kFull_Positioning:
brianosmanfad98562016-05-04 11:06:28 -07001952 jsonPositions.append(MakeJsonPoint(iterPositions[i * 2],
1953 iterPositions[i * 2 + 1]));
ethannicholas50a8dd02016-02-10 05:40:46 -08001954 break;
1955 case SkTextBlob::kHorizontal_Positioning:
1956 jsonPositions.append(Json::Value(iterPositions[i]));
1957 break;
1958 case SkTextBlob::kDefault_Positioning:
1959 break;
1960 }
1961 jsonGlyphs.append(Json::Value(iterGlyphs[i]));
1962 }
1963 if (iter.positioning() != SkTextBlob::kDefault_Positioning) {
1964 run[SKDEBUGCANVAS_ATTRIBUTE_POSITIONS] = jsonPositions;
1965 }
1966 run[SKDEBUGCANVAS_ATTRIBUTE_GLYPHS] = jsonGlyphs;
1967 SkPaint fontPaint;
1968 iter.applyFontToPaint(&fontPaint);
brianosmanfad98562016-05-04 11:06:28 -07001969 run[SKDEBUGCANVAS_ATTRIBUTE_FONT] = MakeJsonPaint(fontPaint, urlDataManager);
1970 run[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(iter.offset());
ethannicholas50a8dd02016-02-10 05:40:46 -08001971 runs.append(run);
1972 iter.next();
1973 }
reed6d2c3e72016-07-07 14:10:14 -07001974 SkRect bounds = fBlob->bounds();
ethannicholas50a8dd02016-02-10 05:40:46 -08001975 result[SKDEBUGCANVAS_ATTRIBUTE_RUNS] = runs;
1976 result[SKDEBUGCANVAS_ATTRIBUTE_X] = Json::Value(fXPos);
1977 result[SKDEBUGCANVAS_ATTRIBUTE_Y] = Json::Value(fYPos);
reed6d2c3e72016-07-07 14:10:14 -07001978 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(bounds);
brianosmanfad98562016-05-04 11:06:28 -07001979 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed6d2c3e72016-07-07 14:10:14 -07001980
1981 SkString desc;
1982 // make the bounds local by applying the x,y
1983 bounds.offset(fXPos, fYPos);
1984 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, bounds)->c_str());
1985
ethannicholas50a8dd02016-02-10 05:40:46 -08001986 return result;
1987}
1988
robertphillips9bafc302015-02-13 11:13:00 -08001989SkDrawPatchCommand::SkDrawPatchCommand(const SkPoint cubics[12], const SkColor colors[4],
Mike Reed7d954ad2016-10-28 15:42:34 -04001990 const SkPoint texCoords[4], SkBlendMode bmode,
robertphillips9bafc302015-02-13 11:13:00 -08001991 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04001992 : INHERITED(kDrawPatch_OpType)
1993 , fBlendMode(bmode)
1994{
robertphillips9bafc302015-02-13 11:13:00 -08001995 memcpy(fCubics, cubics, sizeof(fCubics));
ethannicholas1446a9a2016-02-10 14:05:02 -08001996 if (colors != nullptr) {
1997 memcpy(fColors, colors, sizeof(fColors));
1998 fColorsPtr = fColors;
1999 } else {
2000 fColorsPtr = nullptr;
2001 }
2002 if (texCoords != nullptr) {
2003 memcpy(fTexCoords, texCoords, sizeof(fTexCoords));
2004 fTexCoordsPtr = fTexCoords;
2005 } else {
2006 fTexCoordsPtr = nullptr;
2007 }
robertphillips9bafc302015-02-13 11:13:00 -08002008 fPaint = paint;
robertphillips9bafc302015-02-13 11:13:00 -08002009}
2010
2011void SkDrawPatchCommand::execute(SkCanvas* canvas) const {
Mike Reed7d954ad2016-10-28 15:42:34 -04002012 canvas->drawPatch(fCubics, fColorsPtr, fTexCoordsPtr, fBlendMode, fPaint);
ethannicholas1446a9a2016-02-10 14:05:02 -08002013}
2014
ethannicholasf62a8b72016-02-11 10:35:21 -08002015Json::Value SkDrawPatchCommand::toJSON(UrlDataManager& urlDataManager) const {
2016 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas1446a9a2016-02-10 14:05:02 -08002017 Json::Value cubics = Json::Value(Json::arrayValue);
2018 for (int i = 0; i < 12; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002019 cubics.append(MakeJsonPoint(fCubics[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08002020 }
2021 result[SKDEBUGCANVAS_ATTRIBUTE_CUBICS] = cubics;
2022 if (fColorsPtr != nullptr) {
2023 Json::Value colors = Json::Value(Json::arrayValue);
2024 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002025 colors.append(MakeJsonColor(fColorsPtr[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08002026 }
2027 result[SKDEBUGCANVAS_ATTRIBUTE_COLORS] = colors;
2028 }
2029 if (fTexCoordsPtr != nullptr) {
2030 Json::Value texCoords = Json::Value(Json::arrayValue);
2031 for (int i = 0; i < 4; i++) {
brianosmanfad98562016-05-04 11:06:28 -07002032 texCoords.append(MakeJsonPoint(fTexCoords[i]));
ethannicholas1446a9a2016-02-10 14:05:02 -08002033 }
2034 result[SKDEBUGCANVAS_ATTRIBUTE_TEXTURECOORDS] = texCoords;
2035 }
Mike Reed7d954ad2016-10-28 15:42:34 -04002036 // fBlendMode
ethannicholas1446a9a2016-02-10 14:05:02 -08002037 return result;
2038}
2039
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002040SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002041 : INHERITED(kDrawRect_OpType) {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002042 fRect = rect;
2043 fPaint = paint;
chudy@google.com902ebe52012-06-29 14:21:22 +00002044}
2045
fmalita8c89c522014-11-08 16:18:56 -08002046void SkDrawRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.com91217d02013-03-17 18:33:46 +00002047 canvas->drawRect(fRect, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002048}
2049
ethannicholasf62a8b72016-02-11 10:35:21 -08002050Json::Value SkDrawRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2051 Json::Value result = INHERITED::toJSON(urlDataManager);
brianosmanfad98562016-05-04 11:06:28 -07002052 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonRect(fRect);
2053 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
reed67f62fa2016-06-29 11:36:34 -07002054
2055 SkString desc;
2056 result[SKDEBUGCANVAS_ATTRIBUTE_SHORTDESC] = Json::Value(str_append(&desc, fRect)->c_str());
2057
ethannicholas50a8dd02016-02-10 05:40:46 -08002058 return result;
2059}
2060
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002061SkDrawRRectCommand::SkDrawRRectCommand(const SkRRect& rrect, const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002062 : INHERITED(kDrawRRect_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002063 fRRect = rrect;
2064 fPaint = paint;
robertphillips@google.com67baba42013-01-02 20:20:31 +00002065}
2066
fmalita8c89c522014-11-08 16:18:56 -08002067void SkDrawRRectCommand::execute(SkCanvas* canvas) const {
robertphillips@google.comfebc0ec2013-03-11 22:53:11 +00002068 canvas->drawRRect(fRRect, fPaint);
robertphillips@google.com67baba42013-01-02 20:20:31 +00002069}
2070
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002071bool SkDrawRRectCommand::render(SkCanvas* canvas) const {
robertphillips@google.com6ede1fe2013-06-06 23:59:28 +00002072 render_rrect(canvas, fRRect);
2073 return true;
2074}
2075
ethannicholasf62a8b72016-02-11 10:35:21 -08002076Json::Value SkDrawRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2077 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002078 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = make_json_rrect(fRRect);
brianosmanfad98562016-05-04 11:06:28 -07002079 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002080 return result;
2081}
2082
skia.committer@gmail.com90667ba2014-02-25 03:05:18 +00002083SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer,
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002084 const SkRRect& inner,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002085 const SkPaint& paint)
robertphillips9bafc302015-02-13 11:13:00 -08002086 : INHERITED(kDrawDRRect_OpType) {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002087 fOuter = outer;
2088 fInner = inner;
2089 fPaint = paint;
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002090}
2091
fmalita8c89c522014-11-08 16:18:56 -08002092void SkDrawDRRectCommand::execute(SkCanvas* canvas) const {
commit-bot@chromium.org3d305202014-02-24 17:28:55 +00002093 canvas->drawDRRect(fOuter, fInner, fPaint);
2094}
2095
2096bool SkDrawDRRectCommand::render(SkCanvas* canvas) const {
2097 render_drrect(canvas, fOuter, fInner);
2098 return true;
2099}
2100
ethannicholasf62a8b72016-02-11 10:35:21 -08002101Json::Value SkDrawDRRectCommand::toJSON(UrlDataManager& urlDataManager) const {
2102 Json::Value result = INHERITED::toJSON(urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002103 result[SKDEBUGCANVAS_ATTRIBUTE_OUTER] = make_json_rrect(fOuter);
2104 result[SKDEBUGCANVAS_ATTRIBUTE_INNER] = make_json_rrect(fInner);
brianosmanfad98562016-05-04 11:06:28 -07002105 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002106 return result;
2107}
2108
Derek Sollenberger6aab2ab2018-04-12 12:45:58 -04002109SkDrawShadowCommand::SkDrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec)
2110 : INHERITED(kDrawShadow_OpType) {
2111 fPath = path;
2112 fShadowRec = rec;
2113}
2114
2115void SkDrawShadowCommand::execute(SkCanvas* canvas) const {
2116 canvas->private_draw_shadow_rec(fPath, fShadowRec);
2117}
2118
2119bool SkDrawShadowCommand::render(SkCanvas* canvas) const {
2120 render_shadow(canvas, fPath, fShadowRec);
2121 return true;
2122}
2123
2124Json::Value SkDrawShadowCommand::toJSON(UrlDataManager& urlDataManager) const {
2125 Json::Value result = INHERITED::toJSON(urlDataManager);
2126 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2127
2128 bool geometricOnly = SkToBool(fShadowRec.fFlags & SkShadowFlags::kGeometricOnly_ShadowFlag);
2129 bool transparentOccluder =
2130 SkToBool(fShadowRec.fFlags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
2131
2132 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
2133 result[SKDEBUGCANVAS_ATTRIBUTE_ZPLANE] = MakeJsonPoint3(fShadowRec.fZPlaneParams);
2134 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTPOSITION] = MakeJsonPoint3(fShadowRec.fLightPos);
2135 result[SKDEBUGCANVAS_ATTRIBUTE_LIGHTRADIUS] = MakeJsonScalar(fShadowRec.fLightRadius);
2136 result[SKDEBUGCANVAS_ATTRIBUTE_AMBIENTCOLOR] = MakeJsonColor(fShadowRec.fAmbientColor);
2137 result[SKDEBUGCANVAS_ATTRIBUTE_SPOTCOLOR] = MakeJsonColor(fShadowRec.fSpotColor);
2138 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_TRANSPARENT_OCC, transparentOccluder, false);
2139 store_bool(&result, SKDEBUGCANVAS_SHADOWFLAG_GEOMETRIC_ONLY, geometricOnly, false);
2140 return result;
2141}
2142
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002143SkDrawTextCommand::SkDrawTextCommand(const void* text, size_t byteLength, SkScalar x, SkScalar y,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002144 const SkPaint& paint)
Brian Osman65197ff2018-05-29 14:25:39 -04002145 : INHERITED(kDrawText_OpType)
2146 , fText(SkData::MakeWithCopy(text, byteLength))
2147 , fX(x)
2148 , fY(y)
2149 , fPaint(paint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00002150
fmalita8c89c522014-11-08 16:18:56 -08002151void SkDrawTextCommand::execute(SkCanvas* canvas) const {
Brian Osman65197ff2018-05-29 14:25:39 -04002152 canvas->drawText(fText->data(), fText->size(), fX, fY, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002153}
2154
ethannicholasf62a8b72016-02-11 10:35:21 -08002155Json::Value SkDrawTextCommand::toJSON(UrlDataManager& urlDataManager) const {
2156 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman65197ff2018-05-29 14:25:39 -04002157 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = make_json_text(fText);
ethannicholas50a8dd02016-02-10 05:40:46 -08002158 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07002159 result[SKDEBUGCANVAS_ATTRIBUTE_COORDS] = MakeJsonPoint(fX, fY);
2160 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002161 return result;
2162}
2163
reed45561a02016-07-07 12:47:17 -07002164///////////////////////////////////////////////////////////////////////////////////////////////////
2165
commit-bot@chromium.org7a115912013-06-18 20:20:55 +00002166SkDrawTextOnPathCommand::SkDrawTextOnPathCommand(const void* text, size_t byteLength,
2167 const SkPath& path, const SkMatrix* matrix,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002168 const SkPaint& paint)
Brian Osman8363be12018-05-29 13:38:07 -04002169 : INHERITED(kDrawTextOnPath_OpType)
Brian Osman65197ff2018-05-29 14:25:39 -04002170 , fText(SkData::MakeWithCopy(text, byteLength))
2171 , fPath(path)
2172 , fMatrix(matrix)
2173 , fPaint(paint) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00002174
fmalita8c89c522014-11-08 16:18:56 -08002175void SkDrawTextOnPathCommand::execute(SkCanvas* canvas) const {
Brian Osman65197ff2018-05-29 14:25:39 -04002176 canvas->drawTextOnPath(fText->data(), fText->size(), fPath, fMatrix.getMaybeNull(), fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002177}
2178
ethannicholasf62a8b72016-02-11 10:35:21 -08002179Json::Value SkDrawTextOnPathCommand::toJSON(UrlDataManager& urlDataManager) const {
2180 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman65197ff2018-05-29 14:25:39 -04002181 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = make_json_text(fText);
ethannicholas50a8dd02016-02-10 05:40:46 -08002182 Json::Value coords(Json::arrayValue);
brianosmanfad98562016-05-04 11:06:28 -07002183 result[SKDEBUGCANVAS_ATTRIBUTE_PATH] = MakeJsonPath(fPath);
Brian Osman8363be12018-05-29 13:38:07 -04002184 if (fMatrix.isValid()) {
2185 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(*fMatrix.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002186 }
brianosmanfad98562016-05-04 11:06:28 -07002187 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002188 return result;
2189}
2190
reed45561a02016-07-07 12:47:17 -07002191///////////////////////////////////////////////////////////////////////////////////////////////////
2192
2193SkDrawTextRSXformCommand::SkDrawTextRSXformCommand(const void* text, size_t byteLength,
2194 const SkRSXform xform[], const SkRect* cull,
2195 const SkPaint& paint)
reed63f30d92016-07-07 16:32:51 -07002196 : INHERITED(kDrawTextRSXform_OpType)
Brian Osman65197ff2018-05-29 14:25:39 -04002197 , fText(SkData::MakeWithCopy(text, byteLength))
2198 , fXform(xform, paint.countText(text, byteLength))
Brian Osman8363be12018-05-29 13:38:07 -04002199 , fCull(cull)
Brian Osman65197ff2018-05-29 14:25:39 -04002200 , fPaint(paint) {}
reed45561a02016-07-07 12:47:17 -07002201
2202void SkDrawTextRSXformCommand::execute(SkCanvas* canvas) const {
Brian Osman65197ff2018-05-29 14:25:39 -04002203 canvas->drawTextRSXform(fText->data(), fText->size(), fXform.begin(), fCull.getMaybeNull(),
2204 fPaint);
reed45561a02016-07-07 12:47:17 -07002205}
2206
2207Json::Value SkDrawTextRSXformCommand::toJSON(UrlDataManager& urlDataManager) const {
2208 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman65197ff2018-05-29 14:25:39 -04002209 result[SKDEBUGCANVAS_ATTRIBUTE_TEXT] = make_json_text(fText);
reed45561a02016-07-07 12:47:17 -07002210 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(fPaint, urlDataManager);
2211 return result;
2212}
2213
reed45561a02016-07-07 12:47:17 -07002214///////////////////////////////////////////////////////////////////////////////////////////////////
2215
Mike Reedfed9cfd2017-03-17 12:09:04 -04002216SkDrawVerticesCommand::SkDrawVerticesCommand(sk_sp<SkVertices> vertices, SkBlendMode bmode,
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002217 const SkPaint& paint)
Mike Reed7d954ad2016-10-28 15:42:34 -04002218 : INHERITED(kDrawVertices_OpType)
Mike Reedfed9cfd2017-03-17 12:09:04 -04002219 , fVertices(std::move(vertices))
Mike Reed7d954ad2016-10-28 15:42:34 -04002220 , fBlendMode(bmode)
Brian Osman255735e2018-04-06 14:51:42 -04002221 , fPaint(paint) {}
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002222
fmalita8c89c522014-11-08 16:18:56 -08002223void SkDrawVerticesCommand::execute(SkCanvas* canvas) const {
Mike Reedfed9cfd2017-03-17 12:09:04 -04002224 canvas->drawVertices(fVertices, fBlendMode, fPaint);
chudy@google.com902ebe52012-06-29 14:21:22 +00002225}
2226
Brian Osman616f1cb2018-05-29 11:23:35 -04002227///////////////////////////////////////////////////////////////////////////////////////////////////
2228
2229SkDrawAtlasCommand::SkDrawAtlasCommand(const SkImage* image, const SkRSXform xform[],
2230 const SkRect tex[], const SkColor colors[], int count,
2231 SkBlendMode bmode, const SkRect* cull,
2232 const SkPaint* paint)
2233 : INHERITED(kDrawAtlas_OpType)
2234 , fImage(SkRef(image))
2235 , fXform(xform, count)
2236 , fTex(tex, count)
2237 , fColors(colors, colors ? count : 0)
2238 , fBlendMode(bmode)
2239 , fCull(cull)
2240 , fPaint(paint) {}
2241
2242void SkDrawAtlasCommand::execute(SkCanvas* canvas) const {
2243 canvas->drawAtlas(fImage.get(), fXform.begin(), fTex.begin(),
2244 fColors.isEmpty() ? nullptr : fColors.begin(), fXform.count(), fBlendMode,
2245 fCull.getMaybeNull(), fPaint.getMaybeNull());
2246}
2247
2248///////////////////////////////////////////////////////////////////////////////////////////////////
2249
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002250SkRestoreCommand::SkRestoreCommand()
Brian Osman255735e2018-04-06 14:51:42 -04002251 : INHERITED(kRestore_OpType) {}
chudy@google.com902ebe52012-06-29 14:21:22 +00002252
fmalita8c89c522014-11-08 16:18:56 -08002253void SkRestoreCommand::execute(SkCanvas* canvas) const {
chudy@google.com902ebe52012-06-29 14:21:22 +00002254 canvas->restore();
2255}
2256
Florin Malita5f6102d2014-06-30 10:13:28 -04002257SkSaveCommand::SkSaveCommand()
robertphillips9bafc302015-02-13 11:13:00 -08002258 : INHERITED(kSave_OpType) {
chudy@google.com902ebe52012-06-29 14:21:22 +00002259}
2260
fmalita8c89c522014-11-08 16:18:56 -08002261void SkSaveCommand::execute(SkCanvas* canvas) const {
Florin Malita5f6102d2014-06-30 10:13:28 -04002262 canvas->save();
chudy@google.com902ebe52012-06-29 14:21:22 +00002263}
2264
reed4960eee2015-12-18 07:09:18 -08002265SkSaveLayerCommand::SkSaveLayerCommand(const SkCanvas::SaveLayerRec& rec)
Brian Osman8363be12018-05-29 13:38:07 -04002266 : INHERITED(kSaveLayer_OpType)
2267 , fBounds(rec.fBounds)
2268 , fPaint(rec.fPaint)
2269 , fBackdrop(SkSafeRef(rec.fBackdrop))
2270 , fSaveLayerFlags(rec.fSaveLayerFlags) {}
ethannicholas50a8dd02016-02-10 05:40:46 -08002271
fmalita8c89c522014-11-08 16:18:56 -08002272void SkSaveLayerCommand::execute(SkCanvas* canvas) const {
Brian Osman8363be12018-05-29 13:38:07 -04002273 canvas->saveLayer(SkCanvas::SaveLayerRec(fBounds.getMaybeNull(), fPaint.getMaybeNull(),
reed4960eee2015-12-18 07:09:18 -08002274 fSaveLayerFlags));
chudy@google.com902ebe52012-06-29 14:21:22 +00002275}
2276
ethannicholasf62a8b72016-02-11 10:35:21 -08002277Json::Value SkSaveLayerCommand::toJSON(UrlDataManager& urlDataManager) const {
2278 Json::Value result = INHERITED::toJSON(urlDataManager);
Brian Osman8363be12018-05-29 13:38:07 -04002279 if (fBounds.isValid()) {
2280 result[SKDEBUGCANVAS_ATTRIBUTE_BOUNDS] = MakeJsonRect(*fBounds.get());
ethannicholas50a8dd02016-02-10 05:40:46 -08002281 }
Brian Osman8363be12018-05-29 13:38:07 -04002282 if (fPaint.isValid()) {
2283 result[SKDEBUGCANVAS_ATTRIBUTE_PAINT] = MakeJsonPaint(*fPaint.get(), urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002284 }
2285 if (fBackdrop != nullptr) {
2286 Json::Value jsonBackdrop;
Brian Osman8363be12018-05-29 13:38:07 -04002287 flatten(fBackdrop.get(), &jsonBackdrop, urlDataManager);
ethannicholas50a8dd02016-02-10 05:40:46 -08002288 result[SKDEBUGCANVAS_ATTRIBUTE_BACKDROP] = jsonBackdrop;
2289 }
2290 if (fSaveLayerFlags != 0) {
2291 SkDebugf("unsupported: saveLayer flags\n");
2292 SkASSERT(false);
2293 }
2294 return result;
2295}
2296
commit-bot@chromium.org57f74e02014-03-25 23:31:33 +00002297SkSetMatrixCommand::SkSetMatrixCommand(const SkMatrix& matrix)
robertphillips9bafc302015-02-13 11:13:00 -08002298 : INHERITED(kSetMatrix_OpType) {
robertphillips@google.com0df2a9a2013-03-25 11:50:42 +00002299 fMatrix = matrix;
robertphillips70171682014-10-16 14:28:28 -07002300}
2301
fmalita8c89c522014-11-08 16:18:56 -08002302void SkSetMatrixCommand::execute(SkCanvas* canvas) const {
Brian Osman255735e2018-04-06 14:51:42 -04002303 canvas->setMatrix(fMatrix);
chudy@google.com902ebe52012-06-29 14:21:22 +00002304}
2305
ethannicholasf62a8b72016-02-11 10:35:21 -08002306Json::Value SkSetMatrixCommand::toJSON(UrlDataManager& urlDataManager) const {
2307 Json::Value result = INHERITED::toJSON(urlDataManager);
joshualittbd724132016-03-03 11:39:38 -08002308 result[SKDEBUGCANVAS_ATTRIBUTE_MATRIX] = MakeJsonMatrix(fMatrix);
ethannicholas50a8dd02016-02-10 05:40:46 -08002309 return result;
2310}