blob: e6d42a8e2cdb871420f4d74c7851bf839b6a46e9 [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 Lubicked962642021-02-02 08:18:11 -050026 _scratchFourFloatsA = CanvasKit.Malloc(Float32Array, 4);
27 _scratchFourFloatsAPtr = _scratchFourFloatsA['byteOffset'];
Kevin Lubickf8823b52020-09-03 10:02:10 -040028
Kevin Lubicked962642021-02-02 08:18:11 -050029 _scratchFourFloatsB = CanvasKit.Malloc(Float32Array, 4);
30 _scratchFourFloatsBPtr = _scratchFourFloatsB['byteOffset'];
Kevin Lubickf8823b52020-09-03 10:02:10 -040031
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 Lubicked962642021-02-02 08:18:11 -0500230 this._computeTightBounds(_scratchFourFloatsAPtr);
231 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubick7d96c5c2020-10-01 10:55:16 -0400232 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 Lubicked962642021-02-02 08:18:11 -0500255 this._getBounds(_scratchFourFloatsAPtr);
256 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubickf8823b52020-09-03 10:02:10 -0400257 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 Lubicked962642021-02-02 08:18:11 -0500577 copyRectToWasm(src, _scratchFourFloatsAPtr);
578 copyRectToWasm(dest, _scratchFourFloatsBPtr);
579 this._drawImageRect(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, 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) {
Kevin Lubicked962642021-02-02 08:18:11 -0500583 copyRectToWasm(src, _scratchFourFloatsAPtr);
584 copyRectToWasm(dest, _scratchFourFloatsBPtr);
585 this._drawImageRectCubic(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, B, C,
586 paint || null);
Kevin Lubick72f40762020-12-16 16:00:55 -0500587 };
588
589 CanvasKit.Canvas.prototype.drawImageRectOptions = function(img, src, dest, filter, mipmap, paint) {
Kevin Lubicked962642021-02-02 08:18:11 -0500590 copyRectToWasm(src, _scratchFourFloatsAPtr);
591 copyRectToWasm(dest, _scratchFourFloatsBPtr);
592 this._drawImageRectOptions(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, filter, mipmap,
593 paint || null);
Kevin Lubick72f40762020-12-16 16:00:55 -0500594 };
595
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400596 CanvasKit.Canvas.prototype.drawOval = function(oval, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400597 var oPtr = copyRectToWasm(oval);
598 this._drawOval(oPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500599 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400600
Kevin Lubick658cb712020-12-01 14:55:02 -0500601 // points is a 1d array of length 2n representing n points where the even indices
602 // will be treated as x coordinates and the odd indices will be treated as y coordinates.
603 // Like other APIs, this accepts a malloced type array or malloc obj.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400604 CanvasKit.Canvas.prototype.drawPoints = function(mode, points, paint) {
Kevin Lubick658cb712020-12-01 14:55:02 -0500605 var ptr = copy1dArray(points, 'HEAPF32');
606 this._drawPoints(mode, ptr, points.length / 2, paint);
Kevin Lubickcf118922020-05-28 14:43:38 -0400607 freeArraysThatAreNotMallocedByUsers(ptr, points);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500608 };
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500609
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400610 CanvasKit.Canvas.prototype.drawRRect = function(rrect, paint) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000611 var rPtr = copyRRectToWasm(rrect);
612 this._drawRRect(rPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500613 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000614
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400615 CanvasKit.Canvas.prototype.drawRect = function(rect, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400616 var rPtr = copyRectToWasm(rect);
617 this._drawRect(rPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500618 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400619
Kevin Lubickcbaea292021-01-13 14:16:58 -0500620 CanvasKit.Canvas.prototype.drawShadow = function(path, zPlaneParams, lightPos, lightRadius,
621 ambientColor, spotColor, flags) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400622 var ambiPtr = copyColorToWasmNoScratch(ambientColor);
623 var spotPtr = copyColorToWasmNoScratch(spotColor);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400624 this._drawShadow(path, zPlaneParams, lightPos, lightRadius, ambiPtr, spotPtr, flags);
Kevin Lubickcf118922020-05-28 14:43:38 -0400625 freeArraysThatAreNotMallocedByUsers(ambiPtr, ambientColor);
626 freeArraysThatAreNotMallocedByUsers(spotPtr, spotColor);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500627 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400628
Kevin Lubickcbaea292021-01-13 14:16:58 -0500629 CanvasKit.getShadowLocalBounds = function(ctm, path, zPlaneParams, lightPos, lightRadius,
630 flags, optOutputRect) {
631 var ctmPtr = copy3x3MatrixToWasm(ctm);
632 var ok = this._getShadowLocalBounds(ctmPtr, path, zPlaneParams, lightPos, lightRadius,
Kevin Lubicked962642021-02-02 08:18:11 -0500633 flags, _scratchFourFloatsAPtr);
Kevin Lubickcbaea292021-01-13 14:16:58 -0500634 if (!ok) {
635 return null;
636 }
Kevin Lubicked962642021-02-02 08:18:11 -0500637 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubickcbaea292021-01-13 14:16:58 -0500638 if (optOutputRect) {
639 optOutputRect.set(ta);
640 return optOutputRect;
641 }
642 return ta.slice();
643 };
644
Kevin Lubickc1d08982020-04-06 13:52:15 -0400645 // getLocalToDevice returns a 4x4 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400646 CanvasKit.Canvas.prototype.getLocalToDevice = function() {
Kevin Lubickc1d08982020-04-06 13:52:15 -0400647 // _getLocalToDevice will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400648 this._getLocalToDevice(_scratch4x4MatrixPtr);
649 return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500650 };
Kevin Lubickc1d08982020-04-06 13:52:15 -0400651
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400652 // findMarkedCTM returns a 4x4 matrix, or null if a matrix was not found at
653 // the provided marker.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400654 CanvasKit.Canvas.prototype.findMarkedCTM = function(marker) {
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400655 // _getLocalToDevice will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400656 var found = this._findMarkedCTM(marker, _scratch4x4MatrixPtr);
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400657 if (!found) {
658 return null;
659 }
Kevin Lubick6aa38692020-06-01 11:25:47 -0400660 return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500661 };
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400662
Kevin Lubickc1d08982020-04-06 13:52:15 -0400663 // getTotalMatrix returns the current matrix as a 3x3 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400664 CanvasKit.Canvas.prototype.getTotalMatrix = function() {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400665 // _getTotalMatrix will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400666 this._getTotalMatrix(_scratch3x3MatrixPtr);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400667 // read them out into an array. TODO(kjlubick): If we change Matrix to be
Kevin Lubick6bffe392020-04-02 15:24:15 -0400668 // typedArrays, then we should return a typed array here too.
669 var rv = new Array(9);
670 for (var i = 0; i < 9; i++) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400671 rv[i] = CanvasKit.HEAPF32[_scratch3x3MatrixPtr/4 + i]; // divide by 4 to "cast" to float.
Kevin Lubick6bffe392020-04-02 15:24:15 -0400672 }
Kevin Lubick6bffe392020-04-02 15:24:15 -0400673 return rv;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500674 };
Kevin Lubick6bffe392020-04-02 15:24:15 -0400675
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500676 CanvasKit.Canvas.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj,
677 bytesPerRow) {
678 return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500679 };
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500680
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400681 CanvasKit.Canvas.prototype.saveLayer = function(paint, boundsRect, backdrop, flags) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400682 // bPtr will be 0 (nullptr) if boundsRect is undefined/null.
683 var bPtr = copyRectToWasm(boundsRect);
684 // These or clauses help emscripten, which does not deal with undefined well.
685 return this._saveLayer(paint || null, bPtr, backdrop || null, flags || 0);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500686 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400687
Kevin Lubickcf118922020-05-28 14:43:38 -0400688 // pixels should be a Uint8Array or a plain JS array.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400689 CanvasKit.Canvas.prototype.writePixels = function(pixels, srcWidth, srcHeight,
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400690 destX, destY, alphaType, colorType, colorSpace) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500691 if (pixels.byteLength % (srcWidth * srcHeight)) {
692 throw 'pixels length must be a multiple of the srcWidth * srcHeight';
693 }
694 var bytesPerPixel = pixels.byteLength / (srcWidth * srcHeight);
695 // supply defaults (which are compatible with HTMLCanvas's putImageData)
696 alphaType = alphaType || CanvasKit.AlphaType.Unpremul;
697 colorType = colorType || CanvasKit.ColorType.RGBA_8888;
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400698 colorSpace = colorSpace || CanvasKit.ColorSpace.SRGB;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500699 var srcRowBytes = bytesPerPixel * srcWidth;
700
Kevin Lubickbe728012020-09-03 11:57:12 +0000701 var pptr = copy1dArray(pixels, 'HEAPU8');
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500702 var ok = this._writePixels({
703 'width': srcWidth,
704 'height': srcHeight,
705 'colorType': colorType,
706 'alphaType': alphaType,
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400707 'colorSpace': colorSpace,
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500708 }, pptr, srcRowBytes, destX, destY);
709
Kevin Lubickcf118922020-05-28 14:43:38 -0400710 freeArraysThatAreNotMallocedByUsers(pptr, pixels);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500711 return ok;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500712 };
Kevin Lubick52b9f372018-12-04 13:57:36 -0500713
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400714 CanvasKit.ColorFilter.MakeBlend = function(color4f, mode) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400715 var cPtr = copyColorToWasm(color4f);
Kevin Lubick33645792021-01-29 08:37:41 -0500716 return CanvasKit.ColorFilter._MakeBlend(cPtr, mode);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500717 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400718
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400719 // colorMatrix is an ColorMatrix (e.g. Float32Array of length 20)
720 CanvasKit.ColorFilter.MakeMatrix = function(colorMatrix) {
Kevin Lubickd3729342019-09-12 11:11:25 -0400721 if (!colorMatrix || colorMatrix.length !== 20) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400722 throw 'invalid color matrix';
Kevin Lubickd3729342019-09-12 11:11:25 -0400723 }
Kevin Lubickbe728012020-09-03 11:57:12 +0000724 var fptr = copy1dArray(colorMatrix, 'HEAPF32');
Kevin Lubickd3729342019-09-12 11:11:25 -0400725 // We know skia memcopies the floats, so we can free our memory after the call returns.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400726 var m = CanvasKit.ColorFilter._makeMatrix(fptr);
Kevin Lubickcf118922020-05-28 14:43:38 -0400727 freeArraysThatAreNotMallocedByUsers(fptr, colorMatrix);
Kevin Lubickd3729342019-09-12 11:11:25 -0400728 return m;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500729 };
Kevin Lubickd3729342019-09-12 11:11:25 -0400730
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400731 CanvasKit.ImageFilter.MakeMatrixTransform = function(matr, filterQuality, input) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400732 var matrPtr = copy3x3MatrixToWasm(matr);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400733 return CanvasKit.ImageFilter._MakeMatrixTransform(matrPtr, filterQuality, input);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500734 };
Kevin Lubick6bffe392020-04-02 15:24:15 -0400735
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400736 CanvasKit.Paint.prototype.getColor = function() {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400737 this._getColor(_scratchColorPtr);
738 return copyColorFromWasm(_scratchColorPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500739 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400740
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400741 CanvasKit.Paint.prototype.setColor = function(color4f, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400742 colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400743 // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400744 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400745 this._setColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500746 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400747
Kevin Lubick93f1a382020-06-02 16:15:23 -0400748 // The color components here are expected to be floating point values (nominally between
749 // 0.0 and 1.0, but with wider color gamuts, the values could exceed this range). To convert
750 // between standard 8 bit colors and floats, just divide by 255 before passing them in.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400751 CanvasKit.Paint.prototype.setColorComponents = function(r, g, b, a, colorSpace) {
Kevin Lubick93f1a382020-06-02 16:15:23 -0400752 colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400753 // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here.
Kevin Lubick93f1a382020-06-02 16:15:23 -0400754 var cPtr = copyColorComponentsToWasm(r, g, b, a);
755 this._setColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500756 };
Kevin Lubick93f1a382020-06-02 16:15:23 -0400757
Kevin Lubicked962642021-02-02 08:18:11 -0500758 CanvasKit.Path.prototype.getPoint = function(idx, optionalOutput) {
759 // This will copy 2 floats into a space for 4 floats
760 this._getPoint(idx, _scratchFourFloatsAPtr);
761 var ta = _scratchFourFloatsA['toTypedArray']();
762 if (optionalOutput) {
763 // We cannot call optionalOutput.set() because it is an error to call .set() with
764 // a source bigger than the destination.
765 optionalOutput[0] = ta[0];
766 optionalOutput[1] = ta[1];
767 return optionalOutput;
768 }
769 // Be sure to return a copy of just the first 2 values.
770 return ta.slice(0, 2);
771 };
772
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400773 CanvasKit.PictureRecorder.prototype.beginRecording = function(bounds) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400774 var bPtr = copyRectToWasm(bounds);
775 return this._beginRecording(bPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500776 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400777
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400778 CanvasKit.Surface.prototype.makeImageSnapshot = function(optionalBoundsRect) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400779 var bPtr = copyIRectToWasm(optionalBoundsRect);
780 return this._makeImageSnapshot(bPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500781 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400782
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400783 CanvasKit.Surface.prototype.requestAnimationFrame = function(callback, dirtyRect) {
Kevin Lubick359a7e32019-03-19 09:34:37 -0400784 if (!this._cached_canvas) {
785 this._cached_canvas = this.getCanvas();
786 }
Elliot Evans1ec3b1a2020-07-23 10:25:58 -0400787 requestAnimationFrame(function() {
Kevin Lubick39026282019-03-28 12:46:40 -0400788 if (this._context !== undefined) {
789 CanvasKit.setCurrentContext(this._context);
790 }
Kevin Lubick359a7e32019-03-19 09:34:37 -0400791
792 callback(this._cached_canvas);
793
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400794 // We do not dispose() of the Surface here, as the client will typically
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800795 // call requestAnimationFrame again from within the supplied callback.
796 // For drawing a single frame, prefer drawOnce().
Bryce Thomas9331ca02020-05-29 16:51:21 -0700797 this.flush(dirtyRect);
Kevin Lubick359a7e32019-03-19 09:34:37 -0400798 }.bind(this));
Kevin Lubick9fe83912020-11-03 17:08:34 -0500799 };
Kevin Lubick359a7e32019-03-19 09:34:37 -0400800
Kevin Lubick52379332020-01-27 10:01:25 -0500801 // drawOnce will dispose of the surface after drawing the frame using the provided
802 // callback.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400803 CanvasKit.Surface.prototype.drawOnce = function(callback, dirtyRect) {
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800804 if (!this._cached_canvas) {
805 this._cached_canvas = this.getCanvas();
806 }
Elliot Evans1ec3b1a2020-07-23 10:25:58 -0400807 requestAnimationFrame(function() {
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800808 if (this._context !== undefined) {
809 CanvasKit.setCurrentContext(this._context);
810 }
811 callback(this._cached_canvas);
812
Bryce Thomas9331ca02020-05-29 16:51:21 -0700813 this.flush(dirtyRect);
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800814 this.dispose();
815 }.bind(this));
Kevin Lubick9fe83912020-11-03 17:08:34 -0500816 };
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800817
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400818 CanvasKit.PathEffect.MakeDash = function(intervals, phase) {
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500819 if (!phase) {
820 phase = 0;
821 }
822 if (!intervals.length || intervals.length % 2 === 1) {
823 throw 'Intervals array must have even length';
824 }
Kevin Lubickbe728012020-09-03 11:57:12 +0000825 var ptr = copy1dArray(intervals, 'HEAPF32');
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400826 var dpe = CanvasKit.PathEffect._MakeDash(ptr, intervals.length, phase);
Kevin Lubickcf118922020-05-28 14:43:38 -0400827 freeArraysThatAreNotMallocedByUsers(ptr, intervals);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500828 return dpe;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500829 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500830
Kevin Lubick421ba882020-10-15 13:07:33 -0400831 CanvasKit.Shader.MakeColor = function(color4f, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500832 colorSpace = colorSpace || null;
Kevin Lubick6aa38692020-06-01 11:25:47 -0400833 var cPtr = copyColorToWasm(color4f);
Kevin Lubick421ba882020-10-15 13:07:33 -0400834 return CanvasKit.Shader._MakeColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500835 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400836
Kevin Lubick421ba882020-10-15 13:07:33 -0400837 // TODO(kjlubick) remove deprecated names.
838 CanvasKit.Shader.Blend = CanvasKit.Shader.MakeBlend;
839 CanvasKit.Shader.Color = CanvasKit.Shader.MakeColor;
840 CanvasKit.Shader.Lerp = CanvasKit.Shader.MakeLerp;
841
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400842 CanvasKit.Shader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500843 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400844 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400845 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500846 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400847 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500848
Kevin Lubicked962642021-02-02 08:18:11 -0500849 // Copy start and end to _scratchFourFloatsAPtr.
850 var startEndPts = _scratchFourFloatsA['toTypedArray']();
851 startEndPts.set(start);
852 startEndPts.set(end, 2);
853
854 var lgs = CanvasKit.Shader._MakeLinearGradient(_scratchFourFloatsAPtr, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
Kevin Lubick421ba882020-10-15 13:07:33 -0400855 cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500856
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400857 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400858 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500859 return lgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500860 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500861
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400862 CanvasKit.Shader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500863 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400864 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400865 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500866 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400867 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500868
Kevin Lubicked962642021-02-02 08:18:11 -0500869 var rgs = CanvasKit.Shader._MakeRadialGradient(center[0], center[1], radius, cPtrInfo.colorPtr,
870 cPtrInfo.colorType, posPtr, cPtrInfo.count, mode,
871 flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500872
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400873 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400874 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500875 return rgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500876 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500877
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400878 CanvasKit.Shader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500879 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400880 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400881 var posPtr = copy1dArray(pos, 'HEAPF32');
Dan Field3d44f732020-03-16 09:17:30 -0700882 flags = flags || 0;
883 startAngle = startAngle || 0;
884 endAngle = endAngle || 360;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400885 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Dan Field3d44f732020-03-16 09:17:30 -0700886
Kevin Lubick421ba882020-10-15 13:07:33 -0400887 var sgs = CanvasKit.Shader._MakeSweepGradient(cx, cy, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
888 cPtrInfo.count, mode,
889 startAngle, endAngle, flags,
890 localMatrixPtr, colorSpace);
Dan Field3d44f732020-03-16 09:17:30 -0700891
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400892 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400893 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Dan Field3d44f732020-03-16 09:17:30 -0700894 return sgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500895 };
Dan Field3d44f732020-03-16 09:17:30 -0700896
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400897 CanvasKit.Shader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
Kevin Lubick421ba882020-10-15 13:07:33 -0400898 colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500899 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400900 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400901 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500902 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400903 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500904
Kevin Lubicked962642021-02-02 08:18:11 -0500905 // Copy start and end to _scratchFourFloatsAPtr.
906 var startEndPts = _scratchFourFloatsA['toTypedArray']();
907 startEndPts.set(start);
908 startEndPts.set(end, 2);
909
910 var rgs = CanvasKit.Shader._MakeTwoPointConicalGradient(_scratchFourFloatsAPtr,
911 startRadius, endRadius, cPtrInfo.colorPtr, cPtrInfo.colorType,
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400912 posPtr, cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500913
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400914 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400915 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500916 return rgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500917 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500918
Kevin Lubickf8823b52020-09-03 10:02:10 -0400919 // Clients can pass in a Float32Array with length 4 to this and the results
920 // will be copied into that array. Otherwise, a new TypedArray will be allocated
921 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400922 CanvasKit.Vertices.prototype.bounds = function(optionalOutputArray) {
Kevin Lubicked962642021-02-02 08:18:11 -0500923 this._bounds(_scratchFourFloatsAPtr);
924 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubickf8823b52020-09-03 10:02:10 -0400925 if (optionalOutputArray) {
926 optionalOutputArray.set(ta);
927 return optionalOutputArray;
928 }
929 return ta.slice();
Kevin Lubick9fe83912020-11-03 17:08:34 -0500930 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400931
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500932 // Run through the JS files that are added at compile time.
933 if (CanvasKit._extraInitializations) {
934 CanvasKit._extraInitializations.forEach(function(init) {
935 init();
936 });
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500937 }
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500938}; // end CanvasKit.onRuntimeInitialized, that is, anything changing prototypes or dynamic.
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500939
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400940// Accepts an object holding two canvaskit colors.
941// {
Kevin Lubick3d00e3a2020-10-02 14:59:28 -0400942// ambient: [r, g, b, a],
943// spot: [r, g, b, a],
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400944// }
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400945// Returns the same format. Note, if malloced colors are passed in, the memory
946// housing the passed in colors passed in will be overwritten with the computed
947// tonal colors.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400948CanvasKit.computeTonalColors = function(tonalColors) {
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400949 // copy the colors into WASM
Kevin Lubick6aa38692020-06-01 11:25:47 -0400950 var cPtrAmbi = copyColorToWasmNoScratch(tonalColors['ambient']);
951 var cPtrSpot = copyColorToWasmNoScratch(tonalColors['spot']);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400952 // The output of this function will be the same pointers we passed in.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400953 this._computeTonalColors(cPtrAmbi, cPtrSpot);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400954 // Read the results out.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400955 var result = {
956 'ambient': copyColorFromWasm(cPtrAmbi),
957 'spot': copyColorFromWasm(cPtrSpot),
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400958 };
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400959 // If the user passed us malloced colors in here, we don't want to clean them up.
960 freeArraysThatAreNotMallocedByUsers(cPtrAmbi, tonalColors['ambient']);
961 freeArraysThatAreNotMallocedByUsers(cPtrSpot, tonalColors['spot']);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400962 return result;
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400963};
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400964
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500965CanvasKit.LTRBRect = function(l, t, r, b) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400966 return Float32Array.of(l, t, r, b);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400967};
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500968
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500969CanvasKit.XYWHRect = function(x, y, w, h) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400970 return Float32Array.of(x, y, x+w, y+h);
971};
972
973CanvasKit.LTRBiRect = function(l, t, r, b) {
974 return Int32Array.of(l, t, r, b);
975};
976
977CanvasKit.XYWHiRect = function(x, y, w, h) {
978 return Int32Array.of(x, y, x+w, y+h);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400979};
Kevin Lubick1a05fce2018-11-20 12:51:16 -0500980
Kevin Lubickbe728012020-09-03 11:57:12 +0000981// RRectXY returns a TypedArray representing an RRect with the given rect and a radiusX and
982// radiusY for all 4 corners.
Kevin Lubick7d644e12019-09-11 14:22:22 -0400983CanvasKit.RRectXY = function(rect, rx, ry) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000984 return Float32Array.of(
Kevin Lubickf8823b52020-09-03 10:02:10 -0400985 rect[0], rect[1], rect[2], rect[3],
Kevin Lubickbe728012020-09-03 11:57:12 +0000986 rx, ry,
987 rx, ry,
988 rx, ry,
989 rx, ry,
990 );
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400991};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500992
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500993// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer())
Kevin Lubick6b921b72019-09-18 16:18:17 -0400994CanvasKit.MakeAnimatedImageFromEncoded = function(data) {
995 data = new Uint8Array(data);
996
997 var iptr = CanvasKit._malloc(data.byteLength);
998 CanvasKit.HEAPU8.set(data, iptr);
999 var img = CanvasKit._decodeAnimatedImage(iptr, data.byteLength);
1000 if (!img) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001001 Debug('Could not decode animated image');
Kevin Lubick6b921b72019-09-18 16:18:17 -04001002 return null;
1003 }
1004 return img;
Kevin Lubick9fe83912020-11-03 17:08:34 -05001005};
Kevin Lubick6b921b72019-09-18 16:18:17 -04001006
1007// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer())
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001008CanvasKit.MakeImageFromEncoded = function(data) {
1009 data = new Uint8Array(data);
1010
1011 var iptr = CanvasKit._malloc(data.byteLength);
1012 CanvasKit.HEAPU8.set(data, iptr);
1013 var img = CanvasKit._decodeImage(iptr, data.byteLength);
1014 if (!img) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001015 Debug('Could not decode image');
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001016 return null;
1017 }
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001018 return img;
Kevin Lubick9fe83912020-11-03 17:08:34 -05001019};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001020
Elliot Evans28796192020-06-15 12:53:27 -06001021// A variable to hold a canvasElement which can be reused once created the first time.
1022var memoizedCanvas2dElement = null;
1023
1024// Alternative to CanvasKit.MakeImageFromEncoded. Allows for CanvasKit users to take advantage of
1025// browser APIs to decode images instead of using codecs included in the CanvasKit wasm binary.
1026// Expects that the canvasImageSource has already loaded/decoded.
1027// CanvasImageSource reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource
1028CanvasKit.MakeImageFromCanvasImageSource = function(canvasImageSource) {
1029 var width = canvasImageSource.width;
1030 var height = canvasImageSource.height;
1031
1032 if (!memoizedCanvas2dElement) {
1033 memoizedCanvas2dElement = document.createElement('canvas');
1034 }
1035 memoizedCanvas2dElement.width = width;
1036 memoizedCanvas2dElement.height = height;
1037
1038 var ctx2d = memoizedCanvas2dElement.getContext('2d');
1039 ctx2d.drawImage(canvasImageSource, 0, 0);
1040
1041 var imageData = ctx2d.getImageData(0, 0, width, height);
1042
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001043 return CanvasKit.MakeImage({
1044 'width': width,
1045 'height': height,
1046 'alphaType': CanvasKit.AlphaType.Unpremul,
1047 'colorType': CanvasKit.ColorType.RGBA_8888,
1048 'colorSpace': CanvasKit.ColorSpace.SRGB
1049 }, imageData.data, 4 * width);
Kevin Lubick9fe83912020-11-03 17:08:34 -05001050};
Elliot Evans28796192020-06-15 12:53:27 -06001051
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001052// pixels may be an array but Uint8Array or Uint8ClampedArray is recommended,
1053// with the bytes representing the pixel values.
Kevin Lubickeda0b432019-12-02 08:26:48 -05001054// (e.g. each set of 4 bytes could represent RGBA values for a single pixel).
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001055CanvasKit.MakeImage = function(info, pixels, bytesPerRow) {
1056 var pptr = CanvasKit._malloc(pixels.length);
1057 CanvasKit.HEAPU8.set(pixels, pptr); // We always want to copy the bytes into the WASM heap.
Kevin Lubickeda0b432019-12-02 08:26:48 -05001058 // No need to _free pptr, Image takes it with SkData::MakeFromMalloc
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001059 return CanvasKit._MakeImage(info, pptr, pixels.length, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -05001060};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001061
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001062// Colors may be a Uint32Array of int colors, a Flat Float32Array of float colors
1063// or a 2d Array of Float32Array(4) (deprecated)
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001064// the underlying Skia function accepts only int colors so it is recommended
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001065// to pass an array of int colors to avoid an extra conversion.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001066// ColorBuilder is not accepted.
1067CanvasKit.MakeVertices = function(mode, positions, textureCoordinates, colors,
1068 indices, isVolatile) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001069 // Default isVolatile to true if not set
Kevin Lubickb3574c92019-03-06 08:25:36 -05001070 isVolatile = isVolatile === undefined ? true : isVolatile;
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001071 var idxCount = (indices && indices.length) || 0;
1072
1073 var flags = 0;
1074 // These flags are from SkVertices.h and should be kept in sync with those.
1075 if (textureCoordinates && textureCoordinates.length) {
1076 flags |= (1 << 0);
1077 }
1078 if (colors && colors.length) {
1079 flags |= (1 << 1);
1080 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001081 if (!isVolatile) {
Mike Reed5caf9352020-03-02 14:57:09 -05001082 flags |= (1 << 2);
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001083 }
1084
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001085 var builder = new CanvasKit._VerticesBuilder(mode, positions.length / 2, idxCount, flags);
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001086
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001087 copy1dArray(positions, 'HEAPF32', builder.positions());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001088 if (builder.texCoords()) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001089 copy1dArray(textureCoordinates, 'HEAPF32', builder.texCoords());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001090 }
1091 if (builder.colors()) {
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001092 if (colors.build) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001093 throw('Color builder not accepted by MakeVertices, use array of ints');
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001094 } else {
Kevin Lubickbe728012020-09-03 11:57:12 +00001095 copy1dArray(assureIntColors(colors), 'HEAPU32', builder.colors());
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001096 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001097 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001098 if (builder.indices()) {
Kevin Lubickbe728012020-09-03 11:57:12 +00001099 copy1dArray(indices, 'HEAPU16', builder.indices());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001100 }
Kevin Lubickb3574c92019-03-06 08:25:36 -05001101
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001102 // Create the vertices, which owns the memory that the builder had allocated.
1103 return builder.detach();
Kevin Lubicka4f218d2020-01-14 08:39:09 -05001104};