blob: d5f535387d3648d0adede3a01deef2aaa21bd6bf [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
Kevin Lubickf6040ef2021-02-02 08:26:48 -050032 _scratchThreeFloatsA = CanvasKit.Malloc(Float32Array, 3); // 3 floats to represent SkVector3
33 _scratchThreeFloatsAPtr = _scratchThreeFloatsA['byteOffset'];
34
35 _scratchThreeFloatsB = CanvasKit.Malloc(Float32Array, 3); // 3 floats to represent SkVector3
36 _scratchThreeFloatsBPtr = _scratchThreeFloatsB['byteOffset'];
37
Kevin Lubickf8823b52020-09-03 10:02:10 -040038 _scratchIRect = CanvasKit.Malloc(Int32Array, 4);
39 _scratchIRectPtr = _scratchIRect['byteOffset'];
40
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -040041 // Create single copies of all three supported color spaces
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040042 // These are sk_sp<ColorSpace>
43 CanvasKit.ColorSpace.SRGB = CanvasKit.ColorSpace._MakeSRGB();
44 CanvasKit.ColorSpace.DISPLAY_P3 = CanvasKit.ColorSpace._MakeDisplayP3();
45 CanvasKit.ColorSpace.ADOBE_RGB = CanvasKit.ColorSpace._MakeAdobeRGB();
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -040046
Kevin Lubick995f2e62021-04-30 11:12:01 -040047 // Use quotes to tell closure compiler not to minify the names
48 CanvasKit['GlyphRunFlags'] = {
49 'IsWhiteSpace': CanvasKit['_GlyphRunFlags_isWhiteSpace'],
50 };
51
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040052 CanvasKit.Path.MakeFromCmds = function(cmds) {
Kevin Lubick82186e92021-06-02 10:29:11 -040053 var cmdPtr = copy1dArray(cmds, 'HEAPF32');
54 var path = CanvasKit.Path._MakeFromCmds(cmdPtr, cmds.length);
55 freeArraysThatAreNotMallocedByUsers(cmdPtr, cmds);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040056 return path;
57 };
58
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040059 // The weights array is optional (only used for conics).
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040060 CanvasKit.Path.MakeFromVerbsPointsWeights = function(verbs, pts, weights) {
Kevin Lubickbe728012020-09-03 11:57:12 +000061 var verbsPtr = copy1dArray(verbs, 'HEAPU8');
62 var pointsPtr = copy1dArray(pts, 'HEAPF32');
63 var weightsPtr = copy1dArray(weights, 'HEAPF32');
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040064 var numWeights = (weights && weights.length) || 0;
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040065 var path = CanvasKit.Path._MakeFromVerbsPointsWeights(
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -040066 verbsPtr, verbs.length, pointsPtr, pts.length, weightsPtr, numWeights);
67 freeArraysThatAreNotMallocedByUsers(verbsPtr, verbs);
68 freeArraysThatAreNotMallocedByUsers(pointsPtr, pts);
69 freeArraysThatAreNotMallocedByUsers(weightsPtr, weights);
70 return path;
71 };
Kevin Lubickd3729342019-09-12 11:11:25 -040072
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040073 CanvasKit.Path.prototype.addArc = function(oval, startAngle, sweepAngle) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050074 // see arc() for the HTMLCanvas version
75 // note input angles are degrees.
Kevin Lubickf8823b52020-09-03 10:02:10 -040076 var oPtr = copyRectToWasm(oval);
77 this._addArc(oPtr, startAngle, sweepAngle);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050078 return this;
79 };
Kevin Lubick217056c2018-09-20 17:39:31 -040080
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040081 CanvasKit.Path.prototype.addOval = function(oval, isCCW, startIndex) {
Kevin Lubicke384df42019-08-26 15:48:09 -040082 if (startIndex === undefined) {
83 startIndex = 1;
84 }
Kevin Lubickf8823b52020-09-03 10:02:10 -040085 var oPtr = copyRectToWasm(oval);
86 this._addOval(oPtr, !!isCCW, startIndex);
Kevin Lubicke384df42019-08-26 15:48:09 -040087 return this;
88 };
89
Kevin Lubicka2535af2020-10-02 08:01:57 -040090 // TODO(kjlubick) clean up this API - split it apart if necessary
Kevin Lubick54c1b3d2020-10-07 16:09:22 -040091 CanvasKit.Path.prototype.addPath = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -050092 // Takes 1, 2, 7, or 10 required args, where the first arg is always the path.
93 // The last arg is optional and chooses between add or extend mode.
94 // The options for the remaining args are:
95 // - an array of 6 or 9 parameters (perspective is optional)
96 // - the 9 parameters of a full matrix or
97 // the 6 non-perspective params of a matrix.
98 var args = Array.prototype.slice.call(arguments);
99 var path = args[0];
100 var extend = false;
Kevin Lubickbe728012020-09-03 11:57:12 +0000101 if (typeof args[args.length-1] === 'boolean') {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500102 extend = args.pop();
103 }
104 if (args.length === 1) {
105 // Add path, unchanged. Use identity matrix
106 this._addPath(path, 1, 0, 0,
107 0, 1, 0,
108 0, 0, 1,
109 extend);
110 } else if (args.length === 2) {
111 // User provided the 9 params of a full matrix as an array.
112 var a = args[1];
113 this._addPath(path, a[0], a[1], a[2],
114 a[3], a[4], a[5],
115 a[6] || 0, a[7] || 0, a[8] || 1,
116 extend);
117 } else if (args.length === 7 || args.length === 10) {
118 // User provided the 9 params of a (full) matrix directly.
119 // (or just the 6 non perspective ones)
120 // These are in the same order as what Skia expects.
121 var a = args;
122 this._addPath(path, a[1], a[2], a[3],
123 a[4], a[5], a[6],
124 a[7] || 0, a[8] || 0, a[9] || 1,
125 extend);
126 } else {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400127 Debug('addPath expected to take 1, 2, 7, or 10 required args. Got ' + args.length);
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400128 return null;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500129 }
130 return this;
131 };
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400132
Kevin Lubicke7c1a732020-12-04 09:10:39 -0500133 // points is a 1d array of length 2n representing n points where the even indices
134 // will be treated as x coordinates and the odd indices will be treated as y coordinates.
135 // Like other APIs, this accepts a malloced type array or malloc obj.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400136 CanvasKit.Path.prototype.addPoly = function(points, close) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -0500137 var ptr = copy1dArray(points, 'HEAPF32');
138 this._addPoly(ptr, points.length / 2, close);
Kevin Lubickcf118922020-05-28 14:43:38 -0400139 freeArraysThatAreNotMallocedByUsers(ptr, points);
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500140 return this;
141 };
142
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400143 CanvasKit.Path.prototype.addRect = function(rect, isCCW) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400144 var rPtr = copyRectToWasm(rect);
145 this._addRect(rPtr, !!isCCW);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500146 return this;
147 };
Kevin Lubick217056c2018-09-20 17:39:31 -0400148
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400149 CanvasKit.Path.prototype.addRRect = function(rrect, isCCW) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400150 var rPtr = copyRRectToWasm(rrect);
151 this._addRRect(rPtr, !!isCCW);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500152 return this;
153 };
154
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400155 // The weights array is optional (only used for conics).
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400156 CanvasKit.Path.prototype.addVerbsPointsWeights = function(verbs, points, weights) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000157 var verbsPtr = copy1dArray(verbs, 'HEAPU8');
158 var pointsPtr = copy1dArray(points, 'HEAPF32');
159 var weightsPtr = copy1dArray(weights, 'HEAPF32');
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -0400160 var numWeights = (weights && weights.length) || 0;
161 this._addVerbsPointsWeights(verbsPtr, verbs.length, pointsPtr, points.length,
162 weightsPtr, numWeights);
163 freeArraysThatAreNotMallocedByUsers(verbsPtr, verbs);
164 freeArraysThatAreNotMallocedByUsers(pointsPtr, points);
165 freeArraysThatAreNotMallocedByUsers(weightsPtr, weights);
166 };
167
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400168 CanvasKit.Path.prototype.arc = function(x, y, radius, startAngle, endAngle, ccw) {
169 // emulates the HTMLCanvas behavior. See addArc() for the Path version.
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500170 // Note input angles are radians.
171 var bounds = CanvasKit.LTRBRect(x-radius, y-radius, x+radius, y+radius);
172 var sweep = radiansToDegrees(endAngle - startAngle) - (360 * !!ccw);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400173 var temp = new CanvasKit.Path();
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500174 temp.addArc(bounds, radiansToDegrees(startAngle), sweep);
175 this.addPath(temp, true);
176 temp.delete();
177 return this;
178 };
179
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400180 // Appends arc to Path. Arc added is part of ellipse
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400181 // bounded by oval, from startAngle through sweepAngle. Both startAngle and
182 // sweepAngle are measured in degrees, where zero degrees is aligned with the
183 // positive x-axis, and positive sweeps extends arc clockwise.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400184 CanvasKit.Path.prototype.arcToOval = function(oval, startAngle, sweepAngle, forceMoveTo) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400185 var oPtr = copyRectToWasm(oval);
186 this._arcToOval(oPtr, startAngle, sweepAngle, forceMoveTo);
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400187 return this;
188 };
189
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400190 // Appends arc to Path. Arc is implemented by one or more conics weighted to
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400191 // describe part of oval with radii (rx, ry) rotated by xAxisRotate degrees. Arc
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400192 // curves from last point to (x, y), choosing one of four possible routes:
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400193 // clockwise or counterclockwise, and smaller or larger.
194
195 // Arc sweep is always less than 360 degrees. arcTo() appends line to (x, y) if
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400196 // either radii are zero, or if last point equals (x, y). arcTo() scales radii
197 // (rx, ry) to fit last point and (x, y) if both are greater than zero but
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400198 // too small.
199
200 // arcToRotated() appends up to four conic curves.
201 // arcToRotated() implements the functionality of SVG arc, although SVG sweep-flag value
202 // is opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise,
203 // while kCW_Direction cast to int is zero.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400204 CanvasKit.Path.prototype.arcToRotated = function(rx, ry, xAxisRotate, useSmallArc, isCCW, x, y) {
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400205 this._arcToRotated(rx, ry, xAxisRotate, !!useSmallArc, !!isCCW, x, y);
206 return this;
207 };
208
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400209 // Appends arc to Path, after appending line if needed. Arc is implemented by conic
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400210 // weighted to describe part of circle. Arc is contained by tangent from
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400211 // last Path point to (x1, y1), and tangent from (x1, y1) to (x2, y2). Arc
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400212 // is part of circle sized to radius, positioned so it touches both tangent lines.
213
214 // If last Path Point does not start Arc, arcTo appends connecting Line to Path.
215 // The length of Vector from (x1, y1) to (x2, y2) does not affect Arc.
216
217 // Arc sweep is always less than 180 degrees. If radius is zero, or if
218 // tangents are nearly parallel, arcTo appends Line from last Path Point to (x1, y1).
219
220 // arcToTangent appends at most one Line and one conic.
221 // arcToTangent implements the functionality of PostScript arct and HTML Canvas arcTo.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400222 CanvasKit.Path.prototype.arcToTangent = function(x1, y1, x2, y2, radius) {
Nathaniel Nifongd0c9d0c2020-07-15 16:46:17 -0400223 this._arcToTangent(x1, y1, x2, y2, radius);
224 return this;
225 };
226
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400227 CanvasKit.Path.prototype.close = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500228 this._close();
229 return this;
230 };
231
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400232 CanvasKit.Path.prototype.conicTo = function(x1, y1, x2, y2, w) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500233 this._conicTo(x1, y1, x2, y2, w);
234 return this;
235 };
236
Kevin Lubick7d96c5c2020-10-01 10:55:16 -0400237 // Clients can pass in a Float32Array with length 4 to this and the results
238 // will be copied into that array. Otherwise, a new TypedArray will be allocated
239 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400240 CanvasKit.Path.prototype.computeTightBounds = function(optionalOutputArray) {
Kevin Lubicked962642021-02-02 08:18:11 -0500241 this._computeTightBounds(_scratchFourFloatsAPtr);
242 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubick7d96c5c2020-10-01 10:55:16 -0400243 if (optionalOutputArray) {
244 optionalOutputArray.set(ta);
245 return optionalOutputArray;
246 }
247 return ta.slice();
248 };
249
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400250 CanvasKit.Path.prototype.cubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500251 this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
252 return this;
253 };
254
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400255 CanvasKit.Path.prototype.dash = function(on, off, phase) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500256 if (this._dash(on, off, phase)) {
Kevin Lubick217056c2018-09-20 17:39:31 -0400257 return this;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500258 }
259 return null;
260 };
Kevin Lubick217056c2018-09-20 17:39:31 -0400261
Kevin Lubickf8823b52020-09-03 10:02:10 -0400262 // Clients can pass in a Float32Array with length 4 to this and the results
263 // will be copied into that array. Otherwise, a new TypedArray will be allocated
264 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400265 CanvasKit.Path.prototype.getBounds = function(optionalOutputArray) {
Kevin Lubicked962642021-02-02 08:18:11 -0500266 this._getBounds(_scratchFourFloatsAPtr);
267 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubickf8823b52020-09-03 10:02:10 -0400268 if (optionalOutputArray) {
269 optionalOutputArray.set(ta);
270 return optionalOutputArray;
271 }
272 return ta.slice();
273 };
274
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400275 CanvasKit.Path.prototype.lineTo = function(x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500276 this._lineTo(x, y);
277 return this;
278 };
Kevin Lubick217056c2018-09-20 17:39:31 -0400279
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400280 CanvasKit.Path.prototype.moveTo = function(x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500281 this._moveTo(x, y);
282 return this;
283 };
Kevin Lubickb5ae3b52018-11-03 07:51:19 -0400284
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400285 CanvasKit.Path.prototype.offset = function(dx, dy) {
Kevin Lubicke384df42019-08-26 15:48:09 -0400286 this._transform(1, 0, dx,
287 0, 1, dy,
288 0, 0, 1);
289 return this;
290 };
291
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400292 CanvasKit.Path.prototype.quadTo = function(cpx, cpy, x, y) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500293 this._quadTo(cpx, cpy, x, y);
294 return this;
295 };
296
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400297 CanvasKit.Path.prototype.rArcTo = function(rx, ry, xAxisRotate, useSmallArc, isCCW, dx, dy) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400298 this._rArcTo(rx, ry, xAxisRotate, useSmallArc, isCCW, dx, dy);
299 return this;
300 };
301
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400302 CanvasKit.Path.prototype.rConicTo = function(dx1, dy1, dx2, dy2, w) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400303 this._rConicTo(dx1, dy1, dx2, dy2, w);
304 return this;
305 };
306
307 // These params are all relative
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400308 CanvasKit.Path.prototype.rCubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400309 this._rCubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
310 return this;
311 };
312
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400313 CanvasKit.Path.prototype.rLineTo = function(dx, dy) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400314 this._rLineTo(dx, dy);
315 return this;
316 };
317
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400318 CanvasKit.Path.prototype.rMoveTo = function(dx, dy) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400319 this._rMoveTo(dx, dy);
320 return this;
321 };
322
323 // These params are all relative
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400324 CanvasKit.Path.prototype.rQuadTo = function(cpx, cpy, x, y) {
Kevin Lubick79b71342019-11-01 14:36:52 -0400325 this._rQuadTo(cpx, cpy, x, y);
326 return this;
327 };
328
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400329 CanvasKit.Path.prototype.stroke = function(opts) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500330 // Fill out any missing values with the default values.
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500331 opts = opts || {};
Kevin Lubick6aa38692020-06-01 11:25:47 -0400332 opts['width'] = opts['width'] || 1;
333 opts['miter_limit'] = opts['miter_limit'] || 4;
334 opts['cap'] = opts['cap'] || CanvasKit.StrokeCap.Butt;
335 opts['join'] = opts['join'] || CanvasKit.StrokeJoin.Miter;
336 opts['precision'] = opts['precision'] || 1;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500337 if (this._stroke(opts)) {
338 return this;
339 }
340 return null;
341 };
342
Kevin Lubicka2535af2020-10-02 08:01:57 -0400343 // TODO(kjlubick) Change this to take a 3x3 or 4x4 matrix (optionally malloc'd)
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400344 CanvasKit.Path.prototype.transform = function() {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500345 // Takes 1 or 9 args
346 if (arguments.length === 1) {
347 // argument 1 should be a 6 or 9 element array.
348 var a = arguments[0];
349 this._transform(a[0], a[1], a[2],
350 a[3], a[4], a[5],
351 a[6] || 0, a[7] || 0, a[8] || 1);
352 } else if (arguments.length === 6 || arguments.length === 9) {
353 // these arguments are the 6 or 9 members of the matrix
354 var a = arguments;
355 this._transform(a[0], a[1], a[2],
356 a[3], a[4], a[5],
357 a[6] || 0, a[7] || 0, a[8] || 1);
358 } else {
359 throw 'transform expected to take 1 or 9 arguments. Got ' + arguments.length;
360 }
361 return this;
362 };
363 // isComplement is optional, defaults to false
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400364 CanvasKit.Path.prototype.trim = function(startT, stopT, isComplement) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500365 if (this._trim(startT, stopT, !!isComplement)) {
366 return this;
367 }
368 return null;
369 };
370
Kevin Lubick652d7902020-12-11 14:51:36 -0500371 // makeShaderCubic returns a shader for a given image, allowing it to be used on
372 // a paint as well as other purposes. This shader will be higher quality than
373 // other shader functions. See CubicResampler in SkSamplingOptions.h for more information
374 // on the cubicResampler params.
375 CanvasKit.Image.prototype.makeShaderCubic = function(xTileMode, yTileMode,
376 cubicResamplerB, cubicResamplerC,
377 localMatrix) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400378 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Kevin Lubick652d7902020-12-11 14:51:36 -0500379 return this._makeShaderCubic(xTileMode, yTileMode, cubicResamplerB,
380 cubicResamplerC, localMatrixPtr);
381 };
382
383 // makeShaderCubic returns a shader for a given image, allowing it to be used on
384 // a paint as well as other purposes. This shader will draw more quickly than
385 // other shader functions, but at a lower quality.
386 CanvasKit.Image.prototype.makeShaderOptions = function(xTileMode, yTileMode,
387 filterMode, mipmapMode,
388 localMatrix) {
389 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
390 return this._makeShaderOptions(xTileMode, yTileMode, filterMode, mipmapMode, localMatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500391 };
Kevin Lubicka064c282019-04-04 09:28:53 -0400392
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500393 function readPixels(source, srcX, srcY, imageInfo, destMallocObj, bytesPerRow) {
394 if (!bytesPerRow) {
395 bytesPerRow = 4 * imageInfo['width'];
396 if (imageInfo['colorType'] === CanvasKit.ColorType.RGBA_F16) {
397 bytesPerRow *= 2;
398 }
399 else if (imageInfo['colorType'] === CanvasKit.ColorType.RGBA_F32) {
400 bytesPerRow *= 4;
401 }
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400402 }
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500403 var pBytes = bytesPerRow * imageInfo.height;
Kevin Lubickc4ab0872020-11-03 17:13:09 -0500404 var pPtr;
405 if (destMallocObj) {
406 pPtr = destMallocObj['byteOffset'];
407 } else {
408 pPtr = CanvasKit._malloc(pBytes);
409 }
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400410
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500411 if (!source._readPixels(imageInfo, pPtr, bytesPerRow, srcX, srcY)) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400412 Debug('Could not read pixels with the given inputs');
Kevin Lubickc4ab0872020-11-03 17:13:09 -0500413 if (!destMallocObj) {
414 CanvasKit._free(pPtr);
415 }
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400416 return null;
417 }
418
Kevin Lubickc4ab0872020-11-03 17:13:09 -0500419 // If the user provided us a buffer to copy into, we don't need to allocate a new TypedArray.
420 if (destMallocObj) {
421 return destMallocObj['toTypedArray'](); // Return the typed array wrapper w/o allocating.
422 }
423
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400424 // Put those pixels into a typed array of the right format and then
425 // make a copy with slice() that we can return.
426 var retVal = null;
Kevin Lubickbe728012020-09-03 11:57:12 +0000427 switch (imageInfo['colorType']) {
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400428 case CanvasKit.ColorType.RGBA_8888:
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500429 case CanvasKit.ColorType.RGBA_F16: // there is no half-float JS type, so we return raw bytes.
Bryce Thomas1fa54042020-01-14 13:46:30 -0800430 retVal = new Uint8Array(CanvasKit.HEAPU8.buffer, pPtr, pBytes).slice();
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400431 break;
432 case CanvasKit.ColorType.RGBA_F32:
Bryce Thomas1fa54042020-01-14 13:46:30 -0800433 retVal = new Float32Array(CanvasKit.HEAPU8.buffer, pPtr, pBytes).slice();
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400434 break;
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500435 default:
436 Debug('ColorType not yet supported');
437 return null;
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400438 }
439
440 // Free the allocated pixels in the WASM memory
441 CanvasKit._free(pPtr);
442 return retVal;
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500443 }
444
445 CanvasKit.Image.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj,
446 bytesPerRow) {
447 return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500448 };
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400449
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400450 // Accepts an array of four numbers in the range of 0-1 representing a 4f color
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400451 CanvasKit.Canvas.prototype.clear = function(color4f) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400452 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400453 this._clear(cPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500454 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400455
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400456 CanvasKit.Canvas.prototype.clipRRect = function(rrect, op, antialias) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000457 var rPtr = copyRRectToWasm(rrect);
458 this._clipRRect(rPtr, op, antialias);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500459 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000460
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400461 CanvasKit.Canvas.prototype.clipRect = function(rect, op, antialias) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400462 var rPtr = copyRectToWasm(rect);
463 this._clipRect(rPtr, op, antialias);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500464 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400465
Kevin Lubickc1d08982020-04-06 13:52:15 -0400466 // concat takes a 3x2, a 3x3, or a 4x4 matrix and upscales it (if needed) to 4x4. This is because
467 // under the hood, SkCanvas uses a 4x4 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400468 CanvasKit.Canvas.prototype.concat = function(matr) {
Kevin Lubickc1d08982020-04-06 13:52:15 -0400469 var matrPtr = copy4x4MatrixToWasm(matr);
Kevin Lubick6bffe392020-04-02 15:24:15 -0400470 this._concat(matrPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500471 };
Kevin Lubickd6b32ed2019-05-06 13:04:03 -0400472
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400473 CanvasKit.Canvas.prototype.drawArc = function(oval, startAngle, sweepAngle, useCenter, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400474 var oPtr = copyRectToWasm(oval);
475 this._drawArc(oPtr, startAngle, sweepAngle, useCenter, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500476 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400477
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400478 // atlas is an Image, e.g. from CanvasKit.MakeImageFromEncoded
Kevin Lubick78297af2021-06-02 10:36:06 -0400479 // srcRects, dstXformsshould be arrays of floats of length 4*number of destinations.
480 // The colors param is optional and is used to tint the drawn images using the optional blend
481 // mode. Colors can be a Uint32Array of int colors or a flat Float32Array of float colors.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400482 CanvasKit.Canvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint,
Mike Reed55144312021-03-25 13:13:23 -0400483 /* optional */ blendMode, /* optional */ colors,
484 /* optional */ sampling) {
Kevin Lubickee91c072019-03-29 10:39:52 -0400485 if (!atlas || !paint || !srcRects || !dstXforms) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400486 Debug('Doing nothing since missing a required input');
Kevin Lubickee91c072019-03-29 10:39:52 -0400487 return;
488 }
Nathaniel Nifongcd75b172020-06-05 11:17:43 -0400489
490 // builder arguments report the length as the number of rects, but when passed as arrays
491 // their.length attribute is 4x higher because it's the number of total components of all rects.
492 // colors is always going to report the same length, at least until floats colors are supported
493 // by this function.
494 if (srcRects.length !== dstXforms.length) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400495 Debug('Doing nothing since input arrays length mismatches');
Nathaniel Nifonge5d32542020-03-26 09:27:48 -0400496 return;
Kevin Lubickee91c072019-03-29 10:39:52 -0400497 }
498 if (!blendMode) {
499 blendMode = CanvasKit.BlendMode.SrcOver;
500 }
501
Kevin Lubick78297af2021-06-02 10:36:06 -0400502 var srcRectPtr = copy1dArray(srcRects, 'HEAPF32');
Kevin Lubickee91c072019-03-29 10:39:52 -0400503
Kevin Lubick78297af2021-06-02 10:36:06 -0400504 var dstXformPtr = copy1dArray(dstXforms, 'HEAPF32');
505 var count = dstXforms.length / 4;
Kevin Lubickee91c072019-03-29 10:39:52 -0400506
Kevin Lubick78297af2021-06-02 10:36:06 -0400507 var colorPtr = copy1dArray(assureIntColors(colors), 'HEAPU32');
Kevin Lubickee91c072019-03-29 10:39:52 -0400508
Mike Reed55144312021-03-25 13:13:23 -0400509 // We require one of these:
510 // 1. sampling is null (we default to linear/none)
511 // 2. sampling.B and sampling.C --> CubicResampler
512 // 3. sampling.filter [and sampling.mipmap] --> FilterOptions
513 //
514 // Thus if all fields are available, we will choose cubic (since we search for B,C first)
515
516 if (sampling && ('B' in sampling) && ('C' in sampling)) {
517 this._drawAtlasCubic(atlas, dstXformPtr, srcRectPtr, colorPtr, count, blendMode,
518 sampling['B'], sampling['C'], paint);
519 } else {
520 let filter = CanvasKit.FilterMode.Linear;
521 let mipmap = CanvasKit.MipmapMode.None;
522 if (sampling) {
523 filter = sampling['filter']; // 'filter' is a required field
524 if ('mipmap' in sampling) { // 'mipmap' is optional
525 mipmap = sampling['mipmap'];
526 }
527 }
528 this._drawAtlasOptions(atlas, dstXformPtr, srcRectPtr, colorPtr, count, blendMode,
529 filter, mipmap, paint);
530 }
Kevin Lubickee91c072019-03-29 10:39:52 -0400531
Kevin Lubick78297af2021-06-02 10:36:06 -0400532 freeArraysThatAreNotMallocedByUsers(srcRectPtr, srcRects);
533 freeArraysThatAreNotMallocedByUsers(dstXformPtr, dstXforms);
534 freeArraysThatAreNotMallocedByUsers(colorPtr, colors);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500535 };
Kevin Lubickee91c072019-03-29 10:39:52 -0400536
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400537 CanvasKit.Canvas.prototype.drawColor = function (color4f, mode) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400538 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400539 if (mode !== undefined) {
540 this._drawColor(cPtr, mode);
541 } else {
542 this._drawColor(cPtr);
543 }
Kevin Lubick9fe83912020-11-03 17:08:34 -0500544 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400545
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400546 CanvasKit.Canvas.prototype.drawColorComponents = function (r, g, b, a, mode) {
Kevin Lubick93f1a382020-06-02 16:15:23 -0400547 var cPtr = copyColorComponentsToWasm(r, g, b, a);
548 if (mode !== undefined) {
549 this._drawColor(cPtr, mode);
550 } else {
551 this._drawColor(cPtr);
552 }
Kevin Lubick9fe83912020-11-03 17:08:34 -0500553 };
Kevin Lubick93f1a382020-06-02 16:15:23 -0400554
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400555 CanvasKit.Canvas.prototype.drawDRRect = function(outer, inner, paint) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000556 var oPtr = copyRRectToWasm(outer, _scratchRRectPtr);
557 var iPtr = copyRRectToWasm(inner, _scratchRRect2Ptr);
558 this._drawDRRect(oPtr, iPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500559 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000560
Mike Reed9983b1e2021-04-14 14:49:35 -0400561 CanvasKit.Canvas.prototype.drawGlyphs = function(glyphs, positions, x, y, font, paint) {
Mike Reedae339542021-04-27 17:46:41 -0400562 if (!(glyphs.length*2 <= positions.length)) {
563 throw 'Not enough positions for the array of gyphs';
Mike Reed9983b1e2021-04-14 14:49:35 -0400564 }
565
566 const glyphs_ptr = copy1dArray(glyphs, 'HEAPU16');
567 const positions_ptr = copy1dArray(positions, 'HEAPF32');
568
569 this._drawGlyphs(glyphs.length, glyphs_ptr, positions_ptr, x, y, font, paint);
570
571 freeArraysThatAreNotMallocedByUsers(positions_ptr, positions);
572 freeArraysThatAreNotMallocedByUsers(glyphs_ptr, glyphs);
573 };
574
Kevin Lubick2d633492020-12-17 09:58:32 -0500575 CanvasKit.Canvas.prototype.drawImageNine = function(img, center, dest, filter, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400576 var cPtr = copyIRectToWasm(center);
577 var dPtr = copyRectToWasm(dest);
Kevin Lubick2d633492020-12-17 09:58:32 -0500578 this._drawImageNine(img, cPtr, dPtr, filter, paint || null);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500579 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400580
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400581 CanvasKit.Canvas.prototype.drawImageRect = function(img, src, dest, paint, fastSample) {
Kevin Lubicked962642021-02-02 08:18:11 -0500582 copyRectToWasm(src, _scratchFourFloatsAPtr);
583 copyRectToWasm(dest, _scratchFourFloatsBPtr);
584 this._drawImageRect(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, paint, !!fastSample);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500585 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400586
Kevin Lubick72f40762020-12-16 16:00:55 -0500587 CanvasKit.Canvas.prototype.drawImageRectCubic = function(img, src, dest, B, C, paint) {
Kevin Lubicked962642021-02-02 08:18:11 -0500588 copyRectToWasm(src, _scratchFourFloatsAPtr);
589 copyRectToWasm(dest, _scratchFourFloatsBPtr);
590 this._drawImageRectCubic(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, B, C,
591 paint || null);
Kevin Lubick72f40762020-12-16 16:00:55 -0500592 };
593
594 CanvasKit.Canvas.prototype.drawImageRectOptions = function(img, src, dest, filter, mipmap, paint) {
Kevin Lubicked962642021-02-02 08:18:11 -0500595 copyRectToWasm(src, _scratchFourFloatsAPtr);
596 copyRectToWasm(dest, _scratchFourFloatsBPtr);
597 this._drawImageRectOptions(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, filter, mipmap,
598 paint || null);
Kevin Lubick72f40762020-12-16 16:00:55 -0500599 };
600
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400601 CanvasKit.Canvas.prototype.drawOval = function(oval, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400602 var oPtr = copyRectToWasm(oval);
603 this._drawOval(oPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500604 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400605
Mike Reed6e7d2b32021-03-29 16:38:01 -0400606 CanvasKit.Canvas.prototype.drawPatch = function(cubics, colors, texs, mode, paint) {
607 if (cubics.length < 24) {
Mike Reedbe834bf2021-04-14 14:51:59 -0400608 throw 'Need 12 cubic points';
Mike Reed6e7d2b32021-03-29 16:38:01 -0400609 }
610 if (colors && colors.length < 4) {
Mike Reedbe834bf2021-04-14 14:51:59 -0400611 throw 'Need 4 colors';
Mike Reed6e7d2b32021-03-29 16:38:01 -0400612 }
613 if (texs && texs.length < 8) {
Mike Reedbe834bf2021-04-14 14:51:59 -0400614 throw 'Need 4 shader coordinates';
Mike Reed6e7d2b32021-03-29 16:38:01 -0400615 }
616
617 const cubics_ptr = copy1dArray(cubics, 'HEAPF32');
618 const colors_ptr = colors ? copy1dArray(assureIntColors(colors), 'HEAPU32') : nullptr;
619 const texs_ptr = texs ? copy1dArray(texs, 'HEAPF32') : nullptr;
620 if (!mode) {
621 mode = CanvasKit.BlendMode.Modulate;
622 }
623
624 this._drawPatch(cubics_ptr, colors_ptr, texs_ptr, mode, paint);
625
626 freeArraysThatAreNotMallocedByUsers(texs_ptr, texs);
627 freeArraysThatAreNotMallocedByUsers(colors_ptr, colors);
628 freeArraysThatAreNotMallocedByUsers(cubics_ptr, cubics);
629 };
630
631
Kevin Lubick658cb712020-12-01 14:55:02 -0500632 // points is a 1d array of length 2n representing n points where the even indices
633 // will be treated as x coordinates and the odd indices will be treated as y coordinates.
634 // Like other APIs, this accepts a malloced type array or malloc obj.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400635 CanvasKit.Canvas.prototype.drawPoints = function(mode, points, paint) {
Kevin Lubick658cb712020-12-01 14:55:02 -0500636 var ptr = copy1dArray(points, 'HEAPF32');
637 this._drawPoints(mode, ptr, points.length / 2, paint);
Kevin Lubickcf118922020-05-28 14:43:38 -0400638 freeArraysThatAreNotMallocedByUsers(ptr, points);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500639 };
Kevin Lubick37ab53e2019-11-11 10:06:08 -0500640
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400641 CanvasKit.Canvas.prototype.drawRRect = function(rrect, paint) {
Kevin Lubickbe728012020-09-03 11:57:12 +0000642 var rPtr = copyRRectToWasm(rrect);
643 this._drawRRect(rPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500644 };
Kevin Lubickbe728012020-09-03 11:57:12 +0000645
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400646 CanvasKit.Canvas.prototype.drawRect = function(rect, paint) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400647 var rPtr = copyRectToWasm(rect);
648 this._drawRect(rPtr, paint);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500649 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400650
Kevin Lubickcbaea292021-01-13 14:16:58 -0500651 CanvasKit.Canvas.prototype.drawShadow = function(path, zPlaneParams, lightPos, lightRadius,
652 ambientColor, spotColor, flags) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400653 var ambiPtr = copyColorToWasmNoScratch(ambientColor);
654 var spotPtr = copyColorToWasmNoScratch(spotColor);
Kevin Lubickf6040ef2021-02-02 08:26:48 -0500655 // We use the return value from copy1dArray in case the passed in arrays are malloc'd.
656 var zPlanePtr = copy1dArray(zPlaneParams, 'HEAPF32', _scratchThreeFloatsAPtr);
657 var lightPosPtr = copy1dArray(lightPos, 'HEAPF32', _scratchThreeFloatsBPtr);
658 this._drawShadow(path, zPlanePtr, lightPosPtr, lightRadius, ambiPtr, spotPtr, flags);
Kevin Lubickcf118922020-05-28 14:43:38 -0400659 freeArraysThatAreNotMallocedByUsers(ambiPtr, ambientColor);
660 freeArraysThatAreNotMallocedByUsers(spotPtr, spotColor);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500661 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400662
Kevin Lubickcbaea292021-01-13 14:16:58 -0500663 CanvasKit.getShadowLocalBounds = function(ctm, path, zPlaneParams, lightPos, lightRadius,
664 flags, optOutputRect) {
665 var ctmPtr = copy3x3MatrixToWasm(ctm);
Kevin Lubickf6040ef2021-02-02 08:26:48 -0500666 // We use the return value from copy1dArray in case the passed in arrays are malloc'd.
667 var zPlanePtr = copy1dArray(zPlaneParams, 'HEAPF32', _scratchThreeFloatsAPtr);
668 var lightPosPtr = copy1dArray(lightPos, 'HEAPF32', _scratchThreeFloatsBPtr);
669 var ok = this._getShadowLocalBounds(ctmPtr, path, zPlanePtr, lightPosPtr, lightRadius,
Kevin Lubicked962642021-02-02 08:18:11 -0500670 flags, _scratchFourFloatsAPtr);
Kevin Lubickcbaea292021-01-13 14:16:58 -0500671 if (!ok) {
672 return null;
673 }
Kevin Lubicked962642021-02-02 08:18:11 -0500674 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubickcbaea292021-01-13 14:16:58 -0500675 if (optOutputRect) {
676 optOutputRect.set(ta);
677 return optOutputRect;
678 }
679 return ta.slice();
680 };
681
Kevin Lubickc1d08982020-04-06 13:52:15 -0400682 // getLocalToDevice returns a 4x4 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400683 CanvasKit.Canvas.prototype.getLocalToDevice = function() {
Kevin Lubickc1d08982020-04-06 13:52:15 -0400684 // _getLocalToDevice will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400685 this._getLocalToDevice(_scratch4x4MatrixPtr);
686 return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500687 };
Kevin Lubickc1d08982020-04-06 13:52:15 -0400688
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400689 // findMarkedCTM returns a 4x4 matrix, or null if a matrix was not found at
690 // the provided marker.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400691 CanvasKit.Canvas.prototype.findMarkedCTM = function(marker) {
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400692 // _getLocalToDevice will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400693 var found = this._findMarkedCTM(marker, _scratch4x4MatrixPtr);
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400694 if (!found) {
695 return null;
696 }
Kevin Lubick6aa38692020-06-01 11:25:47 -0400697 return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500698 };
Nathaniel Nifong00de91c2020-05-06 16:22:33 -0400699
Kevin Lubickc1d08982020-04-06 13:52:15 -0400700 // getTotalMatrix returns the current matrix as a 3x3 matrix.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400701 CanvasKit.Canvas.prototype.getTotalMatrix = function() {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400702 // _getTotalMatrix will copy the values into the pointer.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400703 this._getTotalMatrix(_scratch3x3MatrixPtr);
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400704 // read them out into an array. TODO(kjlubick): If we change Matrix to be
Kevin Lubick6bffe392020-04-02 15:24:15 -0400705 // typedArrays, then we should return a typed array here too.
706 var rv = new Array(9);
707 for (var i = 0; i < 9; i++) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400708 rv[i] = CanvasKit.HEAPF32[_scratch3x3MatrixPtr/4 + i]; // divide by 4 to "cast" to float.
Kevin Lubick6bffe392020-04-02 15:24:15 -0400709 }
Kevin Lubick6bffe392020-04-02 15:24:15 -0400710 return rv;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500711 };
Kevin Lubick6bffe392020-04-02 15:24:15 -0400712
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500713 CanvasKit.Canvas.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj,
714 bytesPerRow) {
715 return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500716 };
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500717
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400718 CanvasKit.Canvas.prototype.saveLayer = function(paint, boundsRect, backdrop, flags) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400719 // bPtr will be 0 (nullptr) if boundsRect is undefined/null.
720 var bPtr = copyRectToWasm(boundsRect);
721 // These or clauses help emscripten, which does not deal with undefined well.
722 return this._saveLayer(paint || null, bPtr, backdrop || null, flags || 0);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500723 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400724
Kevin Lubickcf118922020-05-28 14:43:38 -0400725 // pixels should be a Uint8Array or a plain JS array.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400726 CanvasKit.Canvas.prototype.writePixels = function(pixels, srcWidth, srcHeight,
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400727 destX, destY, alphaType, colorType, colorSpace) {
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500728 if (pixels.byteLength % (srcWidth * srcHeight)) {
729 throw 'pixels length must be a multiple of the srcWidth * srcHeight';
730 }
731 var bytesPerPixel = pixels.byteLength / (srcWidth * srcHeight);
732 // supply defaults (which are compatible with HTMLCanvas's putImageData)
733 alphaType = alphaType || CanvasKit.AlphaType.Unpremul;
734 colorType = colorType || CanvasKit.ColorType.RGBA_8888;
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400735 colorSpace = colorSpace || CanvasKit.ColorSpace.SRGB;
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500736 var srcRowBytes = bytesPerPixel * srcWidth;
737
Kevin Lubickbe728012020-09-03 11:57:12 +0000738 var pptr = copy1dArray(pixels, 'HEAPU8');
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500739 var ok = this._writePixels({
740 'width': srcWidth,
741 'height': srcHeight,
742 'colorType': colorType,
743 'alphaType': alphaType,
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400744 'colorSpace': colorSpace,
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500745 }, pptr, srcRowBytes, destX, destY);
746
Kevin Lubickcf118922020-05-28 14:43:38 -0400747 freeArraysThatAreNotMallocedByUsers(pptr, pixels);
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500748 return ok;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500749 };
Kevin Lubick52b9f372018-12-04 13:57:36 -0500750
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400751 CanvasKit.ColorFilter.MakeBlend = function(color4f, mode) {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400752 var cPtr = copyColorToWasm(color4f);
Kevin Lubick33645792021-01-29 08:37:41 -0500753 return CanvasKit.ColorFilter._MakeBlend(cPtr, mode);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500754 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400755
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400756 // colorMatrix is an ColorMatrix (e.g. Float32Array of length 20)
757 CanvasKit.ColorFilter.MakeMatrix = function(colorMatrix) {
Kevin Lubickd3729342019-09-12 11:11:25 -0400758 if (!colorMatrix || colorMatrix.length !== 20) {
Kevin Lubick6bffe392020-04-02 15:24:15 -0400759 throw 'invalid color matrix';
Kevin Lubickd3729342019-09-12 11:11:25 -0400760 }
Kevin Lubickbe728012020-09-03 11:57:12 +0000761 var fptr = copy1dArray(colorMatrix, 'HEAPF32');
Kevin Lubickd3729342019-09-12 11:11:25 -0400762 // We know skia memcopies the floats, so we can free our memory after the call returns.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400763 var m = CanvasKit.ColorFilter._makeMatrix(fptr);
Kevin Lubickcf118922020-05-28 14:43:38 -0400764 freeArraysThatAreNotMallocedByUsers(fptr, colorMatrix);
Kevin Lubickd3729342019-09-12 11:11:25 -0400765 return m;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500766 };
Kevin Lubickd3729342019-09-12 11:11:25 -0400767
Kevin Lubicke9e8e5d2021-02-02 10:21:24 -0500768 CanvasKit.ContourMeasure.prototype.getPosTan = function(distance, optionalOutput) {
769 this._getPosTan(distance, _scratchFourFloatsAPtr);
770 var ta = _scratchFourFloatsA['toTypedArray']();
771 if (optionalOutput) {
772 optionalOutput.set(ta);
773 return optionalOutput;
774 }
775 return ta.slice();
776 };
777
Mike Reed5caab8e2021-07-20 09:52:27 -0400778 CanvasKit.ImageFilter.MakeMatrixTransform = function(matrix, sampling, input) {
779 var matrPtr = copy3x3MatrixToWasm(matrix);
780
781 if ('B' in sampling && 'C' in sampling) {
782 return CanvasKit.ImageFilter._MakeMatrixTransformCubic(matrPtr,
783 sampling.B, sampling.C,
784 input);
785 } else {
786 const filter = sampling['filter']; // 'filter' is a required field
787 let mipmap = CanvasKit.MipmapMode.None;
788 if ('mipmap' in sampling) { // 'mipmap' is optional
789 mipmap = sampling['mipmap'];
790 }
791 return CanvasKit.ImageFilter._MakeMatrixTransformOptions(matrPtr,
792 filter, mipmap,
793 input);
794 }
Kevin Lubick9fe83912020-11-03 17:08:34 -0500795 };
Kevin Lubick6bffe392020-04-02 15:24:15 -0400796
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400797 CanvasKit.Paint.prototype.getColor = function() {
Kevin Lubick6aa38692020-06-01 11:25:47 -0400798 this._getColor(_scratchColorPtr);
799 return copyColorFromWasm(_scratchColorPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500800 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400801
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400802 CanvasKit.Paint.prototype.setColor = function(color4f, colorSpace) {
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400803 colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400804 // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here.
Kevin Lubick6aa38692020-06-01 11:25:47 -0400805 var cPtr = copyColorToWasm(color4f);
Nathaniel Nifongb1ebbb12020-05-26 13:10:20 -0400806 this._setColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500807 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400808
Kevin Lubick93f1a382020-06-02 16:15:23 -0400809 // The color components here are expected to be floating point values (nominally between
810 // 0.0 and 1.0, but with wider color gamuts, the values could exceed this range). To convert
811 // between standard 8 bit colors and floats, just divide by 255 before passing them in.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400812 CanvasKit.Paint.prototype.setColorComponents = function(r, g, b, a, colorSpace) {
Kevin Lubick93f1a382020-06-02 16:15:23 -0400813 colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400814 // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here.
Kevin Lubick93f1a382020-06-02 16:15:23 -0400815 var cPtr = copyColorComponentsToWasm(r, g, b, a);
816 this._setColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500817 };
Kevin Lubick93f1a382020-06-02 16:15:23 -0400818
Kevin Lubicked962642021-02-02 08:18:11 -0500819 CanvasKit.Path.prototype.getPoint = function(idx, optionalOutput) {
820 // This will copy 2 floats into a space for 4 floats
821 this._getPoint(idx, _scratchFourFloatsAPtr);
822 var ta = _scratchFourFloatsA['toTypedArray']();
823 if (optionalOutput) {
824 // We cannot call optionalOutput.set() because it is an error to call .set() with
825 // a source bigger than the destination.
826 optionalOutput[0] = ta[0];
827 optionalOutput[1] = ta[1];
828 return optionalOutput;
829 }
830 // Be sure to return a copy of just the first 2 values.
831 return ta.slice(0, 2);
832 };
833
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400834 CanvasKit.PictureRecorder.prototype.beginRecording = function(bounds) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400835 var bPtr = copyRectToWasm(bounds);
836 return this._beginRecording(bPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500837 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400838
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400839 CanvasKit.Surface.prototype.makeImageSnapshot = function(optionalBoundsRect) {
Kevin Lubickf8823b52020-09-03 10:02:10 -0400840 var bPtr = copyIRectToWasm(optionalBoundsRect);
841 return this._makeImageSnapshot(bPtr);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500842 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400843
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400844 CanvasKit.Surface.prototype.requestAnimationFrame = function(callback, dirtyRect) {
Kevin Lubick359a7e32019-03-19 09:34:37 -0400845 if (!this._cached_canvas) {
846 this._cached_canvas = this.getCanvas();
847 }
Elliot Evans1ec3b1a2020-07-23 10:25:58 -0400848 requestAnimationFrame(function() {
Kevin Lubick39026282019-03-28 12:46:40 -0400849 if (this._context !== undefined) {
850 CanvasKit.setCurrentContext(this._context);
851 }
Kevin Lubick359a7e32019-03-19 09:34:37 -0400852
853 callback(this._cached_canvas);
854
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400855 // We do not dispose() of the Surface here, as the client will typically
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800856 // call requestAnimationFrame again from within the supplied callback.
857 // For drawing a single frame, prefer drawOnce().
Bryce Thomas9331ca02020-05-29 16:51:21 -0700858 this.flush(dirtyRect);
Kevin Lubick359a7e32019-03-19 09:34:37 -0400859 }.bind(this));
Kevin Lubick9fe83912020-11-03 17:08:34 -0500860 };
Kevin Lubick359a7e32019-03-19 09:34:37 -0400861
Kevin Lubick52379332020-01-27 10:01:25 -0500862 // drawOnce will dispose of the surface after drawing the frame using the provided
863 // callback.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400864 CanvasKit.Surface.prototype.drawOnce = function(callback, dirtyRect) {
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800865 if (!this._cached_canvas) {
866 this._cached_canvas = this.getCanvas();
867 }
Elliot Evans1ec3b1a2020-07-23 10:25:58 -0400868 requestAnimationFrame(function() {
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800869 if (this._context !== undefined) {
870 CanvasKit.setCurrentContext(this._context);
871 }
872 callback(this._cached_canvas);
873
Bryce Thomas9331ca02020-05-29 16:51:21 -0700874 this.flush(dirtyRect);
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800875 this.dispose();
876 }.bind(this));
Kevin Lubick9fe83912020-11-03 17:08:34 -0500877 };
Bryce Thomas2c5b8562020-01-22 13:49:41 -0800878
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400879 CanvasKit.PathEffect.MakeDash = function(intervals, phase) {
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500880 if (!phase) {
881 phase = 0;
882 }
883 if (!intervals.length || intervals.length % 2 === 1) {
884 throw 'Intervals array must have even length';
885 }
Kevin Lubickbe728012020-09-03 11:57:12 +0000886 var ptr = copy1dArray(intervals, 'HEAPF32');
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400887 var dpe = CanvasKit.PathEffect._MakeDash(ptr, intervals.length, phase);
Kevin Lubickcf118922020-05-28 14:43:38 -0400888 freeArraysThatAreNotMallocedByUsers(ptr, intervals);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500889 return dpe;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500890 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500891
Kevin Lubick421ba882020-10-15 13:07:33 -0400892 CanvasKit.Shader.MakeColor = function(color4f, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500893 colorSpace = colorSpace || null;
Kevin Lubick6aa38692020-06-01 11:25:47 -0400894 var cPtr = copyColorToWasm(color4f);
Kevin Lubick421ba882020-10-15 13:07:33 -0400895 return CanvasKit.Shader._MakeColor(cPtr, colorSpace);
Kevin Lubick9fe83912020-11-03 17:08:34 -0500896 };
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -0400897
Kevin Lubick421ba882020-10-15 13:07:33 -0400898 // TODO(kjlubick) remove deprecated names.
899 CanvasKit.Shader.Blend = CanvasKit.Shader.MakeBlend;
900 CanvasKit.Shader.Color = CanvasKit.Shader.MakeColor;
Kevin Lubick421ba882020-10-15 13:07:33 -0400901
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400902 CanvasKit.Shader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubickb8123cc2020-11-06 13:05:37 -0500903 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400904 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400905 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500906 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400907 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500908
Kevin Lubicked962642021-02-02 08:18:11 -0500909 // Copy start and end to _scratchFourFloatsAPtr.
910 var startEndPts = _scratchFourFloatsA['toTypedArray']();
911 startEndPts.set(start);
912 startEndPts.set(end, 2);
913
914 var lgs = CanvasKit.Shader._MakeLinearGradient(_scratchFourFloatsAPtr, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
Kevin Lubick421ba882020-10-15 13:07:33 -0400915 cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500916
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400917 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400918 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500919 return lgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500920 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500921
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400922 CanvasKit.Shader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500923 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400924 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400925 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500926 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400927 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500928
Kevin Lubicked962642021-02-02 08:18:11 -0500929 var rgs = CanvasKit.Shader._MakeRadialGradient(center[0], center[1], radius, cPtrInfo.colorPtr,
930 cPtrInfo.colorType, posPtr, cPtrInfo.count, mode,
931 flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500932
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400933 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400934 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500935 return rgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500936 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500937
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400938 CanvasKit.Shader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500939 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400940 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400941 var posPtr = copy1dArray(pos, 'HEAPF32');
Dan Field3d44f732020-03-16 09:17:30 -0700942 flags = flags || 0;
943 startAngle = startAngle || 0;
944 endAngle = endAngle || 360;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400945 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Dan Field3d44f732020-03-16 09:17:30 -0700946
Kevin Lubick421ba882020-10-15 13:07:33 -0400947 var sgs = CanvasKit.Shader._MakeSweepGradient(cx, cy, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
948 cPtrInfo.count, mode,
949 startAngle, endAngle, flags,
950 localMatrixPtr, colorSpace);
Dan Field3d44f732020-03-16 09:17:30 -0700951
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400952 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400953 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Dan Field3d44f732020-03-16 09:17:30 -0700954 return sgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500955 };
Dan Field3d44f732020-03-16 09:17:30 -0700956
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400957 CanvasKit.Shader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
Kevin Lubick421ba882020-10-15 13:07:33 -0400958 colors, pos, mode, localMatrix, flags, colorSpace) {
Kevin Lubicked962642021-02-02 08:18:11 -0500959 colorSpace = colorSpace || null;
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400960 var cPtrInfo = copyFlexibleColorArray(colors);
Kevin Lubick421ba882020-10-15 13:07:33 -0400961 var posPtr = copy1dArray(pos, 'HEAPF32');
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500962 flags = flags || 0;
Kevin Lubick6bffe392020-04-02 15:24:15 -0400963 var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500964
Kevin Lubicked962642021-02-02 08:18:11 -0500965 // Copy start and end to _scratchFourFloatsAPtr.
966 var startEndPts = _scratchFourFloatsA['toTypedArray']();
967 startEndPts.set(start);
968 startEndPts.set(end, 2);
969
970 var rgs = CanvasKit.Shader._MakeTwoPointConicalGradient(_scratchFourFloatsAPtr,
971 startRadius, endRadius, cPtrInfo.colorPtr, cPtrInfo.colorType,
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400972 posPtr, cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500973
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -0400974 freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
Kevin Lubicke7b329e2020-06-05 15:58:01 -0400975 pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500976 return rgs;
Kevin Lubick9fe83912020-11-03 17:08:34 -0500977 };
Nathaniel Nifong23b0ed92020-03-04 15:43:50 -0500978
Kevin Lubickf8823b52020-09-03 10:02:10 -0400979 // Clients can pass in a Float32Array with length 4 to this and the results
980 // will be copied into that array. Otherwise, a new TypedArray will be allocated
981 // and returned.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -0400982 CanvasKit.Vertices.prototype.bounds = function(optionalOutputArray) {
Kevin Lubicked962642021-02-02 08:18:11 -0500983 this._bounds(_scratchFourFloatsAPtr);
984 var ta = _scratchFourFloatsA['toTypedArray']();
Kevin Lubickf8823b52020-09-03 10:02:10 -0400985 if (optionalOutputArray) {
986 optionalOutputArray.set(ta);
987 return optionalOutputArray;
988 }
989 return ta.slice();
Kevin Lubick9fe83912020-11-03 17:08:34 -0500990 };
Kevin Lubickf8823b52020-09-03 10:02:10 -0400991
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500992 // Run through the JS files that are added at compile time.
993 if (CanvasKit._extraInitializations) {
994 CanvasKit._extraInitializations.forEach(function(init) {
995 init();
996 });
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500997 }
Kevin Lubickf5ea37f2019-02-28 10:06:18 -0500998}; // end CanvasKit.onRuntimeInitialized, that is, anything changing prototypes or dynamic.
Kevin Lubickeb2f6b02018-11-29 15:07:02 -0500999
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001000// Accepts an object holding two canvaskit colors.
1001// {
Kevin Lubick3d00e3a2020-10-02 14:59:28 -04001002// ambient: [r, g, b, a],
1003// spot: [r, g, b, a],
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001004// }
Kevin Lubicke7b329e2020-06-05 15:58:01 -04001005// Returns the same format. Note, if malloced colors are passed in, the memory
1006// housing the passed in colors passed in will be overwritten with the computed
1007// tonal colors.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001008CanvasKit.computeTonalColors = function(tonalColors) {
Kevin Lubicke7b329e2020-06-05 15:58:01 -04001009 // copy the colors into WASM
Kevin Lubick6aa38692020-06-01 11:25:47 -04001010 var cPtrAmbi = copyColorToWasmNoScratch(tonalColors['ambient']);
1011 var cPtrSpot = copyColorToWasmNoScratch(tonalColors['spot']);
Kevin Lubicke7b329e2020-06-05 15:58:01 -04001012 // The output of this function will be the same pointers we passed in.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001013 this._computeTonalColors(cPtrAmbi, cPtrSpot);
Kevin Lubicke7b329e2020-06-05 15:58:01 -04001014 // Read the results out.
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001015 var result = {
1016 'ambient': copyColorFromWasm(cPtrAmbi),
1017 'spot': copyColorFromWasm(cPtrSpot),
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -04001018 };
Kevin Lubicke7b329e2020-06-05 15:58:01 -04001019 // If the user passed us malloced colors in here, we don't want to clean them up.
1020 freeArraysThatAreNotMallocedByUsers(cPtrAmbi, tonalColors['ambient']);
1021 freeArraysThatAreNotMallocedByUsers(cPtrSpot, tonalColors['spot']);
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001022 return result;
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -04001023};
Nathaniel Nifong1bedbeb2020-05-04 16:46:17 -04001024
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001025CanvasKit.LTRBRect = function(l, t, r, b) {
Kevin Lubickf8823b52020-09-03 10:02:10 -04001026 return Float32Array.of(l, t, r, b);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -04001027};
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001028
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001029CanvasKit.XYWHRect = function(x, y, w, h) {
Kevin Lubickf8823b52020-09-03 10:02:10 -04001030 return Float32Array.of(x, y, x+w, y+h);
1031};
1032
1033CanvasKit.LTRBiRect = function(l, t, r, b) {
1034 return Int32Array.of(l, t, r, b);
1035};
1036
1037CanvasKit.XYWHiRect = function(x, y, w, h) {
1038 return Int32Array.of(x, y, x+w, y+h);
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -04001039};
Kevin Lubick1a05fce2018-11-20 12:51:16 -05001040
Kevin Lubickbe728012020-09-03 11:57:12 +00001041// RRectXY returns a TypedArray representing an RRect with the given rect and a radiusX and
1042// radiusY for all 4 corners.
Kevin Lubick7d644e12019-09-11 14:22:22 -04001043CanvasKit.RRectXY = function(rect, rx, ry) {
Kevin Lubickbe728012020-09-03 11:57:12 +00001044 return Float32Array.of(
Kevin Lubickf8823b52020-09-03 10:02:10 -04001045 rect[0], rect[1], rect[2], rect[3],
Kevin Lubickbe728012020-09-03 11:57:12 +00001046 rx, ry,
1047 rx, ry,
1048 rx, ry,
1049 rx, ry,
1050 );
Kevin Lubickd9b9e5e2020-06-23 16:58:10 -04001051};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001052
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001053// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer())
Kevin Lubick6b921b72019-09-18 16:18:17 -04001054CanvasKit.MakeAnimatedImageFromEncoded = function(data) {
1055 data = new Uint8Array(data);
1056
1057 var iptr = CanvasKit._malloc(data.byteLength);
1058 CanvasKit.HEAPU8.set(data, iptr);
1059 var img = CanvasKit._decodeAnimatedImage(iptr, data.byteLength);
1060 if (!img) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001061 Debug('Could not decode animated image');
Kevin Lubick6b921b72019-09-18 16:18:17 -04001062 return null;
1063 }
1064 return img;
Kevin Lubick9fe83912020-11-03 17:08:34 -05001065};
Kevin Lubick6b921b72019-09-18 16:18:17 -04001066
1067// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer())
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001068CanvasKit.MakeImageFromEncoded = function(data) {
1069 data = new Uint8Array(data);
1070
1071 var iptr = CanvasKit._malloc(data.byteLength);
1072 CanvasKit.HEAPU8.set(data, iptr);
1073 var img = CanvasKit._decodeImage(iptr, data.byteLength);
1074 if (!img) {
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001075 Debug('Could not decode image');
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001076 return null;
1077 }
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001078 return img;
Kevin Lubick9fe83912020-11-03 17:08:34 -05001079};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001080
Elliot Evans28796192020-06-15 12:53:27 -06001081// A variable to hold a canvasElement which can be reused once created the first time.
1082var memoizedCanvas2dElement = null;
1083
1084// Alternative to CanvasKit.MakeImageFromEncoded. Allows for CanvasKit users to take advantage of
1085// browser APIs to decode images instead of using codecs included in the CanvasKit wasm binary.
1086// Expects that the canvasImageSource has already loaded/decoded.
1087// CanvasImageSource reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource
1088CanvasKit.MakeImageFromCanvasImageSource = function(canvasImageSource) {
1089 var width = canvasImageSource.width;
1090 var height = canvasImageSource.height;
1091
1092 if (!memoizedCanvas2dElement) {
1093 memoizedCanvas2dElement = document.createElement('canvas');
1094 }
1095 memoizedCanvas2dElement.width = width;
1096 memoizedCanvas2dElement.height = height;
1097
1098 var ctx2d = memoizedCanvas2dElement.getContext('2d');
1099 ctx2d.drawImage(canvasImageSource, 0, 0);
1100
1101 var imageData = ctx2d.getImageData(0, 0, width, height);
1102
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001103 return CanvasKit.MakeImage({
1104 'width': width,
1105 'height': height,
1106 'alphaType': CanvasKit.AlphaType.Unpremul,
1107 'colorType': CanvasKit.ColorType.RGBA_8888,
1108 'colorSpace': CanvasKit.ColorSpace.SRGB
1109 }, imageData.data, 4 * width);
Kevin Lubick9fe83912020-11-03 17:08:34 -05001110};
Elliot Evans28796192020-06-15 12:53:27 -06001111
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001112// pixels may be an array but Uint8Array or Uint8ClampedArray is recommended,
1113// with the bytes representing the pixel values.
Kevin Lubickeda0b432019-12-02 08:26:48 -05001114// (e.g. each set of 4 bytes could represent RGBA values for a single pixel).
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001115CanvasKit.MakeImage = function(info, pixels, bytesPerRow) {
1116 var pptr = CanvasKit._malloc(pixels.length);
1117 CanvasKit.HEAPU8.set(pixels, pptr); // We always want to copy the bytes into the WASM heap.
Kevin Lubickeda0b432019-12-02 08:26:48 -05001118 // No need to _free pptr, Image takes it with SkData::MakeFromMalloc
Kevin Lubickae0d3ff2020-11-18 11:23:15 -05001119 return CanvasKit._MakeImage(info, pptr, pixels.length, bytesPerRow);
Kevin Lubick9fe83912020-11-03 17:08:34 -05001120};
Kevin Lubickf5ea37f2019-02-28 10:06:18 -05001121
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001122// Colors may be a Uint32Array of int colors, a Flat Float32Array of float colors
1123// or a 2d Array of Float32Array(4) (deprecated)
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001124// the underlying Skia function accepts only int colors so it is recommended
Nathaniel Nifongd05fd0c2020-06-11 08:44:20 -04001125// to pass an array of int colors to avoid an extra conversion.
Kevin Lubick54c1b3d2020-10-07 16:09:22 -04001126CanvasKit.MakeVertices = function(mode, positions, textureCoordinates, colors,
1127 indices, isVolatile) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001128 // Default isVolatile to true if not set
Kevin Lubickb3574c92019-03-06 08:25:36 -05001129 isVolatile = isVolatile === undefined ? true : isVolatile;
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001130 var idxCount = (indices && indices.length) || 0;
1131
1132 var flags = 0;
1133 // These flags are from SkVertices.h and should be kept in sync with those.
1134 if (textureCoordinates && textureCoordinates.length) {
1135 flags |= (1 << 0);
1136 }
1137 if (colors && colors.length) {
1138 flags |= (1 << 1);
1139 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001140 if (!isVolatile) {
Mike Reed5caf9352020-03-02 14:57:09 -05001141 flags |= (1 << 2);
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001142 }
1143
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001144 var builder = new CanvasKit._VerticesBuilder(mode, positions.length / 2, idxCount, flags);
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001145
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001146 copy1dArray(positions, 'HEAPF32', builder.positions());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001147 if (builder.texCoords()) {
Kevin Lubicke7c1a732020-12-04 09:10:39 -05001148 copy1dArray(textureCoordinates, 'HEAPF32', builder.texCoords());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001149 }
1150 if (builder.colors()) {
Kevin Lubickbe728012020-09-03 11:57:12 +00001151 copy1dArray(assureIntColors(colors), 'HEAPU32', builder.colors());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001152 }
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001153 if (builder.indices()) {
Kevin Lubickbe728012020-09-03 11:57:12 +00001154 copy1dArray(indices, 'HEAPU16', builder.indices());
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001155 }
Kevin Lubickb3574c92019-03-06 08:25:36 -05001156
Kevin Lubickd6ba7252019-06-03 14:38:05 -04001157 // Create the vertices, which owns the memory that the builder had allocated.
1158 return builder.detach();
Kevin Lubicka4f218d2020-01-14 08:39:09 -05001159};