blob: 4bde9e82301941d97fd300c103a684cb49fe2321 [file] [log] [blame]
Kevin Lubick217056c2018-09-20 17:39:31 -04001// Adds JS functions to augment the CanvasKit interface.
2// For example, if there is a wrapper around the C++ call or logic to allow
3// chaining, it should go here.
Kevin Lubick1a05fce2018-11-20 12:51:16 -05004
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05005// CanvasKit.onRuntimeInitialized is called after the WASM library has loaded.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04006// Anything that modifies an exposed class (e.g. Path) should be set
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05007// after onRuntimeInitialized, otherwise, it can happen outside of that scope.
8CanvasKit.onRuntimeInitialized = function() {
9 // All calls to 'this' need to go in externs.js so closure doesn't minify them away.
Kevin Lubick1a05fce2018-11-20 12:51:16 -050010
Kevin Lubick93f1a382020-06-02 16:15:23 -040011 _scratchColor = CanvasKit.Malloc(Float32Array, 4); // 4 color scalars.
Kevin Lubickb42660f2020-06-03 09:58:27 -040012 _scratchColorPtr = _scratchColor['byteOffset'];
Kevin Lubick6aa38692020-06-01 11:25:47 -040013
14 _scratch4x4Matrix = CanvasKit.Malloc(Float32Array, 16); // 16 matrix scalars.
Kevin Lubickb42660f2020-06-03 09:58:27 -040015 _scratch4x4MatrixPtr = _scratch4x4Matrix['byteOffset'];
Kevin Lubick6aa38692020-06-01 11:25:47 -040016
17 _scratch3x3Matrix = CanvasKit.Malloc(Float32Array, 9); // 9 matrix scalars.
Kevin Lubickb42660f2020-06-03 09:58:27 -040018 _scratch3x3MatrixPtr = _scratch3x3Matrix['byteOffset'];
Kevin Lubickbe728012020-09-03 11:57:12 +000019
20 _scratchRRect = CanvasKit.Malloc(Float32Array, 12); // 4 scalars for rrect, 8 for radii.
21 _scratchRRectPtr = _scratchRRect['byteOffset'];
22
23 _scratchRRect2 = CanvasKit.Malloc(Float32Array, 12); // 4 scalars for rrect, 8 for radii.
24 _scratchRRect2Ptr = _scratchRRect2['byteOffset'];
25
Kevin Lubickf8823b52020-09-03 10:02:10 -040026 _scratchRect = CanvasKit.Malloc(Float32Array, 4);
27 _scratchRectPtr = _scratchRect['byteOffset'];
28
29 _scratchRect2 = CanvasKit.Malloc(Float32Array, 4);
30 _scratchRect2Ptr = _scratchRect2['byteOffset'];
31
32 _scratchIRect = CanvasKit.Malloc(Int32Array, 4);
33 _scratchIRectPtr = _scratchIRect['byteOffset'];
34
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -040035 // Create single copies of all three supported color spaces
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040036 // These are sk_sp<ColorSpace>
37 CanvasKit.ColorSpace.SRGB = CanvasKit.ColorSpace._MakeSRGB();
38 CanvasKit.ColorSpace.DISPLAY_P3 = CanvasKit.ColorSpace._MakeDisplayP3();
39 CanvasKit.ColorSpace.ADOBE_RGB = CanvasKit.ColorSpace._MakeAdobeRGB();
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -040040
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040041 CanvasKit.Path.MakeFromCmds = function(cmds) {
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040042 var ptrLen = loadCmdsTypedArray(cmds);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040043 var path = CanvasKit.Path._MakeFromCmds(ptrLen[0], ptrLen[1]);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040044 CanvasKit._free(ptrLen[0]);
45 return path;
46 };
47
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040048 // The weights array is optional (only used for conics).
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040049 CanvasKit.Path.MakeFromVerbsPointsWeights = function(verbs, pts, weights) {
Kevin Lubickbe728012020-09-03 11:57:12 +000050 var verbsPtr = copy1dArray(verbs, 'HEAPU8');
51 var pointsPtr = copy1dArray(pts, 'HEAPF32');
52 var weightsPtr = copy1dArray(weights, 'HEAPF32');
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040053 var numWeights = (weights && weights.length) || 0;
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040054 var path = CanvasKit.Path._MakeFromVerbsPointsWeights(
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040055 verbsPtr, verbs.length, pointsPtr, pts.length, weightsPtr, numWeights);
56 freeArraysThatAreNotMallocedByUsers(verbsPtr, verbs);
57 freeArraysThatAreNotMallocedByUsers(pointsPtr, pts);
58 freeArraysThatAreNotMallocedByUsers(weightsPtr, weights);
59 return path;
60 };
Kevin Lubickd3729342019-09-12 11:11:25 -040061
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040062 CanvasKit.Path.prototype.addArc = function(oval, startAngle, sweepAngle) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050063 // see arc() for the HTMLCanvas version
64 // note input angles are degrees.
Kevin Lubickf8823b52020-09-03 10:02:10 -040065 var oPtr = copyRectToWasm(oval);
66 this._addArc(oPtr, startAngle, sweepAngle);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050067 return this;
68 };
Kevin Lubick217056c2018-09-20 17:39:31 -040069
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040070 CanvasKit.Path.prototype.addOval = function(oval, isCCW, startIndex) {
Kevin Lubicke384df42019-08-26 15:48:09 -040071 if (startIndex === undefined) {
72 startIndex = 1;
73 }
Kevin Lubickf8823b52020-09-03 10:02:10 -040074 var oPtr = copyRectToWasm(oval);
75 this._addOval(oPtr, !!isCCW, startIndex);
Kevin Lubicke384df42019-08-26 15:48:09 -040076 return this;
77 };
78
Kevin Lubicka2535af2020-10-02 08:01:57 -040079 // TODO(kjlubick) clean up this API - split it apart if necessary
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040080 CanvasKit.Path.prototype.addPath = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050081 // Takes 1, 2, 7, or 10 required args, where the first arg is always the path.
82 // The last arg is optional and chooses between add or extend mode.
83 // The options for the remaining args are:
84 // - an array of 6 or 9 parameters (perspective is optional)
85 // - the 9 parameters of a full matrix or
86 // the 6 non-perspective params of a matrix.
87 var args = Array.prototype.slice.call(arguments);
88 var path = args[0];
89 var extend = false;
Kevin Lubickbe728012020-09-03 11:57:12 +000090 if (typeof args[args.length-1] === 'boolean') {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050091 extend = args.pop();
92 }
93 if (args.length === 1) {
94 // Add path, unchanged. Use identity matrix
95 this._addPath(path, 1, 0, 0,
96 0, 1, 0,
97 0, 0, 1,
98 extend);
99 } else if (args.length === 2) {
100 // User provided the 9 params of a full matrix as an array.
101 var a = args[1];
102 this._addPath(path, a[0], a[1], a[2],
103 a[3], a[4], a[5],
104 a[6] || 0, a[7] || 0, a[8] || 1,
105 extend);
106 } else if (args.length === 7 || args.length === 10) {
107 // User provided the 9 params of a (full) matrix directly.
108 // (or just the 6 non perspective ones)
109 // These are in the same order as what Skia expects.
110 var a = args;
111 this._addPath(path, a[1], a[2], a[3],
112 a[4], a[5], a[6],
113 a[7] || 0, a[8] || 0, a[9] || 1,
114 extend);
115 } else {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400116 Debug('addPath expected to take 1, 2, 7, or 10 required args. Got ' + args.length);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400117 return null;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500118 }
119 return this;
120 };
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400121
Kevin Lubicke7c1a732020-12-04 09:10:39 -0500122 // points is a 1d array of length 2n representing n points where the even indices
123 // will be treated as x coordinates and the odd indices will be treated as y coordinates.
124 // Like other APIs, this accepts a malloced type array or malloc obj.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400125 CanvasKit.Path.prototype.addPoly = function(points, close) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -0500126 var ptr = copy1dArray(points, 'HEAPF32');
127 this._addPoly(ptr, points.length / 2, close);
Kevin Lubickcf118922020-05-28 14:43:38 -0400128 freeArraysThatAreNotMallocedByUsers(ptr, points);
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500129 return this;
130 };
131
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400132 CanvasKit.Path.prototype.addRect = function(rect, isCCW) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400133 var rPtr = copyRectToWasm(rect);
134 this._addRect(rPtr, !!isCCW);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500135 return this;
136 };
Kevin Lubick217056c2018-09-20 17:39:31 -0400137
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400138 CanvasKit.Path.prototype.addRRect = function(rrect, isCCW) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400139 var rPtr = copyRRectToWasm(rrect);
140 this._addRRect(rPtr, !!isCCW);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500141 return this;
142 };
143
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400144 // The weights array is optional (only used for conics).
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400145 CanvasKit.Path.prototype.addVerbsPointsWeights = function(verbs, points, weights) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000146 var verbsPtr = copy1dArray(verbs, 'HEAPU8');
147 var pointsPtr = copy1dArray(points, 'HEAPF32');
148 var weightsPtr = copy1dArray(weights, 'HEAPF32');
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400149 var numWeights = (weights && weights.length) || 0;
150 this._addVerbsPointsWeights(verbsPtr, verbs.length, pointsPtr, points.length,
151 weightsPtr, numWeights);
152 freeArraysThatAreNotMallocedByUsers(verbsPtr, verbs);
153 freeArraysThatAreNotMallocedByUsers(pointsPtr, points);
154 freeArraysThatAreNotMallocedByUsers(weightsPtr, weights);
155 };
156
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400157 CanvasKit.Path.prototype.arc = function(x, y, radius, startAngle, endAngle, ccw) {
158 // emulates the HTMLCanvas behavior. See addArc() for the Path version.
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500159 // Note input angles are radians.
160 var bounds = CanvasKit.LTRBRect(x-radius, y-radius, x+radius, y+radius);
161 var sweep = radiansToDegrees(endAngle - startAngle) - (360 * !!ccw);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400162 var temp = new CanvasKit.Path();
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500163 temp.addArc(bounds, radiansToDegrees(startAngle), sweep);
164 this.addPath(temp, true);
165 temp.delete();
166 return this;
167 };
168
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400169 // Appends arc to Path. Arc added is part of ellipse
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400170 // bounded by oval, from startAngle through sweepAngle. Both startAngle and
171 // sweepAngle are measured in degrees, where zero degrees is aligned with the
172 // positive x-axis, and positive sweeps extends arc clockwise.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400173 CanvasKit.Path.prototype.arcToOval = function(oval, startAngle, sweepAngle, forceMoveTo) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400174 var oPtr = copyRectToWasm(oval);
175 this._arcToOval(oPtr, startAngle, sweepAngle, forceMoveTo);
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400176 return this;
177 };
178
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400179 // Appends arc to Path. Arc is implemented by one or more conics weighted to
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400180 // describe part of oval with radii (rx, ry) rotated by xAxisRotate degrees. Arc
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400181 // curves from last point to (x, y), choosing one of four possible routes:
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400182 // clockwise or counterclockwise, and smaller or larger.
183
184 // Arc sweep is always less than 360 degrees. arcTo() appends line to (x, y) if
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400185 // either radii are zero, or if last point equals (x, y). arcTo() scales radii
186 // (rx, ry) to fit last point and (x, y) if both are greater than zero but
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400187 // too small.
188
189 // arcToRotated() appends up to four conic curves.
190 // arcToRotated() implements the functionality of SVG arc, although SVG sweep-flag value
191 // is opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise,
192 // while kCW_Direction cast to int is zero.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400193 CanvasKit.Path.prototype.arcToRotated = function(rx, ry, xAxisRotate, useSmallArc, isCCW, x, y) {
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400194 this._arcToRotated(rx, ry, xAxisRotate, !!useSmallArc, !!isCCW, x, y);
195 return this;
196 };
197
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400198 // Appends arc to Path, after appending line if needed. Arc is implemented by conic
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400199 // weighted to describe part of circle. Arc is contained by tangent from
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400200 // last Path point to (x1, y1), and tangent from (x1, y1) to (x2, y2). Arc
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400201 // is part of circle sized to radius, positioned so it touches both tangent lines.
202
203 // If last Path Point does not start Arc, arcTo appends connecting Line to Path.
204 // The length of Vector from (x1, y1) to (x2, y2) does not affect Arc.
205
206 // Arc sweep is always less than 180 degrees. If radius is zero, or if
207 // tangents are nearly parallel, arcTo appends Line from last Path Point to (x1, y1).
208
209 // arcToTangent appends at most one Line and one conic.
210 // arcToTangent implements the functionality of PostScript arct and HTML Canvas arcTo.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400211 CanvasKit.Path.prototype.arcToTangent = function(x1, y1, x2, y2, radius) {
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400212 this._arcToTangent(x1, y1, x2, y2, radius);
213 return this;
214 };
215
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400216 CanvasKit.Path.prototype.close = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500217 this._close();
218 return this;
219 };
220
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400221 CanvasKit.Path.prototype.conicTo = function(x1, y1, x2, y2, w) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500222 this._conicTo(x1, y1, x2, y2, w);
223 return this;
224 };
225
Kevin Lubick7d96c5c2020-10-01 10:55:16 -0400226 // Clients can pass in a Float32Array with length 4 to this and the results
227 // will be copied into that array. Otherwise, a new TypedArray will be allocated
228 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400229 CanvasKit.Path.prototype.computeTightBounds = function(optionalOutputArray) {
Kevin Lubick7d96c5c2020-10-01 10:55:16 -0400230 this._computeTightBounds(_scratchRectPtr);
231 var ta = _scratchRect['toTypedArray']();
232 if (optionalOutputArray) {
233 optionalOutputArray.set(ta);
234 return optionalOutputArray;
235 }
236 return ta.slice();
237 };
238
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400239 CanvasKit.Path.prototype.cubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500240 this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
241 return this;
242 };
243
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400244 CanvasKit.Path.prototype.dash = function(on, off, phase) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500245 if (this._dash(on, off, phase)) {
Kevin Lubick217056c2018-09-20 17:39:31 -0400246 return this;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500247 }
248 return null;
249 };
Kevin Lubick217056c2018-09-20 17:39:31 -0400250
Kevin Lubickf8823b52020-09-03 10:02:10 -0400251 // Clients can pass in a Float32Array with length 4 to this and the results
252 // will be copied into that array. Otherwise, a new TypedArray will be allocated
253 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400254 CanvasKit.Path.prototype.getBounds = function(optionalOutputArray) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400255 this._getBounds(_scratchRectPtr);
256 var ta = _scratchRect['toTypedArray']();
257 if (optionalOutputArray) {
258 optionalOutputArray.set(ta);
259 return optionalOutputArray;
260 }
261 return ta.slice();
262 };
263
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400264 CanvasKit.Path.prototype.lineTo = function(x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500265 this._lineTo(x, y);
266 return this;
267 };
Kevin Lubick217056c2018-09-20 17:39:31 -0400268
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400269 CanvasKit.Path.prototype.moveTo = function(x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500270 this._moveTo(x, y);
271 return this;
272 };
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400273
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400274 CanvasKit.Path.prototype.offset = function(dx, dy) {
Kevin Lubicke384df42019-08-26 15:48:09 -0400275 this._transform(1, 0, dx,
276 0, 1, dy,
277 0, 0, 1);
278 return this;
279 };
280
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400281 CanvasKit.Path.prototype.quadTo = function(cpx, cpy, x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500282 this._quadTo(cpx, cpy, x, y);
283 return this;
284 };
285
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400286 CanvasKit.Path.prototype.rArcTo = function(rx, ry, xAxisRotate, useSmallArc, isCCW, dx, dy) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400287 this._rArcTo(rx, ry, xAxisRotate, useSmallArc, isCCW, dx, dy);
288 return this;
289 };
290
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400291 CanvasKit.Path.prototype.rConicTo = function(dx1, dy1, dx2, dy2, w) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400292 this._rConicTo(dx1, dy1, dx2, dy2, w);
293 return this;
294 };
295
296 // These params are all relative
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400297 CanvasKit.Path.prototype.rCubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400298 this._rCubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
299 return this;
300 };
301
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400302 CanvasKit.Path.prototype.rLineTo = function(dx, dy) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400303 this._rLineTo(dx, dy);
304 return this;
305 };
306
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400307 CanvasKit.Path.prototype.rMoveTo = function(dx, dy) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400308 this._rMoveTo(dx, dy);
309 return this;
310 };
311
312 // These params are all relative
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400313 CanvasKit.Path.prototype.rQuadTo = function(cpx, cpy, x, y) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400314 this._rQuadTo(cpx, cpy, x, y);
315 return this;
316 };
317
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400318 CanvasKit.Path.prototype.stroke = function(opts) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500319 // Fill out any missing values with the default values.
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500320 opts = opts || {};
Kevin Lubick6aa38692020-06-01 11:25:47 -0400321 opts['width'] = opts['width'] || 1;
322 opts['miter_limit'] = opts['miter_limit'] || 4;
323 opts['cap'] = opts['cap'] || CanvasKit.StrokeCap.Butt;
324 opts['join'] = opts['join'] || CanvasKit.StrokeJoin.Miter;
325 opts['precision'] = opts['precision'] || 1;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500326 if (this._stroke(opts)) {
327 return this;
328 }
329 return null;
330 };
331
Kevin Lubicka2535af2020-10-02 08:01:57 -0400332 // TODO(kjlubick) Change this to take a 3x3 or 4x4 matrix (optionally malloc'd)
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400333 CanvasKit.Path.prototype.transform = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500334 // Takes 1 or 9 args
335 if (arguments.length === 1) {
336 // argument 1 should be a 6 or 9 element array.
337 var a = arguments[0];
338 this._transform(a[0], a[1], a[2],
339 a[3], a[4], a[5],
340 a[6] || 0, a[7] || 0, a[8] || 1);
341 } else if (arguments.length === 6 || arguments.length === 9) {
342 // these arguments are the 6 or 9 members of the matrix
343 var a = arguments;
344 this._transform(a[0], a[1], a[2],
345 a[3], a[4], a[5],
346 a[6] || 0, a[7] || 0, a[8] || 1);
347 } else {
348 throw 'transform expected to take 1 or 9 arguments. Got ' + arguments.length;
349 }
350 return this;
351 };
352 // isComplement is optional, defaults to false
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400353 CanvasKit.Path.prototype.trim = function(startT, stopT, isComplement) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500354 if (this._trim(startT, stopT, !!isComplement)) {
355 return this;
356 }
357 return null;
358 };
359
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400360 CanvasKit.Image.prototype.encodeToData = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500361 if (!arguments.length) {
362 return this._encodeToData();
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400363 }
Kevin Lubick53965c92018-10-11 08:51:55 -0400364
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500365 if (arguments.length === 2) {
366 var a = arguments;
367 return this._encodeToDataWithFormat(a[0], a[1]);
Alexander Khovansky3e119332018-11-15 02:01:19 +0300368 }
369
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500370 throw 'encodeToData expected to take 0 or 2 arguments. Got ' + arguments.length;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500371 };
Kevin Lubick1ba9c4d2019-02-22 10:04:06 -0500372
Kevin Lubick652d7902020-12-11 14:51:36 -0500373 // makeShaderCubic returns a shader for a given image, allowing it to be used on
374 // a paint as well as other purposes. This shader will be higher quality than
375 // other shader functions. See CubicResampler in SkSamplingOptions.h for more information
376 // on the cubicResampler params.
377 CanvasKit.Image.prototype.makeShaderCubic = function(xTileMode, yTileMode,
378 cubicResamplerB, cubicResamplerC,
379 localMatrix) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400380 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Kevin Lubick652d7902020-12-11 14:51:36 -0500381 return this._makeShaderCubic(xTileMode, yTileMode, cubicResamplerB,
382 cubicResamplerC, localMatrixPtr);
383 };
384
385 // makeShaderCubic returns a shader for a given image, allowing it to be used on
386 // a paint as well as other purposes. This shader will draw more quickly than
387 // other shader functions, but at a lower quality.
388 CanvasKit.Image.prototype.makeShaderOptions = function(xTileMode, yTileMode,
389 filterMode, mipmapMode,
390 localMatrix) {
391 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
392 return this._makeShaderOptions(xTileMode, yTileMode, filterMode, mipmapMode, localMatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500393 };
Kevin Lubicka064c282019-04-04 09:28:53 -0400394
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500395 function readPixels(source, srcX, srcY, imageInfo, destMallocObj, bytesPerRow) {
396 if (!bytesPerRow) {
397 bytesPerRow = 4 * imageInfo['width'];
398 if (imageInfo['colorType'] === CanvasKit.ColorType.RGBA_F16) {
399 bytesPerRow *= 2;
400 }
401 else if (imageInfo['colorType'] === CanvasKit.ColorType.RGBA_F32) {
402 bytesPerRow *= 4;
403 }
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400404 }
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500405 var pBytes = bytesPerRow * imageInfo.height;
Kevin Lubickc4ab0872020-11-03 17:13:09 -0500406 var pPtr;
407 if (destMallocObj) {
408 pPtr = destMallocObj['byteOffset'];
409 } else {
410 pPtr = CanvasKit._malloc(pBytes);
411 }
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400412
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500413 if (!source._readPixels(imageInfo, pPtr, bytesPerRow, srcX, srcY)) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400414 Debug('Could not read pixels with the given inputs');
Kevin Lubickc4ab0872020-11-03 17:13:09 -0500415 if (!destMallocObj) {
416 CanvasKit._free(pPtr);
417 }
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400418 return null;
419 }
420
Kevin Lubickc4ab0872020-11-03 17:13:09 -0500421 // If the user provided us a buffer to copy into, we don't need to allocate a new TypedArray.
422 if (destMallocObj) {
423 return destMallocObj['toTypedArray'](); // Return the typed array wrapper w/o allocating.
424 }
425
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400426 // Put those pixels into a typed array of the right format and then
427 // make a copy with slice() that we can return.
428 var retVal = null;
Kevin Lubickbe728012020-09-03 11:57:12 +0000429 switch (imageInfo['colorType']) {
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400430 case CanvasKit.ColorType.RGBA_8888:
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500431 case CanvasKit.ColorType.RGBA_F16: // there is no half-float JS type, so we return raw bytes.
Bryce Thomas1fa54042020-01-14 13:46:30 -0800432 retVal = new Uint8Array(CanvasKit.HEAPU8.buffer, pPtr, pBytes).slice();
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400433 break;
434 case CanvasKit.ColorType.RGBA_F32:
Bryce Thomas1fa54042020-01-14 13:46:30 -0800435 retVal = new Float32Array(CanvasKit.HEAPU8.buffer, pPtr, pBytes).slice();
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400436 break;
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500437 default:
438 Debug('ColorType not yet supported');
439 return null;
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400440 }
441
442 // Free the allocated pixels in the WASM memory
443 CanvasKit._free(pPtr);
444 return retVal;
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500445 }
446
447 CanvasKit.Image.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj,
448 bytesPerRow) {
449 return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500450 };
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400451
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400452 // Accepts an array of four numbers in the range of 0-1 representing a 4f color
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400453 CanvasKit.Canvas.prototype.clear = function(color4f) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400454 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400455 this._clear(cPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500456 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400457
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400458 CanvasKit.Canvas.prototype.clipRRect = function(rrect, op, antialias) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000459 var rPtr = copyRRectToWasm(rrect);
460 this._clipRRect(rPtr, op, antialias);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500461 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000462
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400463 CanvasKit.Canvas.prototype.clipRect = function(rect, op, antialias) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400464 var rPtr = copyRectToWasm(rect);
465 this._clipRect(rPtr, op, antialias);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500466 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400467
Kevin Lubickc1d08982020-04-06 13:52:15 -0400468 // concat takes a 3x2, a 3x3, or a 4x4 matrix and upscales it (if needed) to 4x4. This is because
469 // under the hood, SkCanvas uses a 4x4 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400470 CanvasKit.Canvas.prototype.concat = function(matr) {
Kevin Lubickc1d08982020-04-06 13:52:15 -0400471 var matrPtr = copy4x4MatrixToWasm(matr);
Kevin Lubick6bffe392020-04-02 15:24:15 -0400472 this._concat(matrPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500473 };
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400474
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400475 CanvasKit.Canvas.prototype.drawArc = function(oval, startAngle, sweepAngle, useCenter, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400476 var oPtr = copyRectToWasm(oval);
477 this._drawArc(oPtr, startAngle, sweepAngle, useCenter, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500478 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400479
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400480 // atlas is an Image, e.g. from CanvasKit.MakeImageFromEncoded
481 // srcRects, dstXforms, and colors should be CanvasKit.RectBuilder, CanvasKit.RSXFormBuilder,
482 // and CanvasKit.ColorBuilder (fastest)
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400483 // Or they can be an array of floats of length 4*number of destinations.
484 // colors are optional and used to tint the drawn images using the optional blend mode
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400485 // Colors may be an ColorBuilder, a Uint32Array of int colors,
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400486 // a Flat Float32Array of float colors or a 2d Array of Float32Array(4) (deprecated)
Kevin Lubick97440de2020-09-29 17:58:21 -0400487 // TODO(kjlubick) remove Builders - no longer needed now that Malloc is a thing.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400488 CanvasKit.Canvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint,
Kevin Lubickee91c072019-03-29 10:39:52 -0400489 /*optional*/ blendMode, colors) {
490 if (!atlas || !paint || !srcRects || !dstXforms) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400491 Debug('Doing nothing since missing a required input');
Kevin Lubickee91c072019-03-29 10:39:52 -0400492 return;
493 }
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400494
495 // builder arguments report the length as the number of rects, but when passed as arrays
496 // their.length attribute is 4x higher because it's the number of total components of all rects.
497 // colors is always going to report the same length, at least until floats colors are supported
498 // by this function.
499 if (srcRects.length !== dstXforms.length) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400500 Debug('Doing nothing since input arrays length mismatches');
Nathaniel Nifonge5d32542020-03-26 09:27:48 -0400501 return;
Kevin Lubickee91c072019-03-29 10:39:52 -0400502 }
503 if (!blendMode) {
504 blendMode = CanvasKit.BlendMode.SrcOver;
505 }
506
507 var srcRectPtr;
508 if (srcRects.build) {
509 srcRectPtr = srcRects.build();
510 } else {
Kevin Lubickbe728012020-09-03 11:57:12 +0000511 srcRectPtr = copy1dArray(srcRects, 'HEAPF32');
Kevin Lubickee91c072019-03-29 10:39:52 -0400512 }
513
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400514 var count = 1;
Kevin Lubickee91c072019-03-29 10:39:52 -0400515 var dstXformPtr;
516 if (dstXforms.build) {
517 dstXformPtr = dstXforms.build();
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400518 count = dstXforms.length;
Kevin Lubickee91c072019-03-29 10:39:52 -0400519 } else {
Kevin Lubickbe728012020-09-03 11:57:12 +0000520 dstXformPtr = copy1dArray(dstXforms, 'HEAPF32');
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400521 count = dstXforms.length / 4;
Kevin Lubickee91c072019-03-29 10:39:52 -0400522 }
523
Kevin Lubick6bffe392020-04-02 15:24:15 -0400524 var colorPtr = nullptr;
Kevin Lubickee91c072019-03-29 10:39:52 -0400525 if (colors) {
526 if (colors.build) {
527 colorPtr = colors.build();
528 } else {
Kevin Lubickbe728012020-09-03 11:57:12 +0000529 colorPtr = copy1dArray(assureIntColors(colors), 'HEAPU32');
Kevin Lubickee91c072019-03-29 10:39:52 -0400530 }
531 }
532
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400533 this._drawAtlas(atlas, dstXformPtr, srcRectPtr, colorPtr, count, blendMode, paint);
Kevin Lubickee91c072019-03-29 10:39:52 -0400534
535 if (srcRectPtr && !srcRects.build) {
Kevin Lubickcf118922020-05-28 14:43:38 -0400536 freeArraysThatAreNotMallocedByUsers(srcRectPtr, srcRects);
Kevin Lubickee91c072019-03-29 10:39:52 -0400537 }
538 if (dstXformPtr && !dstXforms.build) {
Kevin Lubickcf118922020-05-28 14:43:38 -0400539 freeArraysThatAreNotMallocedByUsers(dstXformPtr, dstXforms);
Kevin Lubickee91c072019-03-29 10:39:52 -0400540 }
541 if (colorPtr && !colors.build) {
Kevin Lubickcf118922020-05-28 14:43:38 -0400542 freeArraysThatAreNotMallocedByUsers(colorPtr, colors);
Kevin Lubickee91c072019-03-29 10:39:52 -0400543 }
Kevin Lubick9fe83912020-11-03 17:08:34 -0500544 };
Kevin Lubickee91c072019-03-29 10:39:52 -0400545
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400546 CanvasKit.Canvas.prototype.drawColor = function (color4f, mode) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400547 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400548 if (mode !== undefined) {
549 this._drawColor(cPtr, mode);
550 } else {
551 this._drawColor(cPtr);
552 }
Kevin Lubick9fe83912020-11-03 17:08:34 -0500553 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400554
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400555 CanvasKit.Canvas.prototype.drawColorComponents = function (r, g, b, a, mode) {
Kevin Lubick93f1a382020-06-02 16:15:23 -0400556 var cPtr = copyColorComponentsToWasm(r, g, b, a);
557 if (mode !== undefined) {
558 this._drawColor(cPtr, mode);
559 } else {
560 this._drawColor(cPtr);
561 }
Kevin Lubick9fe83912020-11-03 17:08:34 -0500562 };
Kevin Lubick93f1a382020-06-02 16:15:23 -0400563
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400564 CanvasKit.Canvas.prototype.drawDRRect = function(outer, inner, paint) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000565 var oPtr = copyRRectToWasm(outer, _scratchRRectPtr);
566 var iPtr = copyRRectToWasm(inner, _scratchRRect2Ptr);
567 this._drawDRRect(oPtr, iPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500568 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000569
Kevin Lubick2d633492020-12-17 09:58:32 -0500570 CanvasKit.Canvas.prototype.drawImageNine = function(img, center, dest, filter, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400571 var cPtr = copyIRectToWasm(center);
572 var dPtr = copyRectToWasm(dest);
Kevin Lubick2d633492020-12-17 09:58:32 -0500573 this._drawImageNine(img, cPtr, dPtr, filter, paint || null);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500574 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400575
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400576 CanvasKit.Canvas.prototype.drawImageRect = function(img, src, dest, paint, fastSample) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400577 var sPtr = copyRectToWasm(src, _scratchRectPtr);
578 var dPtr = copyRectToWasm(dest, _scratchRect2Ptr);
579 this._drawImageRect(img, sPtr, dPtr, paint, !!fastSample);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500580 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400581
Kevin Lubick72f40762020-12-16 16:00:55 -0500582 CanvasKit.Canvas.prototype.drawImageRectCubic = function(img, src, dest, B, C, paint) {
583 var sPtr = copyRectToWasm(src, _scratchRectPtr);
584 var dPtr = copyRectToWasm(dest, _scratchRect2Ptr);
585 this._drawImageRectCubic(img, sPtr, dPtr, B, C, paint || null);
586 };
587
588 CanvasKit.Canvas.prototype.drawImageRectOptions = function(img, src, dest, filter, mipmap, paint) {
589 var sPtr = copyRectToWasm(src, _scratchRectPtr);
590 var dPtr = copyRectToWasm(dest, _scratchRect2Ptr);
591 this._drawImageRectOptions(img, sPtr, dPtr, filter, mipmap, paint || null);
592 };
593
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400594 CanvasKit.Canvas.prototype.drawOval = function(oval, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400595 var oPtr = copyRectToWasm(oval);
596 this._drawOval(oPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500597 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400598
Kevin Lubick658cb712020-12-01 14:55:02 -0500599 // points is a 1d array of length 2n representing n points where the even indices
600 // will be treated as x coordinates and the odd indices will be treated as y coordinates.
601 // Like other APIs, this accepts a malloced type array or malloc obj.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400602 CanvasKit.Canvas.prototype.drawPoints = function(mode, points, paint) {
Kevin Lubick658cb712020-12-01 14:55:02 -0500603 var ptr = copy1dArray(points, 'HEAPF32');
604 this._drawPoints(mode, ptr, points.length / 2, paint);
Kevin Lubickcf118922020-05-28 14:43:38 -0400605 freeArraysThatAreNotMallocedByUsers(ptr, points);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500606 };
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500607
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400608 CanvasKit.Canvas.prototype.drawRRect = function(rrect, paint) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000609 var rPtr = copyRRectToWasm(rrect);
610 this._drawRRect(rPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500611 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000612
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400613 CanvasKit.Canvas.prototype.drawRect = function(rect, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400614 var rPtr = copyRectToWasm(rect);
615 this._drawRect(rPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500616 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400617
Kevin Lubickcbaea292021-01-13 14:16:58 -0500618 CanvasKit.Canvas.prototype.drawShadow = function(path, zPlaneParams, lightPos, lightRadius,
619 ambientColor, spotColor, flags) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400620 var ambiPtr = copyColorToWasmNoScratch(ambientColor);
621 var spotPtr = copyColorToWasmNoScratch(spotColor);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400622 this._drawShadow(path, zPlaneParams, lightPos, lightRadius, ambiPtr, spotPtr, flags);
Kevin Lubickcf118922020-05-28 14:43:38 -0400623 freeArraysThatAreNotMallocedByUsers(ambiPtr, ambientColor);
624 freeArraysThatAreNotMallocedByUsers(spotPtr, spotColor);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500625 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400626
Kevin Lubickcbaea292021-01-13 14:16:58 -0500627 CanvasKit.getShadowLocalBounds = function(ctm, path, zPlaneParams, lightPos, lightRadius,
628 flags, optOutputRect) {
629 var ctmPtr = copy3x3MatrixToWasm(ctm);
630 var ok = this._getShadowLocalBounds(ctmPtr, path, zPlaneParams, lightPos, lightRadius,
631 flags, _scratchRectPtr);
632 if (!ok) {
633 return null;
634 }
635 var ta = _scratchRect['toTypedArray']();
636 if (optOutputRect) {
637 optOutputRect.set(ta);
638 return optOutputRect;
639 }
640 return ta.slice();
641 };
642
Kevin Lubickc1d08982020-04-06 13:52:15 -0400643 // getLocalToDevice returns a 4x4 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400644 CanvasKit.Canvas.prototype.getLocalToDevice = function() {
Kevin Lubickc1d08982020-04-06 13:52:15 -0400645 // _getLocalToDevice will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400646 this._getLocalToDevice(_scratch4x4MatrixPtr);
647 return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500648 };
Kevin Lubickc1d08982020-04-06 13:52:15 -0400649
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400650 // findMarkedCTM returns a 4x4 matrix, or null if a matrix was not found at
651 // the provided marker.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400652 CanvasKit.Canvas.prototype.findMarkedCTM = function(marker) {
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400653 // _getLocalToDevice will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400654 var found = this._findMarkedCTM(marker, _scratch4x4MatrixPtr);
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400655 if (!found) {
656 return null;
657 }
Kevin Lubick6aa38692020-06-01 11:25:47 -0400658 return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500659 };
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400660
Kevin Lubickc1d08982020-04-06 13:52:15 -0400661 // getTotalMatrix returns the current matrix as a 3x3 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400662 CanvasKit.Canvas.prototype.getTotalMatrix = function() {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400663 // _getTotalMatrix will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400664 this._getTotalMatrix(_scratch3x3MatrixPtr);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400665 // read them out into an array. TODO(kjlubick): If we change Matrix to be
Kevin Lubick6bffe392020-04-02 15:24:15 -0400666 // typedArrays, then we should return a typed array here too.
667 var rv = new Array(9);
668 for (var i = 0; i < 9; i++) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400669 rv[i] = CanvasKit.HEAPF32[_scratch3x3MatrixPtr/4 + i]; // divide by 4 to "cast" to float.
Kevin Lubick6bffe392020-04-02 15:24:15 -0400670 }
Kevin Lubick6bffe392020-04-02 15:24:15 -0400671 return rv;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500672 };
Kevin Lubick6bffe392020-04-02 15:24:15 -0400673
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500674 CanvasKit.Canvas.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj,
675 bytesPerRow) {
676 return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500677 };
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500678
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400679 CanvasKit.Canvas.prototype.saveLayer = function(paint, boundsRect, backdrop, flags) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400680 // bPtr will be 0 (nullptr) if boundsRect is undefined/null.
681 var bPtr = copyRectToWasm(boundsRect);
682 // These or clauses help emscripten, which does not deal with undefined well.
683 return this._saveLayer(paint || null, bPtr, backdrop || null, flags || 0);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500684 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400685
Kevin Lubickcf118922020-05-28 14:43:38 -0400686 // pixels should be a Uint8Array or a plain JS array.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400687 CanvasKit.Canvas.prototype.writePixels = function(pixels, srcWidth, srcHeight,
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400688 destX, destY, alphaType, colorType, colorSpace) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500689 if (pixels.byteLength % (srcWidth * srcHeight)) {
690 throw 'pixels length must be a multiple of the srcWidth * srcHeight';
691 }
692 var bytesPerPixel = pixels.byteLength / (srcWidth * srcHeight);
693 // supply defaults (which are compatible with HTMLCanvas's putImageData)
694 alphaType = alphaType || CanvasKit.AlphaType.Unpremul;
695 colorType = colorType || CanvasKit.ColorType.RGBA_8888;
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400696 colorSpace = colorSpace || CanvasKit.ColorSpace.SRGB;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500697 var srcRowBytes = bytesPerPixel * srcWidth;
698
Kevin Lubickbe728012020-09-03 11:57:12 +0000699 var pptr = copy1dArray(pixels, 'HEAPU8');
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500700 var ok = this._writePixels({
701 'width': srcWidth,
702 'height': srcHeight,
703 'colorType': colorType,
704 'alphaType': alphaType,
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400705 'colorSpace': colorSpace,
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500706 }, pptr, srcRowBytes, destX, destY);
707
Kevin Lubickcf118922020-05-28 14:43:38 -0400708 freeArraysThatAreNotMallocedByUsers(pptr, pixels);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500709 return ok;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500710 };
Kevin Lubick52b9f372018-12-04 13:57:36 -0500711
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400712 CanvasKit.ColorFilter.MakeBlend = function(color4f, mode) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400713 var cPtr = copyColorToWasm(color4f);
Kevin Lubick33645792021-01-29 08:37:41 -0500714 return CanvasKit.ColorFilter._MakeBlend(cPtr, mode);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500715 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400716
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400717 // colorMatrix is an ColorMatrix (e.g. Float32Array of length 20)
718 CanvasKit.ColorFilter.MakeMatrix = function(colorMatrix) {
Kevin Lubickd3729342019-09-12 11:11:25 -0400719 if (!colorMatrix || colorMatrix.length !== 20) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400720 throw 'invalid color matrix';
Kevin Lubickd3729342019-09-12 11:11:25 -0400721 }
Kevin Lubickbe728012020-09-03 11:57:12 +0000722 var fptr = copy1dArray(colorMatrix, 'HEAPF32');
Kevin Lubickd3729342019-09-12 11:11:25 -0400723 // We know skia memcopies the floats, so we can free our memory after the call returns.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400724 var m = CanvasKit.ColorFilter._makeMatrix(fptr);
Kevin Lubickcf118922020-05-28 14:43:38 -0400725 freeArraysThatAreNotMallocedByUsers(fptr, colorMatrix);
Kevin Lubickd3729342019-09-12 11:11:25 -0400726 return m;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500727 };
Kevin Lubickd3729342019-09-12 11:11:25 -0400728
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400729 CanvasKit.ImageFilter.MakeMatrixTransform = function(matr, filterQuality, input) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400730 var matrPtr = copy3x3MatrixToWasm(matr);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400731 return CanvasKit.ImageFilter._MakeMatrixTransform(matrPtr, filterQuality, input);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500732 };
Kevin Lubick6bffe392020-04-02 15:24:15 -0400733
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400734 CanvasKit.Paint.prototype.getColor = function() {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400735 this._getColor(_scratchColorPtr);
736 return copyColorFromWasm(_scratchColorPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500737 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400738
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400739 CanvasKit.Paint.prototype.setColor = function(color4f, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400740 colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400741 // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400742 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400743 this._setColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500744 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400745
Kevin Lubick93f1a382020-06-02 16:15:23 -0400746 // The color components here are expected to be floating point values (nominally between
747 // 0.0 and 1.0, but with wider color gamuts, the values could exceed this range). To convert
748 // between standard 8 bit colors and floats, just divide by 255 before passing them in.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400749 CanvasKit.Paint.prototype.setColorComponents = function(r, g, b, a, colorSpace) {
Kevin Lubick93f1a382020-06-02 16:15:23 -0400750 colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400751 // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here.
Kevin Lubick93f1a382020-06-02 16:15:23 -0400752 var cPtr = copyColorComponentsToWasm(r, g, b, a);
753 this._setColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500754 };
Kevin Lubick93f1a382020-06-02 16:15:23 -0400755
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400756 CanvasKit.PictureRecorder.prototype.beginRecording = function(bounds) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400757 var bPtr = copyRectToWasm(bounds);
758 return this._beginRecording(bPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500759 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400760
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400761 CanvasKit.Surface.prototype.makeImageSnapshot = function(optionalBoundsRect) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400762 var bPtr = copyIRectToWasm(optionalBoundsRect);
763 return this._makeImageSnapshot(bPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500764 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400765
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400766 CanvasKit.Surface.prototype.requestAnimationFrame = function(callback, dirtyRect) {
Kevin Lubick359a7e32019-03-19 09:34:37 -0400767 if (!this._cached_canvas) {
768 this._cached_canvas = this.getCanvas();
769 }
Elliot Evans1ec3b1a2020-07-23 10:25:58 -0400770 requestAnimationFrame(function() {
Kevin Lubick39026282019-03-28 12:46:40 -0400771 if (this._context !== undefined) {
772 CanvasKit.setCurrentContext(this._context);
773 }
Kevin Lubick359a7e32019-03-19 09:34:37 -0400774
775 callback(this._cached_canvas);
776
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400777 // We do not dispose() of the Surface here, as the client will typically
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800778 // call requestAnimationFrame again from within the supplied callback.
779 // For drawing a single frame, prefer drawOnce().
Bryce Thomas9331ca02020-05-29 16:51:21 -0700780 this.flush(dirtyRect);
Kevin Lubick359a7e32019-03-19 09:34:37 -0400781 }.bind(this));
Kevin Lubick9fe83912020-11-03 17:08:34 -0500782 };
Kevin Lubick359a7e32019-03-19 09:34:37 -0400783
Kevin Lubick52379332020-01-27 10:01:25 -0500784 // drawOnce will dispose of the surface after drawing the frame using the provided
785 // callback.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400786 CanvasKit.Surface.prototype.drawOnce = function(callback, dirtyRect) {
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800787 if (!this._cached_canvas) {
788 this._cached_canvas = this.getCanvas();
789 }
Elliot Evans1ec3b1a2020-07-23 10:25:58 -0400790 requestAnimationFrame(function() {
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800791 if (this._context !== undefined) {
792 CanvasKit.setCurrentContext(this._context);
793 }
794 callback(this._cached_canvas);
795
Bryce Thomas9331ca02020-05-29 16:51:21 -0700796 this.flush(dirtyRect);
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800797 this.dispose();
798 }.bind(this));
Kevin Lubick9fe83912020-11-03 17:08:34 -0500799 };
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800800
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400801 CanvasKit.PathEffect.MakeDash = function(intervals, phase) {
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500802 if (!phase) {
803 phase = 0;
804 }
805 if (!intervals.length || intervals.length % 2 === 1) {
806 throw 'Intervals array must have even length';
807 }
Kevin Lubickbe728012020-09-03 11:57:12 +0000808 var ptr = copy1dArray(intervals, 'HEAPF32');
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400809 var dpe = CanvasKit.PathEffect._MakeDash(ptr, intervals.length, phase);
Kevin Lubickcf118922020-05-28 14:43:38 -0400810 freeArraysThatAreNotMallocedByUsers(ptr, intervals);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500811 return dpe;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500812 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500813
Kevin Lubick421ba882020-10-15 13:07:33 -0400814 CanvasKit.Shader.MakeColor = function(color4f, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400815 colorSpace = colorSpace || null
Kevin Lubick6aa38692020-06-01 11:25:47 -0400816 var cPtr = copyColorToWasm(color4f);
Kevin Lubick421ba882020-10-15 13:07:33 -0400817 return CanvasKit.Shader._MakeColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500818 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400819
Kevin Lubick421ba882020-10-15 13:07:33 -0400820 // TODO(kjlubick) remove deprecated names.
821 CanvasKit.Shader.Blend = CanvasKit.Shader.MakeBlend;
822 CanvasKit.Shader.Color = CanvasKit.Shader.MakeColor;
823 CanvasKit.Shader.Lerp = CanvasKit.Shader.MakeLerp;
824
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400825 CanvasKit.Shader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500826 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400827 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400828 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500829 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400830 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500831
Kevin Lubick421ba882020-10-15 13:07:33 -0400832 var lgs = CanvasKit.Shader._MakeLinearGradient(start, end, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
833 cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500834
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400835 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400836 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500837 return lgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500838 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500839
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400840 CanvasKit.Shader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400841 colorSpace = colorSpace || null
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400842 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400843 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500844 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400845 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500846
Kevin Lubick421ba882020-10-15 13:07:33 -0400847 var rgs = CanvasKit.Shader._MakeRadialGradient(center, radius, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
848 cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500849
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400850 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400851 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500852 return rgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500853 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500854
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400855 CanvasKit.Shader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400856 colorSpace = colorSpace || null
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400857 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400858 var posPtr = copy1dArray(pos, 'HEAPF32');
Dan Field3d44f732020-03-16 09:17:30 -0700859 flags = flags || 0;
860 startAngle = startAngle || 0;
861 endAngle = endAngle || 360;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400862 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Dan Field3d44f732020-03-16 09:17:30 -0700863
Kevin Lubick421ba882020-10-15 13:07:33 -0400864 var sgs = CanvasKit.Shader._MakeSweepGradient(cx, cy, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
865 cPtrInfo.count, mode,
866 startAngle, endAngle, flags,
867 localMatrixPtr, colorSpace);
Dan Field3d44f732020-03-16 09:17:30 -0700868
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400869 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400870 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Dan Field3d44f732020-03-16 09:17:30 -0700871 return sgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500872 };
Dan Field3d44f732020-03-16 09:17:30 -0700873
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400874 CanvasKit.Shader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
Kevin Lubick421ba882020-10-15 13:07:33 -0400875 colors, pos, mode, localMatrix, flags, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400876 colorSpace = colorSpace || null
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400877 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400878 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500879 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400880 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500881
Kevin Lubick421ba882020-10-15 13:07:33 -0400882 var rgs = CanvasKit.Shader._MakeTwoPointConicalGradient(
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400883 start, startRadius, end, endRadius, cPtrInfo.colorPtr, cPtrInfo.colorType,
884 posPtr, cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500885
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400886 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400887 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500888 return rgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500889 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500890
Kevin Lubickf8823b52020-09-03 10:02:10 -0400891 // Clients can pass in a Float32Array with length 4 to this and the results
892 // will be copied into that array. Otherwise, a new TypedArray will be allocated
893 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400894 CanvasKit.Vertices.prototype.bounds = function(optionalOutputArray) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400895 this._bounds(_scratchRectPtr);
896 var ta = _scratchRect['toTypedArray']();
897 if (optionalOutputArray) {
898 optionalOutputArray.set(ta);
899 return optionalOutputArray;
900 }
901 return ta.slice();
Kevin Lubick9fe83912020-11-03 17:08:34 -0500902 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400903
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500904 // Run through the JS files that are added at compile time.
905 if (CanvasKit._extraInitializations) {
906 CanvasKit._extraInitializations.forEach(function(init) {
907 init();
908 });
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500909 }
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500910}; // end CanvasKit.onRuntimeInitialized, that is, anything changing prototypes or dynamic.
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500911
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400912// Accepts an object holding two canvaskit colors.
913// {
Kevin Lubick3d00e3a2020-10-02 14:59:28 -0400914// ambient: [r, g, b, a],
915// spot: [r, g, b, a],
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400916// }
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400917// Returns the same format. Note, if malloced colors are passed in, the memory
918// housing the passed in colors passed in will be overwritten with the computed
919// tonal colors.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400920CanvasKit.computeTonalColors = function(tonalColors) {
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400921 // copy the colors into WASM
Kevin Lubick6aa38692020-06-01 11:25:47 -0400922 var cPtrAmbi = copyColorToWasmNoScratch(tonalColors['ambient']);
923 var cPtrSpot = copyColorToWasmNoScratch(tonalColors['spot']);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400924 // The output of this function will be the same pointers we passed in.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400925 this._computeTonalColors(cPtrAmbi, cPtrSpot);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400926 // Read the results out.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400927 var result = {
928 'ambient': copyColorFromWasm(cPtrAmbi),
929 'spot': copyColorFromWasm(cPtrSpot),
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400930 };
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400931 // If the user passed us malloced colors in here, we don't want to clean them up.
932 freeArraysThatAreNotMallocedByUsers(cPtrAmbi, tonalColors['ambient']);
933 freeArraysThatAreNotMallocedByUsers(cPtrSpot, tonalColors['spot']);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400934 return result;
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400935};
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400936
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500937CanvasKit.LTRBRect = function(l, t, r, b) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400938 return Float32Array.of(l, t, r, b);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400939};
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500940
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500941CanvasKit.XYWHRect = function(x, y, w, h) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400942 return Float32Array.of(x, y, x+w, y+h);
943};
944
945CanvasKit.LTRBiRect = function(l, t, r, b) {
946 return Int32Array.of(l, t, r, b);
947};
948
949CanvasKit.XYWHiRect = function(x, y, w, h) {
950 return Int32Array.of(x, y, x+w, y+h);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400951};
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500952
Kevin Lubickbe728012020-09-03 11:57:12 +0000953// RRectXY returns a TypedArray representing an RRect with the given rect and a radiusX and
954// radiusY for all 4 corners.
Kevin Lubick7d644e12019-09-11 14:22:22 -0400955CanvasKit.RRectXY = function(rect, rx, ry) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000956 return Float32Array.of(
Kevin Lubickf8823b52020-09-03 10:02:10 -0400957 rect[0], rect[1], rect[2], rect[3],
Kevin Lubickbe728012020-09-03 11:57:12 +0000958 rx, ry,
959 rx, ry,
960 rx, ry,
961 rx, ry,
962 );
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400963};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500964
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500965// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer())
Kevin Lubick6b921b72019-09-18 16:18:17 -0400966CanvasKit.MakeAnimatedImageFromEncoded = function(data) {
967 data = new Uint8Array(data);
968
969 var iptr = CanvasKit._malloc(data.byteLength);
970 CanvasKit.HEAPU8.set(data, iptr);
971 var img = CanvasKit._decodeAnimatedImage(iptr, data.byteLength);
972 if (!img) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400973 Debug('Could not decode animated image');
Kevin Lubick6b921b72019-09-18 16:18:17 -0400974 return null;
975 }
976 return img;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500977};
Kevin Lubick6b921b72019-09-18 16:18:17 -0400978
979// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer())
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500980CanvasKit.MakeImageFromEncoded = function(data) {
981 data = new Uint8Array(data);
982
983 var iptr = CanvasKit._malloc(data.byteLength);
984 CanvasKit.HEAPU8.set(data, iptr);
985 var img = CanvasKit._decodeImage(iptr, data.byteLength);
986 if (!img) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400987 Debug('Could not decode image');
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500988 return null;
989 }
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500990 return img;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500991};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500992
Elliot Evans28796192020-06-15 12:53:27 -0600993// A variable to hold a canvasElement which can be reused once created the first time.
994var memoizedCanvas2dElement = null;
995
996// Alternative to CanvasKit.MakeImageFromEncoded. Allows for CanvasKit users to take advantage of
997// browser APIs to decode images instead of using codecs included in the CanvasKit wasm binary.
998// Expects that the canvasImageSource has already loaded/decoded.
999// CanvasImageSource reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource
1000CanvasKit.MakeImageFromCanvasImageSource = function(canvasImageSource) {
1001 var width = canvasImageSource.width;
1002 var height = canvasImageSource.height;
1003
1004 if (!memoizedCanvas2dElement) {
1005 memoizedCanvas2dElement = document.createElement('canvas');
1006 }
1007 memoizedCanvas2dElement.width = width;
1008 memoizedCanvas2dElement.height = height;
1009
1010 var ctx2d = memoizedCanvas2dElement.getContext('2d');
1011 ctx2d.drawImage(canvasImageSource, 0, 0);
1012
1013 var imageData = ctx2d.getImageData(0, 0, width, height);
1014
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001015 return CanvasKit.MakeImage({
1016 'width': width,
1017 'height': height,
1018 'alphaType': CanvasKit.AlphaType.Unpremul,
1019 'colorType': CanvasKit.ColorType.RGBA_8888,
1020 'colorSpace': CanvasKit.ColorSpace.SRGB
1021 }, imageData.data, 4 * width);
Kevin Lubick9fe83912020-11-03 17:08:34 -05001022};
Elliot Evans28796192020-06-15 12:53:27 -06001023
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001024// pixels may be an array but Uint8Array or Uint8ClampedArray is recommended,
1025// with the bytes representing the pixel values.
Kevin Lubickeda0b432019-12-02 08:26:48 -05001026// (e.g. each set of 4 bytes could represent RGBA values for a single pixel).
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001027CanvasKit.MakeImage = function(info, pixels, bytesPerRow) {
1028 var pptr = CanvasKit._malloc(pixels.length);
1029 CanvasKit.HEAPU8.set(pixels, pptr); // We always want to copy the bytes into the WASM heap.
Kevin Lubickeda0b432019-12-02 08:26:48 -05001030 // No need to _free pptr, Image takes it with SkData::MakeFromMalloc
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001031 return CanvasKit._MakeImage(info, pptr, pixels.length, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -05001032};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001033
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001034// Colors may be a Uint32Array of int colors, a Flat Float32Array of float colors
1035// or a 2d Array of Float32Array(4) (deprecated)
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001036// the underlying Skia function accepts only int colors so it is recommended
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001037// to pass an array of int colors to avoid an extra conversion.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001038// ColorBuilder is not accepted.
1039CanvasKit.MakeVertices = function(mode, positions, textureCoordinates, colors,
1040 indices, isVolatile) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001041 // Default isVolatile to true if not set
Kevin Lubickb3574c92019-03-06 08:25:36 -05001042 isVolatile = isVolatile === undefined ? true : isVolatile;
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001043 var idxCount = (indices && indices.length) || 0;
1044
1045 var flags = 0;
1046 // These flags are from SkVertices.h and should be kept in sync with those.
1047 if (textureCoordinates && textureCoordinates.length) {
1048 flags |= (1 << 0);
1049 }
1050 if (colors && colors.length) {
1051 flags |= (1 << 1);
1052 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001053 if (!isVolatile) {
Mike Reed5caf9352020-03-02 14:57:09 -05001054 flags |= (1 << 2);
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001055 }
1056
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001057 var builder = new CanvasKit._VerticesBuilder(mode, positions.length / 2, idxCount, flags);
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001058
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001059 copy1dArray(positions, 'HEAPF32', builder.positions());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001060 if (builder.texCoords()) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001061 copy1dArray(textureCoordinates, 'HEAPF32', builder.texCoords());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001062 }
1063 if (builder.colors()) {
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001064 if (colors.build) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001065 throw('Color builder not accepted by MakeVertices, use array of ints');
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001066 } else {
Kevin Lubickbe728012020-09-03 11:57:12 +00001067 copy1dArray(assureIntColors(colors), 'HEAPU32', builder.colors());
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001068 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001069 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001070 if (builder.indices()) {
Kevin Lubickbe728012020-09-03 11:57:12 +00001071 copy1dArray(indices, 'HEAPU16', builder.indices());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001072 }
Kevin Lubickb3574c92019-03-06 08:25:36 -05001073
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001074 // Create the vertices, which owns the memory that the builder had allocated.
1075 return builder.detach();
Kevin Lubicka4f218d2020-01-14 08:39:09 -05001076};