1*c8dee2aaSAndroid Build Coastguard Worker// Adds JS functions to augment the CanvasKit interface. 2*c8dee2aaSAndroid Build Coastguard Worker// For example, if there is a wrapper around the C++ call or logic to allow 3*c8dee2aaSAndroid Build Coastguard Worker// chaining, it should go here. 4*c8dee2aaSAndroid Build Coastguard Worker 5*c8dee2aaSAndroid Build Coastguard Worker// CanvasKit.onRuntimeInitialized is called after the WASM library has loaded. 6*c8dee2aaSAndroid Build Coastguard Worker// Anything that modifies an exposed class (e.g. Path) should be set 7*c8dee2aaSAndroid Build Coastguard Worker// after onRuntimeInitialized, otherwise, it can happen outside of that scope. 8*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.onRuntimeInitialized = function() { 9*c8dee2aaSAndroid Build Coastguard Worker // All calls to 'this' need to go in externs.js so closure doesn't minify them away. 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker _scratchColor = CanvasKit.Malloc(Float32Array, 4); // 4 color scalars. 12*c8dee2aaSAndroid Build Coastguard Worker _scratchColorPtr = _scratchColor['byteOffset']; 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker _scratch4x4Matrix = CanvasKit.Malloc(Float32Array, 16); // 16 matrix scalars. 15*c8dee2aaSAndroid Build Coastguard Worker _scratch4x4MatrixPtr = _scratch4x4Matrix['byteOffset']; 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker _scratch3x3Matrix = CanvasKit.Malloc(Float32Array, 9); // 9 matrix scalars. 18*c8dee2aaSAndroid Build Coastguard Worker _scratch3x3MatrixPtr = _scratch3x3Matrix['byteOffset']; 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker _scratchRRect = CanvasKit.Malloc(Float32Array, 12); // 4 scalars for rrect, 8 for radii. 21*c8dee2aaSAndroid Build Coastguard Worker _scratchRRectPtr = _scratchRRect['byteOffset']; 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker _scratchRRect2 = CanvasKit.Malloc(Float32Array, 12); // 4 scalars for rrect, 8 for radii. 24*c8dee2aaSAndroid Build Coastguard Worker _scratchRRect2Ptr = _scratchRRect2['byteOffset']; 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker _scratchFourFloatsA = CanvasKit.Malloc(Float32Array, 4); 27*c8dee2aaSAndroid Build Coastguard Worker _scratchFourFloatsAPtr = _scratchFourFloatsA['byteOffset']; 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker _scratchFourFloatsB = CanvasKit.Malloc(Float32Array, 4); 30*c8dee2aaSAndroid Build Coastguard Worker _scratchFourFloatsBPtr = _scratchFourFloatsB['byteOffset']; 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker _scratchThreeFloatsA = CanvasKit.Malloc(Float32Array, 3); // 3 floats to represent SkVector3 33*c8dee2aaSAndroid Build Coastguard Worker _scratchThreeFloatsAPtr = _scratchThreeFloatsA['byteOffset']; 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker _scratchThreeFloatsB = CanvasKit.Malloc(Float32Array, 3); // 3 floats to represent SkVector3 36*c8dee2aaSAndroid Build Coastguard Worker _scratchThreeFloatsBPtr = _scratchThreeFloatsB['byteOffset']; 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker _scratchIRect = CanvasKit.Malloc(Int32Array, 4); 39*c8dee2aaSAndroid Build Coastguard Worker _scratchIRectPtr = _scratchIRect['byteOffset']; 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker // Create single copies of all three supported color spaces 42*c8dee2aaSAndroid Build Coastguard Worker // These are sk_sp<ColorSpace> 43*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ColorSpace.SRGB = CanvasKit.ColorSpace._MakeSRGB(); 44*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ColorSpace.DISPLAY_P3 = CanvasKit.ColorSpace._MakeDisplayP3(); 45*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ColorSpace.ADOBE_RGB = CanvasKit.ColorSpace._MakeAdobeRGB(); 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker // Use quotes to tell closure compiler not to minify the names 48*c8dee2aaSAndroid Build Coastguard Worker CanvasKit['GlyphRunFlags'] = { 49*c8dee2aaSAndroid Build Coastguard Worker 'IsWhiteSpace': CanvasKit['_GlyphRunFlags_isWhiteSpace'], 50*c8dee2aaSAndroid Build Coastguard Worker }; 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.MakeFromCmds = function(cmds) { 53*c8dee2aaSAndroid Build Coastguard Worker var cmdPtr = copy1dArray(cmds, 'HEAPF32'); 54*c8dee2aaSAndroid Build Coastguard Worker var path = CanvasKit.Path._MakeFromCmds(cmdPtr, cmds.length); 55*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cmdPtr, cmds); 56*c8dee2aaSAndroid Build Coastguard Worker return path; 57*c8dee2aaSAndroid Build Coastguard Worker }; 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker // The weights array is optional (only used for conics). 60*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.MakeFromVerbsPointsWeights = function(verbs, pts, weights) { 61*c8dee2aaSAndroid Build Coastguard Worker var verbsPtr = copy1dArray(verbs, 'HEAPU8'); 62*c8dee2aaSAndroid Build Coastguard Worker var pointsPtr = copy1dArray(pts, 'HEAPF32'); 63*c8dee2aaSAndroid Build Coastguard Worker var weightsPtr = copy1dArray(weights, 'HEAPF32'); 64*c8dee2aaSAndroid Build Coastguard Worker var numWeights = (weights && weights.length) || 0; 65*c8dee2aaSAndroid Build Coastguard Worker var path = CanvasKit.Path._MakeFromVerbsPointsWeights( 66*c8dee2aaSAndroid Build Coastguard Worker verbsPtr, verbs.length, pointsPtr, pts.length, weightsPtr, numWeights); 67*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(verbsPtr, verbs); 68*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(pointsPtr, pts); 69*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(weightsPtr, weights); 70*c8dee2aaSAndroid Build Coastguard Worker return path; 71*c8dee2aaSAndroid Build Coastguard Worker }; 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addArc = function(oval, startAngle, sweepAngle) { 74*c8dee2aaSAndroid Build Coastguard Worker // see arc() for the HTMLCanvas version 75*c8dee2aaSAndroid Build Coastguard Worker // note input angles are degrees. 76*c8dee2aaSAndroid Build Coastguard Worker var oPtr = copyRectToWasm(oval); 77*c8dee2aaSAndroid Build Coastguard Worker this._addArc(oPtr, startAngle, sweepAngle); 78*c8dee2aaSAndroid Build Coastguard Worker return this; 79*c8dee2aaSAndroid Build Coastguard Worker }; 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addCircle = function(x, y, r, isCCW) { 82*c8dee2aaSAndroid Build Coastguard Worker this._addCircle(x, y, r, !!isCCW); 83*c8dee2aaSAndroid Build Coastguard Worker return this; 84*c8dee2aaSAndroid Build Coastguard Worker }; 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addOval = function(oval, isCCW, startIndex) { 87*c8dee2aaSAndroid Build Coastguard Worker if (startIndex === undefined) { 88*c8dee2aaSAndroid Build Coastguard Worker startIndex = 1; 89*c8dee2aaSAndroid Build Coastguard Worker } 90*c8dee2aaSAndroid Build Coastguard Worker var oPtr = copyRectToWasm(oval); 91*c8dee2aaSAndroid Build Coastguard Worker this._addOval(oPtr, !!isCCW, startIndex); 92*c8dee2aaSAndroid Build Coastguard Worker return this; 93*c8dee2aaSAndroid Build Coastguard Worker }; 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker // TODO(kjlubick) clean up this API - split it apart if necessary 96*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addPath = function() { 97*c8dee2aaSAndroid Build Coastguard Worker // Takes 1, 2, 7, or 10 required args, where the first arg is always the path. 98*c8dee2aaSAndroid Build Coastguard Worker // The last arg is optional and chooses between add or extend mode. 99*c8dee2aaSAndroid Build Coastguard Worker // The options for the remaining args are: 100*c8dee2aaSAndroid Build Coastguard Worker // - an array of 6 or 9 parameters (perspective is optional) 101*c8dee2aaSAndroid Build Coastguard Worker // - the 9 parameters of a full matrix or 102*c8dee2aaSAndroid Build Coastguard Worker // the 6 non-perspective params of a matrix. 103*c8dee2aaSAndroid Build Coastguard Worker var args = Array.prototype.slice.call(arguments); 104*c8dee2aaSAndroid Build Coastguard Worker var path = args[0]; 105*c8dee2aaSAndroid Build Coastguard Worker var extend = false; 106*c8dee2aaSAndroid Build Coastguard Worker if (typeof args[args.length-1] === 'boolean') { 107*c8dee2aaSAndroid Build Coastguard Worker extend = args.pop(); 108*c8dee2aaSAndroid Build Coastguard Worker } 109*c8dee2aaSAndroid Build Coastguard Worker if (args.length === 1) { 110*c8dee2aaSAndroid Build Coastguard Worker // Add path, unchanged. Use identity matrix 111*c8dee2aaSAndroid Build Coastguard Worker this._addPath(path, 1, 0, 0, 112*c8dee2aaSAndroid Build Coastguard Worker 0, 1, 0, 113*c8dee2aaSAndroid Build Coastguard Worker 0, 0, 1, 114*c8dee2aaSAndroid Build Coastguard Worker extend); 115*c8dee2aaSAndroid Build Coastguard Worker } else if (args.length === 2) { 116*c8dee2aaSAndroid Build Coastguard Worker // User provided the 9 params of a full matrix as an array. 117*c8dee2aaSAndroid Build Coastguard Worker var a = args[1]; 118*c8dee2aaSAndroid Build Coastguard Worker this._addPath(path, a[0], a[1], a[2], 119*c8dee2aaSAndroid Build Coastguard Worker a[3], a[4], a[5], 120*c8dee2aaSAndroid Build Coastguard Worker a[6] || 0, a[7] || 0, a[8] || 1, 121*c8dee2aaSAndroid Build Coastguard Worker extend); 122*c8dee2aaSAndroid Build Coastguard Worker } else if (args.length === 7 || args.length === 10) { 123*c8dee2aaSAndroid Build Coastguard Worker // User provided the 9 params of a (full) matrix directly. 124*c8dee2aaSAndroid Build Coastguard Worker // (or just the 6 non perspective ones) 125*c8dee2aaSAndroid Build Coastguard Worker // These are in the same order as what Skia expects. 126*c8dee2aaSAndroid Build Coastguard Worker var a = args; 127*c8dee2aaSAndroid Build Coastguard Worker this._addPath(path, a[1], a[2], a[3], 128*c8dee2aaSAndroid Build Coastguard Worker a[4], a[5], a[6], 129*c8dee2aaSAndroid Build Coastguard Worker a[7] || 0, a[8] || 0, a[9] || 1, 130*c8dee2aaSAndroid Build Coastguard Worker extend); 131*c8dee2aaSAndroid Build Coastguard Worker } else { 132*c8dee2aaSAndroid Build Coastguard Worker Debug('addPath expected to take 1, 2, 7, or 10 required args. Got ' + args.length); 133*c8dee2aaSAndroid Build Coastguard Worker return null; 134*c8dee2aaSAndroid Build Coastguard Worker } 135*c8dee2aaSAndroid Build Coastguard Worker return this; 136*c8dee2aaSAndroid Build Coastguard Worker }; 137*c8dee2aaSAndroid Build Coastguard Worker 138*c8dee2aaSAndroid Build Coastguard Worker // points is a 1d array of length 2n representing n points where the even indices 139*c8dee2aaSAndroid Build Coastguard Worker // will be treated as x coordinates and the odd indices will be treated as y coordinates. 140*c8dee2aaSAndroid Build Coastguard Worker // Like other APIs, this accepts a malloced type array or malloc obj. 141*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addPoly = function(points, close) { 142*c8dee2aaSAndroid Build Coastguard Worker var ptr = copy1dArray(points, 'HEAPF32'); 143*c8dee2aaSAndroid Build Coastguard Worker this._addPoly(ptr, points.length / 2, close); 144*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(ptr, points); 145*c8dee2aaSAndroid Build Coastguard Worker return this; 146*c8dee2aaSAndroid Build Coastguard Worker }; 147*c8dee2aaSAndroid Build Coastguard Worker 148*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addRect = function(rect, isCCW) { 149*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRectToWasm(rect); 150*c8dee2aaSAndroid Build Coastguard Worker this._addRect(rPtr, !!isCCW); 151*c8dee2aaSAndroid Build Coastguard Worker return this; 152*c8dee2aaSAndroid Build Coastguard Worker }; 153*c8dee2aaSAndroid Build Coastguard Worker 154*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addRRect = function(rrect, isCCW) { 155*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRRectToWasm(rrect); 156*c8dee2aaSAndroid Build Coastguard Worker this._addRRect(rPtr, !!isCCW); 157*c8dee2aaSAndroid Build Coastguard Worker return this; 158*c8dee2aaSAndroid Build Coastguard Worker }; 159*c8dee2aaSAndroid Build Coastguard Worker 160*c8dee2aaSAndroid Build Coastguard Worker // The weights array is optional (only used for conics). 161*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.addVerbsPointsWeights = function(verbs, points, weights) { 162*c8dee2aaSAndroid Build Coastguard Worker var verbsPtr = copy1dArray(verbs, 'HEAPU8'); 163*c8dee2aaSAndroid Build Coastguard Worker var pointsPtr = copy1dArray(points, 'HEAPF32'); 164*c8dee2aaSAndroid Build Coastguard Worker var weightsPtr = copy1dArray(weights, 'HEAPF32'); 165*c8dee2aaSAndroid Build Coastguard Worker var numWeights = (weights && weights.length) || 0; 166*c8dee2aaSAndroid Build Coastguard Worker this._addVerbsPointsWeights(verbsPtr, verbs.length, pointsPtr, points.length, 167*c8dee2aaSAndroid Build Coastguard Worker weightsPtr, numWeights); 168*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(verbsPtr, verbs); 169*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(pointsPtr, points); 170*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(weightsPtr, weights); 171*c8dee2aaSAndroid Build Coastguard Worker }; 172*c8dee2aaSAndroid Build Coastguard Worker 173*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.arc = function(x, y, radius, startAngle, endAngle, ccw) { 174*c8dee2aaSAndroid Build Coastguard Worker // emulates the HTMLCanvas behavior. See addArc() for the Path version. 175*c8dee2aaSAndroid Build Coastguard Worker // Note input angles are radians. 176*c8dee2aaSAndroid Build Coastguard Worker var bounds = CanvasKit.LTRBRect(x-radius, y-radius, x+radius, y+radius); 177*c8dee2aaSAndroid Build Coastguard Worker var sweep = radiansToDegrees(endAngle - startAngle) - (360 * !!ccw); 178*c8dee2aaSAndroid Build Coastguard Worker var temp = new CanvasKit.Path(); 179*c8dee2aaSAndroid Build Coastguard Worker temp.addArc(bounds, radiansToDegrees(startAngle), sweep); 180*c8dee2aaSAndroid Build Coastguard Worker this.addPath(temp, true); 181*c8dee2aaSAndroid Build Coastguard Worker temp.delete(); 182*c8dee2aaSAndroid Build Coastguard Worker return this; 183*c8dee2aaSAndroid Build Coastguard Worker }; 184*c8dee2aaSAndroid Build Coastguard Worker 185*c8dee2aaSAndroid Build Coastguard Worker // Appends arc to Path. Arc added is part of ellipse 186*c8dee2aaSAndroid Build Coastguard Worker // bounded by oval, from startAngle through sweepAngle. Both startAngle and 187*c8dee2aaSAndroid Build Coastguard Worker // sweepAngle are measured in degrees, where zero degrees is aligned with the 188*c8dee2aaSAndroid Build Coastguard Worker // positive x-axis, and positive sweeps extends arc clockwise. 189*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.arcToOval = function(oval, startAngle, sweepAngle, forceMoveTo) { 190*c8dee2aaSAndroid Build Coastguard Worker var oPtr = copyRectToWasm(oval); 191*c8dee2aaSAndroid Build Coastguard Worker this._arcToOval(oPtr, startAngle, sweepAngle, forceMoveTo); 192*c8dee2aaSAndroid Build Coastguard Worker return this; 193*c8dee2aaSAndroid Build Coastguard Worker }; 194*c8dee2aaSAndroid Build Coastguard Worker 195*c8dee2aaSAndroid Build Coastguard Worker // Appends arc to Path. Arc is implemented by one or more conics weighted to 196*c8dee2aaSAndroid Build Coastguard Worker // describe part of oval with radii (rx, ry) rotated by xAxisRotate degrees. Arc 197*c8dee2aaSAndroid Build Coastguard Worker // curves from last point to (x, y), choosing one of four possible routes: 198*c8dee2aaSAndroid Build Coastguard Worker // clockwise or counterclockwise, and smaller or larger. 199*c8dee2aaSAndroid Build Coastguard Worker 200*c8dee2aaSAndroid Build Coastguard Worker // Arc sweep is always less than 360 degrees. arcTo() appends line to (x, y) if 201*c8dee2aaSAndroid Build Coastguard Worker // either radii are zero, or if last point equals (x, y). arcTo() scales radii 202*c8dee2aaSAndroid Build Coastguard Worker // (rx, ry) to fit last point and (x, y) if both are greater than zero but 203*c8dee2aaSAndroid Build Coastguard Worker // too small. 204*c8dee2aaSAndroid Build Coastguard Worker 205*c8dee2aaSAndroid Build Coastguard Worker // arcToRotated() appends up to four conic curves. 206*c8dee2aaSAndroid Build Coastguard Worker // arcToRotated() implements the functionality of SVG arc, although SVG sweep-flag value 207*c8dee2aaSAndroid Build Coastguard Worker // is opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise, 208*c8dee2aaSAndroid Build Coastguard Worker // while kCW_Direction cast to int is zero. 209*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.arcToRotated = function(rx, ry, xAxisRotate, useSmallArc, isCCW, x, y) { 210*c8dee2aaSAndroid Build Coastguard Worker this._arcToRotated(rx, ry, xAxisRotate, !!useSmallArc, !!isCCW, x, y); 211*c8dee2aaSAndroid Build Coastguard Worker return this; 212*c8dee2aaSAndroid Build Coastguard Worker }; 213*c8dee2aaSAndroid Build Coastguard Worker 214*c8dee2aaSAndroid Build Coastguard Worker // Appends arc to Path, after appending line if needed. Arc is implemented by conic 215*c8dee2aaSAndroid Build Coastguard Worker // weighted to describe part of circle. Arc is contained by tangent from 216*c8dee2aaSAndroid Build Coastguard Worker // last Path point to (x1, y1), and tangent from (x1, y1) to (x2, y2). Arc 217*c8dee2aaSAndroid Build Coastguard Worker // is part of circle sized to radius, positioned so it touches both tangent lines. 218*c8dee2aaSAndroid Build Coastguard Worker 219*c8dee2aaSAndroid Build Coastguard Worker // If last Path Point does not start Arc, arcTo appends connecting Line to Path. 220*c8dee2aaSAndroid Build Coastguard Worker // The length of Vector from (x1, y1) to (x2, y2) does not affect Arc. 221*c8dee2aaSAndroid Build Coastguard Worker 222*c8dee2aaSAndroid Build Coastguard Worker // Arc sweep is always less than 180 degrees. If radius is zero, or if 223*c8dee2aaSAndroid Build Coastguard Worker // tangents are nearly parallel, arcTo appends Line from last Path Point to (x1, y1). 224*c8dee2aaSAndroid Build Coastguard Worker 225*c8dee2aaSAndroid Build Coastguard Worker // arcToTangent appends at most one Line and one conic. 226*c8dee2aaSAndroid Build Coastguard Worker // arcToTangent implements the functionality of PostScript arct and HTML Canvas arcTo. 227*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.arcToTangent = function(x1, y1, x2, y2, radius) { 228*c8dee2aaSAndroid Build Coastguard Worker this._arcToTangent(x1, y1, x2, y2, radius); 229*c8dee2aaSAndroid Build Coastguard Worker return this; 230*c8dee2aaSAndroid Build Coastguard Worker }; 231*c8dee2aaSAndroid Build Coastguard Worker 232*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.close = function() { 233*c8dee2aaSAndroid Build Coastguard Worker this._close(); 234*c8dee2aaSAndroid Build Coastguard Worker return this; 235*c8dee2aaSAndroid Build Coastguard Worker }; 236*c8dee2aaSAndroid Build Coastguard Worker 237*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.conicTo = function(x1, y1, x2, y2, w) { 238*c8dee2aaSAndroid Build Coastguard Worker this._conicTo(x1, y1, x2, y2, w); 239*c8dee2aaSAndroid Build Coastguard Worker return this; 240*c8dee2aaSAndroid Build Coastguard Worker }; 241*c8dee2aaSAndroid Build Coastguard Worker 242*c8dee2aaSAndroid Build Coastguard Worker // Clients can pass in a Float32Array with length 4 to this and the results 243*c8dee2aaSAndroid Build Coastguard Worker // will be copied into that array. Otherwise, a new TypedArray will be allocated 244*c8dee2aaSAndroid Build Coastguard Worker // and returned. 245*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.computeTightBounds = function(optionalOutputArray) { 246*c8dee2aaSAndroid Build Coastguard Worker this._computeTightBounds(_scratchFourFloatsAPtr); 247*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 248*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutputArray) { 249*c8dee2aaSAndroid Build Coastguard Worker optionalOutputArray.set(ta); 250*c8dee2aaSAndroid Build Coastguard Worker return optionalOutputArray; 251*c8dee2aaSAndroid Build Coastguard Worker } 252*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 253*c8dee2aaSAndroid Build Coastguard Worker }; 254*c8dee2aaSAndroid Build Coastguard Worker 255*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.cubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) { 256*c8dee2aaSAndroid Build Coastguard Worker this._cubicTo(cp1x, cp1y, cp2x, cp2y, x, y); 257*c8dee2aaSAndroid Build Coastguard Worker return this; 258*c8dee2aaSAndroid Build Coastguard Worker }; 259*c8dee2aaSAndroid Build Coastguard Worker 260*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.dash = function(on, off, phase) { 261*c8dee2aaSAndroid Build Coastguard Worker if (this._dash(on, off, phase)) { 262*c8dee2aaSAndroid Build Coastguard Worker return this; 263*c8dee2aaSAndroid Build Coastguard Worker } 264*c8dee2aaSAndroid Build Coastguard Worker return null; 265*c8dee2aaSAndroid Build Coastguard Worker }; 266*c8dee2aaSAndroid Build Coastguard Worker 267*c8dee2aaSAndroid Build Coastguard Worker // Clients can pass in a Float32Array with length 4 to this and the results 268*c8dee2aaSAndroid Build Coastguard Worker // will be copied into that array. Otherwise, a new TypedArray will be allocated 269*c8dee2aaSAndroid Build Coastguard Worker // and returned. 270*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.getBounds = function(optionalOutputArray) { 271*c8dee2aaSAndroid Build Coastguard Worker this._getBounds(_scratchFourFloatsAPtr); 272*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 273*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutputArray) { 274*c8dee2aaSAndroid Build Coastguard Worker optionalOutputArray.set(ta); 275*c8dee2aaSAndroid Build Coastguard Worker return optionalOutputArray; 276*c8dee2aaSAndroid Build Coastguard Worker } 277*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 278*c8dee2aaSAndroid Build Coastguard Worker }; 279*c8dee2aaSAndroid Build Coastguard Worker 280*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.lineTo = function(x, y) { 281*c8dee2aaSAndroid Build Coastguard Worker this._lineTo(x, y); 282*c8dee2aaSAndroid Build Coastguard Worker return this; 283*c8dee2aaSAndroid Build Coastguard Worker }; 284*c8dee2aaSAndroid Build Coastguard Worker 285*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.moveTo = function(x, y) { 286*c8dee2aaSAndroid Build Coastguard Worker this._moveTo(x, y); 287*c8dee2aaSAndroid Build Coastguard Worker return this; 288*c8dee2aaSAndroid Build Coastguard Worker }; 289*c8dee2aaSAndroid Build Coastguard Worker 290*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.offset = function(dx, dy) { 291*c8dee2aaSAndroid Build Coastguard Worker this._transform(1, 0, dx, 292*c8dee2aaSAndroid Build Coastguard Worker 0, 1, dy, 293*c8dee2aaSAndroid Build Coastguard Worker 0, 0, 1); 294*c8dee2aaSAndroid Build Coastguard Worker return this; 295*c8dee2aaSAndroid Build Coastguard Worker }; 296*c8dee2aaSAndroid Build Coastguard Worker 297*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.quadTo = function(cpx, cpy, x, y) { 298*c8dee2aaSAndroid Build Coastguard Worker this._quadTo(cpx, cpy, x, y); 299*c8dee2aaSAndroid Build Coastguard Worker return this; 300*c8dee2aaSAndroid Build Coastguard Worker }; 301*c8dee2aaSAndroid Build Coastguard Worker 302*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.rArcTo = function(rx, ry, xAxisRotate, useSmallArc, isCCW, dx, dy) { 303*c8dee2aaSAndroid Build Coastguard Worker this._rArcTo(rx, ry, xAxisRotate, useSmallArc, isCCW, dx, dy); 304*c8dee2aaSAndroid Build Coastguard Worker return this; 305*c8dee2aaSAndroid Build Coastguard Worker }; 306*c8dee2aaSAndroid Build Coastguard Worker 307*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.rConicTo = function(dx1, dy1, dx2, dy2, w) { 308*c8dee2aaSAndroid Build Coastguard Worker this._rConicTo(dx1, dy1, dx2, dy2, w); 309*c8dee2aaSAndroid Build Coastguard Worker return this; 310*c8dee2aaSAndroid Build Coastguard Worker }; 311*c8dee2aaSAndroid Build Coastguard Worker 312*c8dee2aaSAndroid Build Coastguard Worker // These params are all relative 313*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.rCubicTo = function(cp1x, cp1y, cp2x, cp2y, x, y) { 314*c8dee2aaSAndroid Build Coastguard Worker this._rCubicTo(cp1x, cp1y, cp2x, cp2y, x, y); 315*c8dee2aaSAndroid Build Coastguard Worker return this; 316*c8dee2aaSAndroid Build Coastguard Worker }; 317*c8dee2aaSAndroid Build Coastguard Worker 318*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.rLineTo = function(dx, dy) { 319*c8dee2aaSAndroid Build Coastguard Worker this._rLineTo(dx, dy); 320*c8dee2aaSAndroid Build Coastguard Worker return this; 321*c8dee2aaSAndroid Build Coastguard Worker }; 322*c8dee2aaSAndroid Build Coastguard Worker 323*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.rMoveTo = function(dx, dy) { 324*c8dee2aaSAndroid Build Coastguard Worker this._rMoveTo(dx, dy); 325*c8dee2aaSAndroid Build Coastguard Worker return this; 326*c8dee2aaSAndroid Build Coastguard Worker }; 327*c8dee2aaSAndroid Build Coastguard Worker 328*c8dee2aaSAndroid Build Coastguard Worker // These params are all relative 329*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.rQuadTo = function(cpx, cpy, x, y) { 330*c8dee2aaSAndroid Build Coastguard Worker this._rQuadTo(cpx, cpy, x, y); 331*c8dee2aaSAndroid Build Coastguard Worker return this; 332*c8dee2aaSAndroid Build Coastguard Worker }; 333*c8dee2aaSAndroid Build Coastguard Worker 334*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.stroke = function(opts) { 335*c8dee2aaSAndroid Build Coastguard Worker // Fill out any missing values with the default values. 336*c8dee2aaSAndroid Build Coastguard Worker opts = opts || {}; 337*c8dee2aaSAndroid Build Coastguard Worker opts['width'] = opts['width'] || 1; 338*c8dee2aaSAndroid Build Coastguard Worker opts['miter_limit'] = opts['miter_limit'] || 4; 339*c8dee2aaSAndroid Build Coastguard Worker opts['cap'] = opts['cap'] || CanvasKit.StrokeCap.Butt; 340*c8dee2aaSAndroid Build Coastguard Worker opts['join'] = opts['join'] || CanvasKit.StrokeJoin.Miter; 341*c8dee2aaSAndroid Build Coastguard Worker opts['precision'] = opts['precision'] || 1; 342*c8dee2aaSAndroid Build Coastguard Worker if (this._stroke(opts)) { 343*c8dee2aaSAndroid Build Coastguard Worker return this; 344*c8dee2aaSAndroid Build Coastguard Worker } 345*c8dee2aaSAndroid Build Coastguard Worker return null; 346*c8dee2aaSAndroid Build Coastguard Worker }; 347*c8dee2aaSAndroid Build Coastguard Worker 348*c8dee2aaSAndroid Build Coastguard Worker // TODO(kjlubick) Change this to take a 3x3 or 4x4 matrix (optionally malloc'd) 349*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.transform = function() { 350*c8dee2aaSAndroid Build Coastguard Worker // Takes 1 or 9 args 351*c8dee2aaSAndroid Build Coastguard Worker if (arguments.length === 1) { 352*c8dee2aaSAndroid Build Coastguard Worker // argument 1 should be a 6 or 9 element array. 353*c8dee2aaSAndroid Build Coastguard Worker var a = arguments[0]; 354*c8dee2aaSAndroid Build Coastguard Worker this._transform(a[0], a[1], a[2], 355*c8dee2aaSAndroid Build Coastguard Worker a[3], a[4], a[5], 356*c8dee2aaSAndroid Build Coastguard Worker a[6] || 0, a[7] || 0, a[8] || 1); 357*c8dee2aaSAndroid Build Coastguard Worker } else if (arguments.length === 6 || arguments.length === 9) { 358*c8dee2aaSAndroid Build Coastguard Worker // these arguments are the 6 or 9 members of the matrix 359*c8dee2aaSAndroid Build Coastguard Worker var a = arguments; 360*c8dee2aaSAndroid Build Coastguard Worker this._transform(a[0], a[1], a[2], 361*c8dee2aaSAndroid Build Coastguard Worker a[3], a[4], a[5], 362*c8dee2aaSAndroid Build Coastguard Worker a[6] || 0, a[7] || 0, a[8] || 1); 363*c8dee2aaSAndroid Build Coastguard Worker } else { 364*c8dee2aaSAndroid Build Coastguard Worker throw 'transform expected to take 1 or 9 arguments. Got ' + arguments.length; 365*c8dee2aaSAndroid Build Coastguard Worker } 366*c8dee2aaSAndroid Build Coastguard Worker return this; 367*c8dee2aaSAndroid Build Coastguard Worker }; 368*c8dee2aaSAndroid Build Coastguard Worker 369*c8dee2aaSAndroid Build Coastguard Worker // isComplement is optional, defaults to false 370*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.trim = function(startT, stopT, isComplement) { 371*c8dee2aaSAndroid Build Coastguard Worker if (this._trim(startT, stopT, !!isComplement)) { 372*c8dee2aaSAndroid Build Coastguard Worker return this; 373*c8dee2aaSAndroid Build Coastguard Worker } 374*c8dee2aaSAndroid Build Coastguard Worker return null; 375*c8dee2aaSAndroid Build Coastguard Worker }; 376*c8dee2aaSAndroid Build Coastguard Worker 377*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Image.prototype.encodeToBytes = function(fmt, quality) { 378*c8dee2aaSAndroid Build Coastguard Worker var grCtx = CanvasKit.getCurrentGrDirectContext(); 379*c8dee2aaSAndroid Build Coastguard Worker fmt = fmt || CanvasKit.ImageFormat.PNG; 380*c8dee2aaSAndroid Build Coastguard Worker quality = quality || 100; 381*c8dee2aaSAndroid Build Coastguard Worker if (grCtx) { 382*c8dee2aaSAndroid Build Coastguard Worker return this._encodeToBytes(fmt, quality, grCtx); 383*c8dee2aaSAndroid Build Coastguard Worker } else { 384*c8dee2aaSAndroid Build Coastguard Worker return this._encodeToBytes(fmt, quality); 385*c8dee2aaSAndroid Build Coastguard Worker } 386*c8dee2aaSAndroid Build Coastguard Worker }; 387*c8dee2aaSAndroid Build Coastguard Worker 388*c8dee2aaSAndroid Build Coastguard Worker // makeShaderCubic returns a shader for a given image, allowing it to be used on 389*c8dee2aaSAndroid Build Coastguard Worker // a paint as well as other purposes. This shader will be higher quality than 390*c8dee2aaSAndroid Build Coastguard Worker // other shader functions. See CubicResampler in SkSamplingOptions.h for more information 391*c8dee2aaSAndroid Build Coastguard Worker // on the cubicResampler params. 392*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Image.prototype.makeShaderCubic = function(xTileMode, yTileMode, 393*c8dee2aaSAndroid Build Coastguard Worker cubicResamplerB, cubicResamplerC, 394*c8dee2aaSAndroid Build Coastguard Worker localMatrix) { 395*c8dee2aaSAndroid Build Coastguard Worker var localMatrixPtr = copy3x3MatrixToWasm(localMatrix); 396*c8dee2aaSAndroid Build Coastguard Worker return this._makeShaderCubic(xTileMode, yTileMode, cubicResamplerB, 397*c8dee2aaSAndroid Build Coastguard Worker cubicResamplerC, localMatrixPtr); 398*c8dee2aaSAndroid Build Coastguard Worker }; 399*c8dee2aaSAndroid Build Coastguard Worker 400*c8dee2aaSAndroid Build Coastguard Worker // makeShaderCubic returns a shader for a given image, allowing it to be used on 401*c8dee2aaSAndroid Build Coastguard Worker // a paint as well as other purposes. This shader will draw more quickly than 402*c8dee2aaSAndroid Build Coastguard Worker // other shader functions, but at a lower quality. 403*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Image.prototype.makeShaderOptions = function(xTileMode, yTileMode, 404*c8dee2aaSAndroid Build Coastguard Worker filterMode, mipmapMode, 405*c8dee2aaSAndroid Build Coastguard Worker localMatrix) { 406*c8dee2aaSAndroid Build Coastguard Worker var localMatrixPtr = copy3x3MatrixToWasm(localMatrix); 407*c8dee2aaSAndroid Build Coastguard Worker return this._makeShaderOptions(xTileMode, yTileMode, filterMode, mipmapMode, localMatrixPtr); 408*c8dee2aaSAndroid Build Coastguard Worker }; 409*c8dee2aaSAndroid Build Coastguard Worker 410*c8dee2aaSAndroid Build Coastguard Worker function readPixels(source, srcX, srcY, imageInfo, destMallocObj, bytesPerRow, grCtx) { 411*c8dee2aaSAndroid Build Coastguard Worker if (!bytesPerRow) { 412*c8dee2aaSAndroid Build Coastguard Worker bytesPerRow = 4 * imageInfo['width']; 413*c8dee2aaSAndroid Build Coastguard Worker if (imageInfo['colorType'] === CanvasKit.ColorType.RGBA_F16) { 414*c8dee2aaSAndroid Build Coastguard Worker bytesPerRow *= 2; 415*c8dee2aaSAndroid Build Coastguard Worker } 416*c8dee2aaSAndroid Build Coastguard Worker else if (imageInfo['colorType'] === CanvasKit.ColorType.RGBA_F32) { 417*c8dee2aaSAndroid Build Coastguard Worker bytesPerRow *= 4; 418*c8dee2aaSAndroid Build Coastguard Worker } 419*c8dee2aaSAndroid Build Coastguard Worker } 420*c8dee2aaSAndroid Build Coastguard Worker var pBytes = bytesPerRow * imageInfo.height; 421*c8dee2aaSAndroid Build Coastguard Worker var pPtr; 422*c8dee2aaSAndroid Build Coastguard Worker if (destMallocObj) { 423*c8dee2aaSAndroid Build Coastguard Worker pPtr = destMallocObj['byteOffset']; 424*c8dee2aaSAndroid Build Coastguard Worker } else { 425*c8dee2aaSAndroid Build Coastguard Worker pPtr = CanvasKit._malloc(pBytes); 426*c8dee2aaSAndroid Build Coastguard Worker } 427*c8dee2aaSAndroid Build Coastguard Worker 428*c8dee2aaSAndroid Build Coastguard Worker var rv; 429*c8dee2aaSAndroid Build Coastguard Worker if (grCtx) { 430*c8dee2aaSAndroid Build Coastguard Worker rv = source._readPixels(imageInfo, pPtr, bytesPerRow, srcX, srcY, grCtx); 431*c8dee2aaSAndroid Build Coastguard Worker } else { 432*c8dee2aaSAndroid Build Coastguard Worker rv = source._readPixels(imageInfo, pPtr, bytesPerRow, srcX, srcY); 433*c8dee2aaSAndroid Build Coastguard Worker } 434*c8dee2aaSAndroid Build Coastguard Worker if (!rv) { 435*c8dee2aaSAndroid Build Coastguard Worker Debug('Could not read pixels with the given inputs'); 436*c8dee2aaSAndroid Build Coastguard Worker if (!destMallocObj) { 437*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(pPtr); 438*c8dee2aaSAndroid Build Coastguard Worker } 439*c8dee2aaSAndroid Build Coastguard Worker return null; 440*c8dee2aaSAndroid Build Coastguard Worker } 441*c8dee2aaSAndroid Build Coastguard Worker 442*c8dee2aaSAndroid Build Coastguard Worker // If the user provided us a buffer to copy into, we don't need to allocate a new TypedArray. 443*c8dee2aaSAndroid Build Coastguard Worker if (destMallocObj) { 444*c8dee2aaSAndroid Build Coastguard Worker return destMallocObj['toTypedArray'](); // Return the typed array wrapper w/o allocating. 445*c8dee2aaSAndroid Build Coastguard Worker } 446*c8dee2aaSAndroid Build Coastguard Worker 447*c8dee2aaSAndroid Build Coastguard Worker // Put those pixels into a typed array of the right format and then 448*c8dee2aaSAndroid Build Coastguard Worker // make a copy with slice() that we can return. 449*c8dee2aaSAndroid Build Coastguard Worker var retVal = null; 450*c8dee2aaSAndroid Build Coastguard Worker switch (imageInfo['colorType']) { 451*c8dee2aaSAndroid Build Coastguard Worker case CanvasKit.ColorType.RGBA_8888: 452*c8dee2aaSAndroid Build Coastguard Worker case CanvasKit.ColorType.RGBA_F16: // there is no half-float JS type, so we return raw bytes. 453*c8dee2aaSAndroid Build Coastguard Worker retVal = new Uint8Array(CanvasKit.HEAPU8.buffer, pPtr, pBytes).slice(); 454*c8dee2aaSAndroid Build Coastguard Worker break; 455*c8dee2aaSAndroid Build Coastguard Worker case CanvasKit.ColorType.RGBA_F32: 456*c8dee2aaSAndroid Build Coastguard Worker retVal = new Float32Array(CanvasKit.HEAPU8.buffer, pPtr, pBytes).slice(); 457*c8dee2aaSAndroid Build Coastguard Worker break; 458*c8dee2aaSAndroid Build Coastguard Worker default: 459*c8dee2aaSAndroid Build Coastguard Worker Debug('ColorType not yet supported'); 460*c8dee2aaSAndroid Build Coastguard Worker return null; 461*c8dee2aaSAndroid Build Coastguard Worker } 462*c8dee2aaSAndroid Build Coastguard Worker 463*c8dee2aaSAndroid Build Coastguard Worker // Free the allocated pixels in the WASM memory 464*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(pPtr); 465*c8dee2aaSAndroid Build Coastguard Worker return retVal; 466*c8dee2aaSAndroid Build Coastguard Worker } 467*c8dee2aaSAndroid Build Coastguard Worker 468*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Image.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj, 469*c8dee2aaSAndroid Build Coastguard Worker bytesPerRow) { 470*c8dee2aaSAndroid Build Coastguard Worker var grCtx = CanvasKit.getCurrentGrDirectContext(); 471*c8dee2aaSAndroid Build Coastguard Worker return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow, grCtx); 472*c8dee2aaSAndroid Build Coastguard Worker }; 473*c8dee2aaSAndroid Build Coastguard Worker 474*c8dee2aaSAndroid Build Coastguard Worker // Accepts an array of four numbers in the range of 0-1 representing a 4f color 475*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.clear = function(color4f) { 476*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 477*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color4f); 478*c8dee2aaSAndroid Build Coastguard Worker this._clear(cPtr); 479*c8dee2aaSAndroid Build Coastguard Worker }; 480*c8dee2aaSAndroid Build Coastguard Worker 481*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.clipRRect = function(rrect, op, antialias) { 482*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 483*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRRectToWasm(rrect); 484*c8dee2aaSAndroid Build Coastguard Worker this._clipRRect(rPtr, op, antialias); 485*c8dee2aaSAndroid Build Coastguard Worker }; 486*c8dee2aaSAndroid Build Coastguard Worker 487*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.clipRect = function(rect, op, antialias) { 488*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 489*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRectToWasm(rect); 490*c8dee2aaSAndroid Build Coastguard Worker this._clipRect(rPtr, op, antialias); 491*c8dee2aaSAndroid Build Coastguard Worker }; 492*c8dee2aaSAndroid Build Coastguard Worker 493*c8dee2aaSAndroid Build Coastguard Worker // concat takes a 3x2, a 3x3, or a 4x4 matrix and upscales it (if needed) to 4x4. This is because 494*c8dee2aaSAndroid Build Coastguard Worker // under the hood, SkCanvas uses a 4x4 matrix. 495*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.concat = function(matr) { 496*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 497*c8dee2aaSAndroid Build Coastguard Worker var matrPtr = copy4x4MatrixToWasm(matr); 498*c8dee2aaSAndroid Build Coastguard Worker this._concat(matrPtr); 499*c8dee2aaSAndroid Build Coastguard Worker }; 500*c8dee2aaSAndroid Build Coastguard Worker 501*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawArc = function(oval, startAngle, sweepAngle, useCenter, paint) { 502*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 503*c8dee2aaSAndroid Build Coastguard Worker var oPtr = copyRectToWasm(oval); 504*c8dee2aaSAndroid Build Coastguard Worker this._drawArc(oPtr, startAngle, sweepAngle, useCenter, paint); 505*c8dee2aaSAndroid Build Coastguard Worker }; 506*c8dee2aaSAndroid Build Coastguard Worker 507*c8dee2aaSAndroid Build Coastguard Worker // atlas is an Image, e.g. from CanvasKit.MakeImageFromEncoded 508*c8dee2aaSAndroid Build Coastguard Worker // srcRects, dstXformsshould be arrays of floats of length 4*number of destinations. 509*c8dee2aaSAndroid Build Coastguard Worker // The colors param is optional and is used to tint the drawn images using the optional blend 510*c8dee2aaSAndroid Build Coastguard Worker // mode. Colors can be a Uint32Array of int colors or a flat Float32Array of float colors. 511*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint, 512*c8dee2aaSAndroid Build Coastguard Worker /* optional */ blendMode, /* optional */ colors, 513*c8dee2aaSAndroid Build Coastguard Worker /* optional */ sampling) { 514*c8dee2aaSAndroid Build Coastguard Worker if (!atlas || !paint || !srcRects || !dstXforms) { 515*c8dee2aaSAndroid Build Coastguard Worker Debug('Doing nothing since missing a required input'); 516*c8dee2aaSAndroid Build Coastguard Worker return; 517*c8dee2aaSAndroid Build Coastguard Worker } 518*c8dee2aaSAndroid Build Coastguard Worker 519*c8dee2aaSAndroid Build Coastguard Worker // builder arguments report the length as the number of rects, but when passed as arrays 520*c8dee2aaSAndroid Build Coastguard Worker // their.length attribute is 4x higher because it's the number of total components of all rects. 521*c8dee2aaSAndroid Build Coastguard Worker // colors is always going to report the same length, at least until floats colors are supported 522*c8dee2aaSAndroid Build Coastguard Worker // by this function. 523*c8dee2aaSAndroid Build Coastguard Worker if (srcRects.length !== dstXforms.length) { 524*c8dee2aaSAndroid Build Coastguard Worker Debug('Doing nothing since input arrays length mismatches'); 525*c8dee2aaSAndroid Build Coastguard Worker return; 526*c8dee2aaSAndroid Build Coastguard Worker } 527*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 528*c8dee2aaSAndroid Build Coastguard Worker if (!blendMode) { 529*c8dee2aaSAndroid Build Coastguard Worker blendMode = CanvasKit.BlendMode.SrcOver; 530*c8dee2aaSAndroid Build Coastguard Worker } 531*c8dee2aaSAndroid Build Coastguard Worker 532*c8dee2aaSAndroid Build Coastguard Worker var srcRectPtr = copy1dArray(srcRects, 'HEAPF32'); 533*c8dee2aaSAndroid Build Coastguard Worker 534*c8dee2aaSAndroid Build Coastguard Worker var dstXformPtr = copy1dArray(dstXforms, 'HEAPF32'); 535*c8dee2aaSAndroid Build Coastguard Worker var count = dstXforms.length / 4; 536*c8dee2aaSAndroid Build Coastguard Worker 537*c8dee2aaSAndroid Build Coastguard Worker var colorPtr = copy1dArray(assureIntColors(colors), 'HEAPU32'); 538*c8dee2aaSAndroid Build Coastguard Worker 539*c8dee2aaSAndroid Build Coastguard Worker // We require one of these: 540*c8dee2aaSAndroid Build Coastguard Worker // 1. sampling is null (we default to linear/none) 541*c8dee2aaSAndroid Build Coastguard Worker // 2. sampling.B and sampling.C --> CubicResampler 542*c8dee2aaSAndroid Build Coastguard Worker // 3. sampling.filter [and sampling.mipmap] --> FilterOptions 543*c8dee2aaSAndroid Build Coastguard Worker // 544*c8dee2aaSAndroid Build Coastguard Worker // Thus if all fields are available, we will choose cubic (since we search for B,C first) 545*c8dee2aaSAndroid Build Coastguard Worker 546*c8dee2aaSAndroid Build Coastguard Worker if (sampling && ('B' in sampling) && ('C' in sampling)) { 547*c8dee2aaSAndroid Build Coastguard Worker this._drawAtlasCubic(atlas, dstXformPtr, srcRectPtr, colorPtr, count, blendMode, 548*c8dee2aaSAndroid Build Coastguard Worker sampling['B'], sampling['C'], paint); 549*c8dee2aaSAndroid Build Coastguard Worker } else { 550*c8dee2aaSAndroid Build Coastguard Worker let filter = CanvasKit.FilterMode.Linear; 551*c8dee2aaSAndroid Build Coastguard Worker let mipmap = CanvasKit.MipmapMode.None; 552*c8dee2aaSAndroid Build Coastguard Worker if (sampling) { 553*c8dee2aaSAndroid Build Coastguard Worker filter = sampling['filter']; // 'filter' is a required field 554*c8dee2aaSAndroid Build Coastguard Worker if ('mipmap' in sampling) { // 'mipmap' is optional 555*c8dee2aaSAndroid Build Coastguard Worker mipmap = sampling['mipmap']; 556*c8dee2aaSAndroid Build Coastguard Worker } 557*c8dee2aaSAndroid Build Coastguard Worker } 558*c8dee2aaSAndroid Build Coastguard Worker this._drawAtlasOptions(atlas, dstXformPtr, srcRectPtr, colorPtr, count, blendMode, 559*c8dee2aaSAndroid Build Coastguard Worker filter, mipmap, paint); 560*c8dee2aaSAndroid Build Coastguard Worker } 561*c8dee2aaSAndroid Build Coastguard Worker 562*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(srcRectPtr, srcRects); 563*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(dstXformPtr, dstXforms); 564*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(colorPtr, colors); 565*c8dee2aaSAndroid Build Coastguard Worker }; 566*c8dee2aaSAndroid Build Coastguard Worker 567*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawCircle = function(cx, cy, r, paint) { 568*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 569*c8dee2aaSAndroid Build Coastguard Worker this._drawCircle(cx, cy, r, paint); 570*c8dee2aaSAndroid Build Coastguard Worker } 571*c8dee2aaSAndroid Build Coastguard Worker 572*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawColor = function(color4f, mode) { 573*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 574*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color4f); 575*c8dee2aaSAndroid Build Coastguard Worker if (mode !== undefined) { 576*c8dee2aaSAndroid Build Coastguard Worker this._drawColor(cPtr, mode); 577*c8dee2aaSAndroid Build Coastguard Worker } else { 578*c8dee2aaSAndroid Build Coastguard Worker this._drawColor(cPtr); 579*c8dee2aaSAndroid Build Coastguard Worker } 580*c8dee2aaSAndroid Build Coastguard Worker }; 581*c8dee2aaSAndroid Build Coastguard Worker 582*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawColorInt = function(color, mode) { 583*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 584*c8dee2aaSAndroid Build Coastguard Worker this._drawColorInt(color, mode || CanvasKit.BlendMode.SrcOver); 585*c8dee2aaSAndroid Build Coastguard Worker } 586*c8dee2aaSAndroid Build Coastguard Worker 587*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawColorComponents = function(r, g, b, a, mode) { 588*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 589*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorComponentsToWasm(r, g, b, a); 590*c8dee2aaSAndroid Build Coastguard Worker if (mode !== undefined) { 591*c8dee2aaSAndroid Build Coastguard Worker this._drawColor(cPtr, mode); 592*c8dee2aaSAndroid Build Coastguard Worker } else { 593*c8dee2aaSAndroid Build Coastguard Worker this._drawColor(cPtr); 594*c8dee2aaSAndroid Build Coastguard Worker } 595*c8dee2aaSAndroid Build Coastguard Worker }; 596*c8dee2aaSAndroid Build Coastguard Worker 597*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawDRRect = function(outer, inner, paint) { 598*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 599*c8dee2aaSAndroid Build Coastguard Worker var oPtr = copyRRectToWasm(outer, _scratchRRectPtr); 600*c8dee2aaSAndroid Build Coastguard Worker var iPtr = copyRRectToWasm(inner, _scratchRRect2Ptr); 601*c8dee2aaSAndroid Build Coastguard Worker this._drawDRRect(oPtr, iPtr, paint); 602*c8dee2aaSAndroid Build Coastguard Worker }; 603*c8dee2aaSAndroid Build Coastguard Worker 604*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImage = function(img, x, y, paint) { 605*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 606*c8dee2aaSAndroid Build Coastguard Worker this._drawImage(img, x, y, paint || null); 607*c8dee2aaSAndroid Build Coastguard Worker }; 608*c8dee2aaSAndroid Build Coastguard Worker 609*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImageCubic = function(img, x, y, b, c, paint) { 610*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 611*c8dee2aaSAndroid Build Coastguard Worker this._drawImageCubic(img, x, y, b, c, paint || null); 612*c8dee2aaSAndroid Build Coastguard Worker }; 613*c8dee2aaSAndroid Build Coastguard Worker 614*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImageOptions = function(img, x, y, filter, mipmap, paint) { 615*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 616*c8dee2aaSAndroid Build Coastguard Worker this._drawImageOptions(img, x, y, filter, mipmap, paint || null); 617*c8dee2aaSAndroid Build Coastguard Worker }; 618*c8dee2aaSAndroid Build Coastguard Worker 619*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImageNine = function(img, center, dest, filter, paint) { 620*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 621*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyIRectToWasm(center); 622*c8dee2aaSAndroid Build Coastguard Worker var dPtr = copyRectToWasm(dest); 623*c8dee2aaSAndroid Build Coastguard Worker this._drawImageNine(img, cPtr, dPtr, filter, paint || null); 624*c8dee2aaSAndroid Build Coastguard Worker }; 625*c8dee2aaSAndroid Build Coastguard Worker 626*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImageRect = function(img, src, dest, paint, fastSample) { 627*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 628*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(src, _scratchFourFloatsAPtr); 629*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(dest, _scratchFourFloatsBPtr); 630*c8dee2aaSAndroid Build Coastguard Worker this._drawImageRect(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, paint, !!fastSample); 631*c8dee2aaSAndroid Build Coastguard Worker }; 632*c8dee2aaSAndroid Build Coastguard Worker 633*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImageRectCubic = function(img, src, dest, B, C, paint) { 634*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 635*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(src, _scratchFourFloatsAPtr); 636*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(dest, _scratchFourFloatsBPtr); 637*c8dee2aaSAndroid Build Coastguard Worker this._drawImageRectCubic(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, B, C, 638*c8dee2aaSAndroid Build Coastguard Worker paint || null); 639*c8dee2aaSAndroid Build Coastguard Worker }; 640*c8dee2aaSAndroid Build Coastguard Worker 641*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawImageRectOptions = function(img, src, dest, filter, mipmap, paint) { 642*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 643*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(src, _scratchFourFloatsAPtr); 644*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(dest, _scratchFourFloatsBPtr); 645*c8dee2aaSAndroid Build Coastguard Worker this._drawImageRectOptions(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, filter, mipmap, 646*c8dee2aaSAndroid Build Coastguard Worker paint || null); 647*c8dee2aaSAndroid Build Coastguard Worker }; 648*c8dee2aaSAndroid Build Coastguard Worker 649*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawLine = function(x1, y1, x2, y2, paint) { 650*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 651*c8dee2aaSAndroid Build Coastguard Worker this._drawLine(x1, y1, x2, y2, paint); 652*c8dee2aaSAndroid Build Coastguard Worker } 653*c8dee2aaSAndroid Build Coastguard Worker 654*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawOval = function(oval, paint) { 655*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 656*c8dee2aaSAndroid Build Coastguard Worker var oPtr = copyRectToWasm(oval); 657*c8dee2aaSAndroid Build Coastguard Worker this._drawOval(oPtr, paint); 658*c8dee2aaSAndroid Build Coastguard Worker }; 659*c8dee2aaSAndroid Build Coastguard Worker 660*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawPaint = function(paint) { 661*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 662*c8dee2aaSAndroid Build Coastguard Worker this._drawPaint(paint); 663*c8dee2aaSAndroid Build Coastguard Worker } 664*c8dee2aaSAndroid Build Coastguard Worker 665*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawParagraph = function(p, x, y) { 666*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 667*c8dee2aaSAndroid Build Coastguard Worker this._drawParagraph(p, x, y); 668*c8dee2aaSAndroid Build Coastguard Worker } 669*c8dee2aaSAndroid Build Coastguard Worker 670*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawPatch = function(cubics, colors, texs, mode, paint) { 671*c8dee2aaSAndroid Build Coastguard Worker if (cubics.length < 24) { 672*c8dee2aaSAndroid Build Coastguard Worker throw 'Need 12 cubic points'; 673*c8dee2aaSAndroid Build Coastguard Worker } 674*c8dee2aaSAndroid Build Coastguard Worker if (colors && colors.length < 4) { 675*c8dee2aaSAndroid Build Coastguard Worker throw 'Need 4 colors'; 676*c8dee2aaSAndroid Build Coastguard Worker } 677*c8dee2aaSAndroid Build Coastguard Worker if (texs && texs.length < 8) { 678*c8dee2aaSAndroid Build Coastguard Worker throw 'Need 4 shader coordinates'; 679*c8dee2aaSAndroid Build Coastguard Worker } 680*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 681*c8dee2aaSAndroid Build Coastguard Worker 682*c8dee2aaSAndroid Build Coastguard Worker const cubics_ptr = copy1dArray(cubics, 'HEAPF32'); 683*c8dee2aaSAndroid Build Coastguard Worker const colors_ptr = colors ? copy1dArray(assureIntColors(colors), 'HEAPU32') : nullptr; 684*c8dee2aaSAndroid Build Coastguard Worker const texs_ptr = texs ? copy1dArray(texs, 'HEAPF32') : nullptr; 685*c8dee2aaSAndroid Build Coastguard Worker if (!mode) { 686*c8dee2aaSAndroid Build Coastguard Worker mode = CanvasKit.BlendMode.Modulate; 687*c8dee2aaSAndroid Build Coastguard Worker } 688*c8dee2aaSAndroid Build Coastguard Worker 689*c8dee2aaSAndroid Build Coastguard Worker this._drawPatch(cubics_ptr, colors_ptr, texs_ptr, mode, paint); 690*c8dee2aaSAndroid Build Coastguard Worker 691*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(texs_ptr, texs); 692*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(colors_ptr, colors); 693*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cubics_ptr, cubics); 694*c8dee2aaSAndroid Build Coastguard Worker }; 695*c8dee2aaSAndroid Build Coastguard Worker 696*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawPath = function(path, paint) { 697*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 698*c8dee2aaSAndroid Build Coastguard Worker this._drawPath(path, paint); 699*c8dee2aaSAndroid Build Coastguard Worker } 700*c8dee2aaSAndroid Build Coastguard Worker 701*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawPicture = function(pic) { 702*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 703*c8dee2aaSAndroid Build Coastguard Worker this._drawPicture(pic); 704*c8dee2aaSAndroid Build Coastguard Worker } 705*c8dee2aaSAndroid Build Coastguard Worker 706*c8dee2aaSAndroid Build Coastguard Worker // points is a 1d array of length 2n representing n points where the even indices 707*c8dee2aaSAndroid Build Coastguard Worker // will be treated as x coordinates and the odd indices will be treated as y coordinates. 708*c8dee2aaSAndroid Build Coastguard Worker // Like other APIs, this accepts a malloced type array or malloc obj. 709*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawPoints = function(mode, points, paint) { 710*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 711*c8dee2aaSAndroid Build Coastguard Worker var ptr = copy1dArray(points, 'HEAPF32'); 712*c8dee2aaSAndroid Build Coastguard Worker this._drawPoints(mode, ptr, points.length / 2, paint); 713*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(ptr, points); 714*c8dee2aaSAndroid Build Coastguard Worker }; 715*c8dee2aaSAndroid Build Coastguard Worker 716*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawRRect = function(rrect, paint) { 717*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 718*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRRectToWasm(rrect); 719*c8dee2aaSAndroid Build Coastguard Worker this._drawRRect(rPtr, paint); 720*c8dee2aaSAndroid Build Coastguard Worker }; 721*c8dee2aaSAndroid Build Coastguard Worker 722*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawRect = function(rect, paint) { 723*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 724*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRectToWasm(rect); 725*c8dee2aaSAndroid Build Coastguard Worker this._drawRect(rPtr, paint); 726*c8dee2aaSAndroid Build Coastguard Worker }; 727*c8dee2aaSAndroid Build Coastguard Worker 728*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawRect4f = function(l, t, r, b, paint) { 729*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 730*c8dee2aaSAndroid Build Coastguard Worker this._drawRect4f(l, t, r, b, paint); 731*c8dee2aaSAndroid Build Coastguard Worker } 732*c8dee2aaSAndroid Build Coastguard Worker 733*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawShadow = function(path, zPlaneParams, lightPos, lightRadius, 734*c8dee2aaSAndroid Build Coastguard Worker ambientColor, spotColor, flags) { 735*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 736*c8dee2aaSAndroid Build Coastguard Worker var ambiPtr = copyColorToWasmNoScratch(ambientColor); 737*c8dee2aaSAndroid Build Coastguard Worker var spotPtr = copyColorToWasmNoScratch(spotColor); 738*c8dee2aaSAndroid Build Coastguard Worker // We use the return value from copy1dArray in case the passed in arrays are malloc'd. 739*c8dee2aaSAndroid Build Coastguard Worker var zPlanePtr = copy1dArray(zPlaneParams, 'HEAPF32', _scratchThreeFloatsAPtr); 740*c8dee2aaSAndroid Build Coastguard Worker var lightPosPtr = copy1dArray(lightPos, 'HEAPF32', _scratchThreeFloatsBPtr); 741*c8dee2aaSAndroid Build Coastguard Worker this._drawShadow(path, zPlanePtr, lightPosPtr, lightRadius, ambiPtr, spotPtr, flags); 742*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(ambiPtr, ambientColor); 743*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(spotPtr, spotColor); 744*c8dee2aaSAndroid Build Coastguard Worker }; 745*c8dee2aaSAndroid Build Coastguard Worker 746*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.getShadowLocalBounds = function(ctm, path, zPlaneParams, lightPos, lightRadius, 747*c8dee2aaSAndroid Build Coastguard Worker flags, optOutputRect) { 748*c8dee2aaSAndroid Build Coastguard Worker var ctmPtr = copy3x3MatrixToWasm(ctm); 749*c8dee2aaSAndroid Build Coastguard Worker // We use the return value from copy1dArray in case the passed in arrays are malloc'd. 750*c8dee2aaSAndroid Build Coastguard Worker var zPlanePtr = copy1dArray(zPlaneParams, 'HEAPF32', _scratchThreeFloatsAPtr); 751*c8dee2aaSAndroid Build Coastguard Worker var lightPosPtr = copy1dArray(lightPos, 'HEAPF32', _scratchThreeFloatsBPtr); 752*c8dee2aaSAndroid Build Coastguard Worker var ok = this._getShadowLocalBounds(ctmPtr, path, zPlanePtr, lightPosPtr, lightRadius, 753*c8dee2aaSAndroid Build Coastguard Worker flags, _scratchFourFloatsAPtr); 754*c8dee2aaSAndroid Build Coastguard Worker if (!ok) { 755*c8dee2aaSAndroid Build Coastguard Worker return null; 756*c8dee2aaSAndroid Build Coastguard Worker } 757*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 758*c8dee2aaSAndroid Build Coastguard Worker if (optOutputRect) { 759*c8dee2aaSAndroid Build Coastguard Worker optOutputRect.set(ta); 760*c8dee2aaSAndroid Build Coastguard Worker return optOutputRect; 761*c8dee2aaSAndroid Build Coastguard Worker } 762*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 763*c8dee2aaSAndroid Build Coastguard Worker }; 764*c8dee2aaSAndroid Build Coastguard Worker 765*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawTextBlob = function(blob, x, y, paint) { 766*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 767*c8dee2aaSAndroid Build Coastguard Worker this._drawTextBlob(blob, x, y, paint); 768*c8dee2aaSAndroid Build Coastguard Worker } 769*c8dee2aaSAndroid Build Coastguard Worker 770*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.drawVertices = function(verts, mode, paint) { 771*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 772*c8dee2aaSAndroid Build Coastguard Worker this._drawVertices(verts, mode, paint); 773*c8dee2aaSAndroid Build Coastguard Worker } 774*c8dee2aaSAndroid Build Coastguard Worker 775*c8dee2aaSAndroid Build Coastguard Worker // getDeviceClipBounds returns an SkIRect 776*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.getDeviceClipBounds = function(outputRect) { 777*c8dee2aaSAndroid Build Coastguard Worker // _getDeviceClipBounds will copy the values into the pointer. 778*c8dee2aaSAndroid Build Coastguard Worker this._getDeviceClipBounds(_scratchIRectPtr); 779*c8dee2aaSAndroid Build Coastguard Worker return copyIRectFromWasm(_scratchIRect, outputRect); 780*c8dee2aaSAndroid Build Coastguard Worker }; 781*c8dee2aaSAndroid Build Coastguard Worker 782*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.quickReject = function(rect) { 783*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRectToWasm(rect); 784*c8dee2aaSAndroid Build Coastguard Worker return this._quickReject(rPtr); 785*c8dee2aaSAndroid Build Coastguard Worker }; 786*c8dee2aaSAndroid Build Coastguard Worker 787*c8dee2aaSAndroid Build Coastguard Worker // getLocalToDevice returns a 4x4 matrix. 788*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.getLocalToDevice = function() { 789*c8dee2aaSAndroid Build Coastguard Worker // _getLocalToDevice will copy the values into the pointer. 790*c8dee2aaSAndroid Build Coastguard Worker this._getLocalToDevice(_scratch4x4MatrixPtr); 791*c8dee2aaSAndroid Build Coastguard Worker return copy4x4MatrixFromWasm(_scratch4x4MatrixPtr); 792*c8dee2aaSAndroid Build Coastguard Worker }; 793*c8dee2aaSAndroid Build Coastguard Worker 794*c8dee2aaSAndroid Build Coastguard Worker // getTotalMatrix returns the current matrix as a 3x3 matrix. 795*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.getTotalMatrix = function() { 796*c8dee2aaSAndroid Build Coastguard Worker // _getTotalMatrix will copy the values into the pointer. 797*c8dee2aaSAndroid Build Coastguard Worker this._getTotalMatrix(_scratch3x3MatrixPtr); 798*c8dee2aaSAndroid Build Coastguard Worker // read them out into an array. TODO(kjlubick): If we change Matrix to be 799*c8dee2aaSAndroid Build Coastguard Worker // typedArrays, then we should return a typed array here too. 800*c8dee2aaSAndroid Build Coastguard Worker var rv = new Array(9); 801*c8dee2aaSAndroid Build Coastguard Worker for (var i = 0; i < 9; i++) { 802*c8dee2aaSAndroid Build Coastguard Worker rv[i] = CanvasKit.HEAPF32[_scratch3x3MatrixPtr/4 + i]; // divide by 4 to "cast" to float. 803*c8dee2aaSAndroid Build Coastguard Worker } 804*c8dee2aaSAndroid Build Coastguard Worker return rv; 805*c8dee2aaSAndroid Build Coastguard Worker }; 806*c8dee2aaSAndroid Build Coastguard Worker 807*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.makeSurface = function(imageInfo) { 808*c8dee2aaSAndroid Build Coastguard Worker var s = this._makeSurface(imageInfo); 809*c8dee2aaSAndroid Build Coastguard Worker s._context = this._context; 810*c8dee2aaSAndroid Build Coastguard Worker return s; 811*c8dee2aaSAndroid Build Coastguard Worker }; 812*c8dee2aaSAndroid Build Coastguard Worker 813*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.readPixels = function(srcX, srcY, imageInfo, destMallocObj, 814*c8dee2aaSAndroid Build Coastguard Worker bytesPerRow) { 815*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 816*c8dee2aaSAndroid Build Coastguard Worker return readPixels(this, srcX, srcY, imageInfo, destMallocObj, bytesPerRow); 817*c8dee2aaSAndroid Build Coastguard Worker }; 818*c8dee2aaSAndroid Build Coastguard Worker 819*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.saveLayer = function (paint, boundsRect, backdrop, flags, backdropTileMode) { 820*c8dee2aaSAndroid Build Coastguard Worker // bPtr will be 0 (nullptr) if boundsRect is undefined/null. 821*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copyRectToWasm(boundsRect); 822*c8dee2aaSAndroid Build Coastguard Worker // These or clauses help emscripten, which does not deal with undefined well. 823*c8dee2aaSAndroid Build Coastguard Worker return this._saveLayer(paint || null, bPtr, backdrop || null, flags || 0, backdropTileMode || CanvasKit.TileMode.Clamp); 824*c8dee2aaSAndroid Build Coastguard Worker }; 825*c8dee2aaSAndroid Build Coastguard Worker 826*c8dee2aaSAndroid Build Coastguard Worker // pixels should be a Uint8Array or a plain JS array. 827*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Canvas.prototype.writePixels = function(pixels, srcWidth, srcHeight, 828*c8dee2aaSAndroid Build Coastguard Worker destX, destY, alphaType, colorType, colorSpace) { 829*c8dee2aaSAndroid Build Coastguard Worker if (pixels.byteLength % (srcWidth * srcHeight)) { 830*c8dee2aaSAndroid Build Coastguard Worker throw 'pixels length must be a multiple of the srcWidth * srcHeight'; 831*c8dee2aaSAndroid Build Coastguard Worker } 832*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 833*c8dee2aaSAndroid Build Coastguard Worker var bytesPerPixel = pixels.byteLength / (srcWidth * srcHeight); 834*c8dee2aaSAndroid Build Coastguard Worker // supply defaults (which are compatible with HTMLCanvas's putImageData) 835*c8dee2aaSAndroid Build Coastguard Worker alphaType = alphaType || CanvasKit.AlphaType.Unpremul; 836*c8dee2aaSAndroid Build Coastguard Worker colorType = colorType || CanvasKit.ColorType.RGBA_8888; 837*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || CanvasKit.ColorSpace.SRGB; 838*c8dee2aaSAndroid Build Coastguard Worker var srcRowBytes = bytesPerPixel * srcWidth; 839*c8dee2aaSAndroid Build Coastguard Worker 840*c8dee2aaSAndroid Build Coastguard Worker var pptr = copy1dArray(pixels, 'HEAPU8'); 841*c8dee2aaSAndroid Build Coastguard Worker var ok = this._writePixels({ 842*c8dee2aaSAndroid Build Coastguard Worker 'width': srcWidth, 843*c8dee2aaSAndroid Build Coastguard Worker 'height': srcHeight, 844*c8dee2aaSAndroid Build Coastguard Worker 'colorType': colorType, 845*c8dee2aaSAndroid Build Coastguard Worker 'alphaType': alphaType, 846*c8dee2aaSAndroid Build Coastguard Worker 'colorSpace': colorSpace, 847*c8dee2aaSAndroid Build Coastguard Worker }, pptr, srcRowBytes, destX, destY); 848*c8dee2aaSAndroid Build Coastguard Worker 849*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(pptr, pixels); 850*c8dee2aaSAndroid Build Coastguard Worker return ok; 851*c8dee2aaSAndroid Build Coastguard Worker }; 852*c8dee2aaSAndroid Build Coastguard Worker 853*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ColorFilter.MakeBlend = function(color4f, mode, colorSpace) { 854*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color4f); 855*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || CanvasKit.ColorSpace.SRGB; 856*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ColorFilter._MakeBlend(cPtr, mode, colorSpace); 857*c8dee2aaSAndroid Build Coastguard Worker }; 858*c8dee2aaSAndroid Build Coastguard Worker 859*c8dee2aaSAndroid Build Coastguard Worker // colorMatrix is an ColorMatrix (e.g. Float32Array of length 20) 860*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ColorFilter.MakeMatrix = function(colorMatrix) { 861*c8dee2aaSAndroid Build Coastguard Worker if (!colorMatrix || colorMatrix.length !== 20) { 862*c8dee2aaSAndroid Build Coastguard Worker throw 'invalid color matrix'; 863*c8dee2aaSAndroid Build Coastguard Worker } 864*c8dee2aaSAndroid Build Coastguard Worker var fptr = copy1dArray(colorMatrix, 'HEAPF32'); 865*c8dee2aaSAndroid Build Coastguard Worker // We know skia memcopies the floats, so we can free our memory after the call returns. 866*c8dee2aaSAndroid Build Coastguard Worker var m = CanvasKit.ColorFilter._makeMatrix(fptr); 867*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(fptr, colorMatrix); 868*c8dee2aaSAndroid Build Coastguard Worker return m; 869*c8dee2aaSAndroid Build Coastguard Worker }; 870*c8dee2aaSAndroid Build Coastguard Worker 871*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ContourMeasure.prototype.getPosTan = function(distance, optionalOutput) { 872*c8dee2aaSAndroid Build Coastguard Worker this._getPosTan(distance, _scratchFourFloatsAPtr); 873*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 874*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutput) { 875*c8dee2aaSAndroid Build Coastguard Worker optionalOutput.set(ta); 876*c8dee2aaSAndroid Build Coastguard Worker return optionalOutput; 877*c8dee2aaSAndroid Build Coastguard Worker } 878*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 879*c8dee2aaSAndroid Build Coastguard Worker }; 880*c8dee2aaSAndroid Build Coastguard Worker 881*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ImageFilter.prototype.getOutputBounds = function (drawBounds, ctm, optionalOutputArray) { 882*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copyRectToWasm(drawBounds, _scratchFourFloatsAPtr); 883*c8dee2aaSAndroid Build Coastguard Worker var mPtr = copy3x3MatrixToWasm(ctm); 884*c8dee2aaSAndroid Build Coastguard Worker this._getOutputBounds(bPtr, mPtr, _scratchIRectPtr); 885*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchIRect['toTypedArray'](); 886*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutputArray) { 887*c8dee2aaSAndroid Build Coastguard Worker optionalOutputArray.set(ta); 888*c8dee2aaSAndroid Build Coastguard Worker return optionalOutputArray; 889*c8dee2aaSAndroid Build Coastguard Worker } 890*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 891*c8dee2aaSAndroid Build Coastguard Worker }; 892*c8dee2aaSAndroid Build Coastguard Worker 893*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ImageFilter.MakeDropShadow = function(dx, dy, sx, sy, color, input) { 894*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color, _scratchColorPtr); 895*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ImageFilter._MakeDropShadow(dx, dy, sx, sy, cPtr, input); 896*c8dee2aaSAndroid Build Coastguard Worker }; 897*c8dee2aaSAndroid Build Coastguard Worker 898*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ImageFilter.MakeDropShadowOnly = function(dx, dy, sx, sy, color, input) { 899*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color, _scratchColorPtr); 900*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ImageFilter._MakeDropShadowOnly(dx, dy, sx, sy, cPtr, input); 901*c8dee2aaSAndroid Build Coastguard Worker }; 902*c8dee2aaSAndroid Build Coastguard Worker 903*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ImageFilter.MakeImage = function(img, sampling, srcRect, dstRect) { 904*c8dee2aaSAndroid Build Coastguard Worker var srcPtr = copyRectToWasm(srcRect, _scratchFourFloatsAPtr); 905*c8dee2aaSAndroid Build Coastguard Worker var dstPtr = copyRectToWasm(dstRect, _scratchFourFloatsBPtr); 906*c8dee2aaSAndroid Build Coastguard Worker 907*c8dee2aaSAndroid Build Coastguard Worker if ('B' in sampling && 'C' in sampling) { 908*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ImageFilter._MakeImageCubic(img, sampling['B'], sampling['C'], srcPtr, dstPtr); 909*c8dee2aaSAndroid Build Coastguard Worker } else { 910*c8dee2aaSAndroid Build Coastguard Worker const filter = sampling['filter']; // 'filter' is a required field 911*c8dee2aaSAndroid Build Coastguard Worker let mipmap = CanvasKit.MipmapMode.None; 912*c8dee2aaSAndroid Build Coastguard Worker if ('mipmap' in sampling) { // 'mipmap' is optional 913*c8dee2aaSAndroid Build Coastguard Worker mipmap = sampling['mipmap']; 914*c8dee2aaSAndroid Build Coastguard Worker } 915*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ImageFilter._MakeImageOptions(img, filter, mipmap, srcPtr, dstPtr); 916*c8dee2aaSAndroid Build Coastguard Worker } 917*c8dee2aaSAndroid Build Coastguard Worker }; 918*c8dee2aaSAndroid Build Coastguard Worker 919*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ImageFilter.MakeMatrixTransform = function(matrix, sampling, input) { 920*c8dee2aaSAndroid Build Coastguard Worker var matrPtr = copy3x3MatrixToWasm(matrix); 921*c8dee2aaSAndroid Build Coastguard Worker 922*c8dee2aaSAndroid Build Coastguard Worker if ('B' in sampling && 'C' in sampling) { 923*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ImageFilter._MakeMatrixTransformCubic(matrPtr, 924*c8dee2aaSAndroid Build Coastguard Worker sampling['B'], sampling['C'], 925*c8dee2aaSAndroid Build Coastguard Worker input); 926*c8dee2aaSAndroid Build Coastguard Worker } else { 927*c8dee2aaSAndroid Build Coastguard Worker const filter = sampling['filter']; // 'filter' is a required field 928*c8dee2aaSAndroid Build Coastguard Worker let mipmap = CanvasKit.MipmapMode.None; 929*c8dee2aaSAndroid Build Coastguard Worker if ('mipmap' in sampling) { // 'mipmap' is optional 930*c8dee2aaSAndroid Build Coastguard Worker mipmap = sampling['mipmap']; 931*c8dee2aaSAndroid Build Coastguard Worker } 932*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.ImageFilter._MakeMatrixTransformOptions(matrPtr, 933*c8dee2aaSAndroid Build Coastguard Worker filter, mipmap, 934*c8dee2aaSAndroid Build Coastguard Worker input); 935*c8dee2aaSAndroid Build Coastguard Worker } 936*c8dee2aaSAndroid Build Coastguard Worker }; 937*c8dee2aaSAndroid Build Coastguard Worker 938*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paint.prototype.getColor = function() { 939*c8dee2aaSAndroid Build Coastguard Worker this._getColor(_scratchColorPtr); 940*c8dee2aaSAndroid Build Coastguard Worker return copyColorFromWasm(_scratchColorPtr); 941*c8dee2aaSAndroid Build Coastguard Worker }; 942*c8dee2aaSAndroid Build Coastguard Worker 943*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paint.prototype.setColor = function(color4f, colorSpace) { 944*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method. 945*c8dee2aaSAndroid Build Coastguard Worker // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here. 946*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color4f); 947*c8dee2aaSAndroid Build Coastguard Worker this._setColor(cPtr, colorSpace); 948*c8dee2aaSAndroid Build Coastguard Worker }; 949*c8dee2aaSAndroid Build Coastguard Worker 950*c8dee2aaSAndroid Build Coastguard Worker // The color components here are expected to be floating point values (nominally between 951*c8dee2aaSAndroid Build Coastguard Worker // 0.0 and 1.0, but with wider color gamuts, the values could exceed this range). To convert 952*c8dee2aaSAndroid Build Coastguard Worker // between standard 8 bit colors and floats, just divide by 255 before passing them in. 953*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Paint.prototype.setColorComponents = function(r, g, b, a, colorSpace) { 954*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method. 955*c8dee2aaSAndroid Build Coastguard Worker // emscripten wouldn't bind undefined to the sk_sp<ColorSpace> expected here. 956*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorComponentsToWasm(r, g, b, a); 957*c8dee2aaSAndroid Build Coastguard Worker this._setColor(cPtr, colorSpace); 958*c8dee2aaSAndroid Build Coastguard Worker }; 959*c8dee2aaSAndroid Build Coastguard Worker 960*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Path.prototype.getPoint = function(idx, optionalOutput) { 961*c8dee2aaSAndroid Build Coastguard Worker // This will copy 2 floats into a space for 4 floats 962*c8dee2aaSAndroid Build Coastguard Worker this._getPoint(idx, _scratchFourFloatsAPtr); 963*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 964*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutput) { 965*c8dee2aaSAndroid Build Coastguard Worker // We cannot call optionalOutput.set() because it is an error to call .set() with 966*c8dee2aaSAndroid Build Coastguard Worker // a source bigger than the destination. 967*c8dee2aaSAndroid Build Coastguard Worker optionalOutput[0] = ta[0]; 968*c8dee2aaSAndroid Build Coastguard Worker optionalOutput[1] = ta[1]; 969*c8dee2aaSAndroid Build Coastguard Worker return optionalOutput; 970*c8dee2aaSAndroid Build Coastguard Worker } 971*c8dee2aaSAndroid Build Coastguard Worker // Be sure to return a copy of just the first 2 values. 972*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(0, 2); 973*c8dee2aaSAndroid Build Coastguard Worker }; 974*c8dee2aaSAndroid Build Coastguard Worker 975*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Picture.prototype.makeShader = function(tmx, tmy, mode, matr, rect) { 976*c8dee2aaSAndroid Build Coastguard Worker var mPtr = copy3x3MatrixToWasm(matr); 977*c8dee2aaSAndroid Build Coastguard Worker var rPtr = copyRectToWasm(rect); 978*c8dee2aaSAndroid Build Coastguard Worker return this._makeShader(tmx, tmy, mode, mPtr, rPtr); 979*c8dee2aaSAndroid Build Coastguard Worker }; 980*c8dee2aaSAndroid Build Coastguard Worker 981*c8dee2aaSAndroid Build Coastguard Worker // Clients can pass in a Float32Array with length 4 to this and the results 982*c8dee2aaSAndroid Build Coastguard Worker // will be copied into that array. Otherwise, a new TypedArray will be allocated 983*c8dee2aaSAndroid Build Coastguard Worker // and returned. 984*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Picture.prototype.cullRect = function (optionalOutputArray) { 985*c8dee2aaSAndroid Build Coastguard Worker this._cullRect(_scratchFourFloatsAPtr); 986*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 987*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutputArray) { 988*c8dee2aaSAndroid Build Coastguard Worker optionalOutputArray.set(ta); 989*c8dee2aaSAndroid Build Coastguard Worker return optionalOutputArray; 990*c8dee2aaSAndroid Build Coastguard Worker } 991*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 992*c8dee2aaSAndroid Build Coastguard Worker }; 993*c8dee2aaSAndroid Build Coastguard Worker 994*c8dee2aaSAndroid Build Coastguard Worker // `bounds` is a required argument and is the initial cullRect for the picture. 995*c8dee2aaSAndroid Build Coastguard Worker // `computeBounds` is an optional boolean argument (default false) which, if 996*c8dee2aaSAndroid Build Coastguard Worker // true, will cause the recorded picture to compute a more accurate cullRect 997*c8dee2aaSAndroid Build Coastguard Worker // when it is created. 998*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.PictureRecorder.prototype.beginRecording = function (bounds, computeBounds) { 999*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copyRectToWasm(bounds); 1000*c8dee2aaSAndroid Build Coastguard Worker return this._beginRecording(bPtr, !!computeBounds); 1001*c8dee2aaSAndroid Build Coastguard Worker }; 1002*c8dee2aaSAndroid Build Coastguard Worker 1003*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype.getCanvas = function() { 1004*c8dee2aaSAndroid Build Coastguard Worker var c = this._getCanvas(); 1005*c8dee2aaSAndroid Build Coastguard Worker c._context = this._context; 1006*c8dee2aaSAndroid Build Coastguard Worker return c; 1007*c8dee2aaSAndroid Build Coastguard Worker }; 1008*c8dee2aaSAndroid Build Coastguard Worker 1009*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype.makeImageSnapshot = function(optionalBoundsRect) { 1010*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 1011*c8dee2aaSAndroid Build Coastguard Worker var bPtr = copyIRectToWasm(optionalBoundsRect); 1012*c8dee2aaSAndroid Build Coastguard Worker return this._makeImageSnapshot(bPtr); 1013*c8dee2aaSAndroid Build Coastguard Worker }; 1014*c8dee2aaSAndroid Build Coastguard Worker 1015*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype.makeSurface = function(imageInfo) { 1016*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 1017*c8dee2aaSAndroid Build Coastguard Worker var s = this._makeSurface(imageInfo); 1018*c8dee2aaSAndroid Build Coastguard Worker s._context = this._context; 1019*c8dee2aaSAndroid Build Coastguard Worker return s; 1020*c8dee2aaSAndroid Build Coastguard Worker }; 1021*c8dee2aaSAndroid Build Coastguard Worker 1022*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype._requestAnimationFrameInternal = function(callback, dirtyRect) { 1023*c8dee2aaSAndroid Build Coastguard Worker if (!this._cached_canvas) { 1024*c8dee2aaSAndroid Build Coastguard Worker this._cached_canvas = this.getCanvas(); 1025*c8dee2aaSAndroid Build Coastguard Worker } 1026*c8dee2aaSAndroid Build Coastguard Worker return requestAnimationFrame(function() { 1027*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 1028*c8dee2aaSAndroid Build Coastguard Worker 1029*c8dee2aaSAndroid Build Coastguard Worker callback(this._cached_canvas); 1030*c8dee2aaSAndroid Build Coastguard Worker 1031*c8dee2aaSAndroid Build Coastguard Worker // We do not dispose() of the Surface here, as the client will typically 1032*c8dee2aaSAndroid Build Coastguard Worker // call requestAnimationFrame again from within the supplied callback. 1033*c8dee2aaSAndroid Build Coastguard Worker // For drawing a single frame, prefer drawOnce(). 1034*c8dee2aaSAndroid Build Coastguard Worker this.flush(dirtyRect); 1035*c8dee2aaSAndroid Build Coastguard Worker }.bind(this)); 1036*c8dee2aaSAndroid Build Coastguard Worker }; 1037*c8dee2aaSAndroid Build Coastguard Worker if (!CanvasKit.Surface.prototype.requestAnimationFrame) { 1038*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype.requestAnimationFrame = 1039*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype._requestAnimationFrameInternal; 1040*c8dee2aaSAndroid Build Coastguard Worker } 1041*c8dee2aaSAndroid Build Coastguard Worker 1042*c8dee2aaSAndroid Build Coastguard Worker // drawOnce will dispose of the surface after drawing the frame using the provided 1043*c8dee2aaSAndroid Build Coastguard Worker // callback. 1044*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype._drawOnceInternal = function(callback, dirtyRect) { 1045*c8dee2aaSAndroid Build Coastguard Worker if (!this._cached_canvas) { 1046*c8dee2aaSAndroid Build Coastguard Worker this._cached_canvas = this.getCanvas(); 1047*c8dee2aaSAndroid Build Coastguard Worker } 1048*c8dee2aaSAndroid Build Coastguard Worker requestAnimationFrame(function() { 1049*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.setCurrentContext(this._context); 1050*c8dee2aaSAndroid Build Coastguard Worker callback(this._cached_canvas); 1051*c8dee2aaSAndroid Build Coastguard Worker 1052*c8dee2aaSAndroid Build Coastguard Worker this.flush(dirtyRect); 1053*c8dee2aaSAndroid Build Coastguard Worker this.dispose(); 1054*c8dee2aaSAndroid Build Coastguard Worker }.bind(this)); 1055*c8dee2aaSAndroid Build Coastguard Worker }; 1056*c8dee2aaSAndroid Build Coastguard Worker if (!CanvasKit.Surface.prototype.drawOnce) { 1057*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Surface.prototype.drawOnce = CanvasKit.Surface.prototype._drawOnceInternal; 1058*c8dee2aaSAndroid Build Coastguard Worker } 1059*c8dee2aaSAndroid Build Coastguard Worker 1060*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.PathEffect.MakeDash = function(intervals, phase) { 1061*c8dee2aaSAndroid Build Coastguard Worker if (!phase) { 1062*c8dee2aaSAndroid Build Coastguard Worker phase = 0; 1063*c8dee2aaSAndroid Build Coastguard Worker } 1064*c8dee2aaSAndroid Build Coastguard Worker if (!intervals.length || intervals.length % 2 === 1) { 1065*c8dee2aaSAndroid Build Coastguard Worker throw 'Intervals array must have even length'; 1066*c8dee2aaSAndroid Build Coastguard Worker } 1067*c8dee2aaSAndroid Build Coastguard Worker var ptr = copy1dArray(intervals, 'HEAPF32'); 1068*c8dee2aaSAndroid Build Coastguard Worker var dpe = CanvasKit.PathEffect._MakeDash(ptr, intervals.length, phase); 1069*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(ptr, intervals); 1070*c8dee2aaSAndroid Build Coastguard Worker return dpe; 1071*c8dee2aaSAndroid Build Coastguard Worker }; 1072*c8dee2aaSAndroid Build Coastguard Worker 1073*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.PathEffect.MakeLine2D = function(width, matrix) { 1074*c8dee2aaSAndroid Build Coastguard Worker var matrixPtr = copy3x3MatrixToWasm(matrix); 1075*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.PathEffect._MakeLine2D(width, matrixPtr); 1076*c8dee2aaSAndroid Build Coastguard Worker }; 1077*c8dee2aaSAndroid Build Coastguard Worker 1078*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.PathEffect.MakePath2D = function(matrix, path) { 1079*c8dee2aaSAndroid Build Coastguard Worker var matrixPtr = copy3x3MatrixToWasm(matrix); 1080*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.PathEffect._MakePath2D(matrixPtr, path); 1081*c8dee2aaSAndroid Build Coastguard Worker }; 1082*c8dee2aaSAndroid Build Coastguard Worker 1083*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.MakeColor = function(color4f, colorSpace) { 1084*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; 1085*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color4f); 1086*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.Shader._MakeColor(cPtr, colorSpace); 1087*c8dee2aaSAndroid Build Coastguard Worker }; 1088*c8dee2aaSAndroid Build Coastguard Worker 1089*c8dee2aaSAndroid Build Coastguard Worker // TODO(kjlubick) remove deprecated names. 1090*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.Blend = CanvasKit.Shader.MakeBlend; 1091*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.Color = CanvasKit.Shader.MakeColor; 1092*c8dee2aaSAndroid Build Coastguard Worker 1093*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags, colorSpace) { 1094*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; 1095*c8dee2aaSAndroid Build Coastguard Worker var cPtrInfo = copyFlexibleColorArray(colors); 1096*c8dee2aaSAndroid Build Coastguard Worker var posPtr = copy1dArray(pos, 'HEAPF32'); 1097*c8dee2aaSAndroid Build Coastguard Worker flags = flags || 0; 1098*c8dee2aaSAndroid Build Coastguard Worker var localMatrixPtr = copy3x3MatrixToWasm(localMatrix); 1099*c8dee2aaSAndroid Build Coastguard Worker 1100*c8dee2aaSAndroid Build Coastguard Worker // Copy start and end to _scratchFourFloatsAPtr. 1101*c8dee2aaSAndroid Build Coastguard Worker var startEndPts = _scratchFourFloatsA['toTypedArray'](); 1102*c8dee2aaSAndroid Build Coastguard Worker startEndPts.set(start); 1103*c8dee2aaSAndroid Build Coastguard Worker startEndPts.set(end, 2); 1104*c8dee2aaSAndroid Build Coastguard Worker 1105*c8dee2aaSAndroid Build Coastguard Worker var lgs = CanvasKit.Shader._MakeLinearGradient(_scratchFourFloatsAPtr, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr, 1106*c8dee2aaSAndroid Build Coastguard Worker cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace); 1107*c8dee2aaSAndroid Build Coastguard Worker 1108*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors); 1109*c8dee2aaSAndroid Build Coastguard Worker pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos); 1110*c8dee2aaSAndroid Build Coastguard Worker return lgs; 1111*c8dee2aaSAndroid Build Coastguard Worker }; 1112*c8dee2aaSAndroid Build Coastguard Worker 1113*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags, colorSpace) { 1114*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; 1115*c8dee2aaSAndroid Build Coastguard Worker var cPtrInfo = copyFlexibleColorArray(colors); 1116*c8dee2aaSAndroid Build Coastguard Worker var posPtr = copy1dArray(pos, 'HEAPF32'); 1117*c8dee2aaSAndroid Build Coastguard Worker flags = flags || 0; 1118*c8dee2aaSAndroid Build Coastguard Worker var localMatrixPtr = copy3x3MatrixToWasm(localMatrix); 1119*c8dee2aaSAndroid Build Coastguard Worker 1120*c8dee2aaSAndroid Build Coastguard Worker var rgs = CanvasKit.Shader._MakeRadialGradient(center[0], center[1], radius, cPtrInfo.colorPtr, 1121*c8dee2aaSAndroid Build Coastguard Worker cPtrInfo.colorType, posPtr, cPtrInfo.count, mode, 1122*c8dee2aaSAndroid Build Coastguard Worker flags, localMatrixPtr, colorSpace); 1123*c8dee2aaSAndroid Build Coastguard Worker 1124*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors); 1125*c8dee2aaSAndroid Build Coastguard Worker pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos); 1126*c8dee2aaSAndroid Build Coastguard Worker return rgs; 1127*c8dee2aaSAndroid Build Coastguard Worker }; 1128*c8dee2aaSAndroid Build Coastguard Worker 1129*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle, colorSpace) { 1130*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; 1131*c8dee2aaSAndroid Build Coastguard Worker var cPtrInfo = copyFlexibleColorArray(colors); 1132*c8dee2aaSAndroid Build Coastguard Worker var posPtr = copy1dArray(pos, 'HEAPF32'); 1133*c8dee2aaSAndroid Build Coastguard Worker flags = flags || 0; 1134*c8dee2aaSAndroid Build Coastguard Worker startAngle = startAngle || 0; 1135*c8dee2aaSAndroid Build Coastguard Worker endAngle = endAngle || 360; 1136*c8dee2aaSAndroid Build Coastguard Worker var localMatrixPtr = copy3x3MatrixToWasm(localMatrix); 1137*c8dee2aaSAndroid Build Coastguard Worker 1138*c8dee2aaSAndroid Build Coastguard Worker var sgs = CanvasKit.Shader._MakeSweepGradient(cx, cy, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr, 1139*c8dee2aaSAndroid Build Coastguard Worker cPtrInfo.count, mode, 1140*c8dee2aaSAndroid Build Coastguard Worker startAngle, endAngle, flags, 1141*c8dee2aaSAndroid Build Coastguard Worker localMatrixPtr, colorSpace); 1142*c8dee2aaSAndroid Build Coastguard Worker 1143*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors); 1144*c8dee2aaSAndroid Build Coastguard Worker pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos); 1145*c8dee2aaSAndroid Build Coastguard Worker return sgs; 1146*c8dee2aaSAndroid Build Coastguard Worker }; 1147*c8dee2aaSAndroid Build Coastguard Worker 1148*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Shader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius, 1149*c8dee2aaSAndroid Build Coastguard Worker colors, pos, mode, localMatrix, flags, colorSpace) { 1150*c8dee2aaSAndroid Build Coastguard Worker colorSpace = colorSpace || null; 1151*c8dee2aaSAndroid Build Coastguard Worker var cPtrInfo = copyFlexibleColorArray(colors); 1152*c8dee2aaSAndroid Build Coastguard Worker var posPtr = copy1dArray(pos, 'HEAPF32'); 1153*c8dee2aaSAndroid Build Coastguard Worker flags = flags || 0; 1154*c8dee2aaSAndroid Build Coastguard Worker var localMatrixPtr = copy3x3MatrixToWasm(localMatrix); 1155*c8dee2aaSAndroid Build Coastguard Worker 1156*c8dee2aaSAndroid Build Coastguard Worker // Copy start and end to _scratchFourFloatsAPtr. 1157*c8dee2aaSAndroid Build Coastguard Worker var startEndPts = _scratchFourFloatsA['toTypedArray'](); 1158*c8dee2aaSAndroid Build Coastguard Worker startEndPts.set(start); 1159*c8dee2aaSAndroid Build Coastguard Worker startEndPts.set(end, 2); 1160*c8dee2aaSAndroid Build Coastguard Worker 1161*c8dee2aaSAndroid Build Coastguard Worker var rgs = CanvasKit.Shader._MakeTwoPointConicalGradient(_scratchFourFloatsAPtr, 1162*c8dee2aaSAndroid Build Coastguard Worker startRadius, endRadius, cPtrInfo.colorPtr, cPtrInfo.colorType, 1163*c8dee2aaSAndroid Build Coastguard Worker posPtr, cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace); 1164*c8dee2aaSAndroid Build Coastguard Worker 1165*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors); 1166*c8dee2aaSAndroid Build Coastguard Worker pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos); 1167*c8dee2aaSAndroid Build Coastguard Worker return rgs; 1168*c8dee2aaSAndroid Build Coastguard Worker }; 1169*c8dee2aaSAndroid Build Coastguard Worker 1170*c8dee2aaSAndroid Build Coastguard Worker // Clients can pass in a Float32Array with length 4 to this and the results 1171*c8dee2aaSAndroid Build Coastguard Worker // will be copied into that array. Otherwise, a new TypedArray will be allocated 1172*c8dee2aaSAndroid Build Coastguard Worker // and returned. 1173*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Vertices.prototype.bounds = function(optionalOutputArray) { 1174*c8dee2aaSAndroid Build Coastguard Worker this._bounds(_scratchFourFloatsAPtr); 1175*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 1176*c8dee2aaSAndroid Build Coastguard Worker if (optionalOutputArray) { 1177*c8dee2aaSAndroid Build Coastguard Worker optionalOutputArray.set(ta); 1178*c8dee2aaSAndroid Build Coastguard Worker return optionalOutputArray; 1179*c8dee2aaSAndroid Build Coastguard Worker } 1180*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 1181*c8dee2aaSAndroid Build Coastguard Worker }; 1182*c8dee2aaSAndroid Build Coastguard Worker 1183*c8dee2aaSAndroid Build Coastguard Worker // Run through the JS files that are added at compile time. 1184*c8dee2aaSAndroid Build Coastguard Worker if (CanvasKit._extraInitializations) { 1185*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._extraInitializations.forEach(function(init) { 1186*c8dee2aaSAndroid Build Coastguard Worker init(); 1187*c8dee2aaSAndroid Build Coastguard Worker }); 1188*c8dee2aaSAndroid Build Coastguard Worker } 1189*c8dee2aaSAndroid Build Coastguard Worker}; // end CanvasKit.onRuntimeInitialized, that is, anything changing prototypes or dynamic. 1190*c8dee2aaSAndroid Build Coastguard Worker 1191*c8dee2aaSAndroid Build Coastguard Worker// Accepts an object holding two canvaskit colors. 1192*c8dee2aaSAndroid Build Coastguard Worker// { 1193*c8dee2aaSAndroid Build Coastguard Worker// ambient: [r, g, b, a], 1194*c8dee2aaSAndroid Build Coastguard Worker// spot: [r, g, b, a], 1195*c8dee2aaSAndroid Build Coastguard Worker// } 1196*c8dee2aaSAndroid Build Coastguard Worker// Returns the same format. Note, if malloced colors are passed in, the memory 1197*c8dee2aaSAndroid Build Coastguard Worker// housing the passed in colors passed in will be overwritten with the computed 1198*c8dee2aaSAndroid Build Coastguard Worker// tonal colors. 1199*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.computeTonalColors = function(tonalColors) { 1200*c8dee2aaSAndroid Build Coastguard Worker // copy the colors into WASM 1201*c8dee2aaSAndroid Build Coastguard Worker var cPtrAmbi = copyColorToWasmNoScratch(tonalColors['ambient']); 1202*c8dee2aaSAndroid Build Coastguard Worker var cPtrSpot = copyColorToWasmNoScratch(tonalColors['spot']); 1203*c8dee2aaSAndroid Build Coastguard Worker // The output of this function will be the same pointers we passed in. 1204*c8dee2aaSAndroid Build Coastguard Worker this._computeTonalColors(cPtrAmbi, cPtrSpot); 1205*c8dee2aaSAndroid Build Coastguard Worker // Read the results out. 1206*c8dee2aaSAndroid Build Coastguard Worker var result = { 1207*c8dee2aaSAndroid Build Coastguard Worker 'ambient': copyColorFromWasm(cPtrAmbi), 1208*c8dee2aaSAndroid Build Coastguard Worker 'spot': copyColorFromWasm(cPtrSpot), 1209*c8dee2aaSAndroid Build Coastguard Worker }; 1210*c8dee2aaSAndroid Build Coastguard Worker // If the user passed us malloced colors in here, we don't want to clean them up. 1211*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cPtrAmbi, tonalColors['ambient']); 1212*c8dee2aaSAndroid Build Coastguard Worker freeArraysThatAreNotMallocedByUsers(cPtrSpot, tonalColors['spot']); 1213*c8dee2aaSAndroid Build Coastguard Worker return result; 1214*c8dee2aaSAndroid Build Coastguard Worker}; 1215*c8dee2aaSAndroid Build Coastguard Worker 1216*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.LTRBRect = function(l, t, r, b) { 1217*c8dee2aaSAndroid Build Coastguard Worker return Float32Array.of(l, t, r, b); 1218*c8dee2aaSAndroid Build Coastguard Worker}; 1219*c8dee2aaSAndroid Build Coastguard Worker 1220*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.XYWHRect = function(x, y, w, h) { 1221*c8dee2aaSAndroid Build Coastguard Worker return Float32Array.of(x, y, x+w, y+h); 1222*c8dee2aaSAndroid Build Coastguard Worker}; 1223*c8dee2aaSAndroid Build Coastguard Worker 1224*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.LTRBiRect = function(l, t, r, b) { 1225*c8dee2aaSAndroid Build Coastguard Worker return Int32Array.of(l, t, r, b); 1226*c8dee2aaSAndroid Build Coastguard Worker}; 1227*c8dee2aaSAndroid Build Coastguard Worker 1228*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.XYWHiRect = function(x, y, w, h) { 1229*c8dee2aaSAndroid Build Coastguard Worker return Int32Array.of(x, y, x+w, y+h); 1230*c8dee2aaSAndroid Build Coastguard Worker}; 1231*c8dee2aaSAndroid Build Coastguard Worker 1232*c8dee2aaSAndroid Build Coastguard Worker// RRectXY returns a TypedArray representing an RRect with the given rect and a radiusX and 1233*c8dee2aaSAndroid Build Coastguard Worker// radiusY for all 4 corners. 1234*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.RRectXY = function(rect, rx, ry) { 1235*c8dee2aaSAndroid Build Coastguard Worker return Float32Array.of( 1236*c8dee2aaSAndroid Build Coastguard Worker rect[0], rect[1], rect[2], rect[3], 1237*c8dee2aaSAndroid Build Coastguard Worker rx, ry, 1238*c8dee2aaSAndroid Build Coastguard Worker rx, ry, 1239*c8dee2aaSAndroid Build Coastguard Worker rx, ry, 1240*c8dee2aaSAndroid Build Coastguard Worker rx, ry, 1241*c8dee2aaSAndroid Build Coastguard Worker ); 1242*c8dee2aaSAndroid Build Coastguard Worker}; 1243*c8dee2aaSAndroid Build Coastguard Worker 1244*c8dee2aaSAndroid Build Coastguard Worker// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer()) 1245*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.MakeAnimatedImageFromEncoded = function(data) { 1246*c8dee2aaSAndroid Build Coastguard Worker data = new Uint8Array(data); 1247*c8dee2aaSAndroid Build Coastguard Worker 1248*c8dee2aaSAndroid Build Coastguard Worker var iptr = CanvasKit._malloc(data.byteLength); 1249*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.HEAPU8.set(data, iptr); 1250*c8dee2aaSAndroid Build Coastguard Worker var img = CanvasKit._decodeAnimatedImage(iptr, data.byteLength); 1251*c8dee2aaSAndroid Build Coastguard Worker if (!img) { 1252*c8dee2aaSAndroid Build Coastguard Worker Debug('Could not decode animated image'); 1253*c8dee2aaSAndroid Build Coastguard Worker return null; 1254*c8dee2aaSAndroid Build Coastguard Worker } 1255*c8dee2aaSAndroid Build Coastguard Worker return img; 1256*c8dee2aaSAndroid Build Coastguard Worker}; 1257*c8dee2aaSAndroid Build Coastguard Worker 1258*c8dee2aaSAndroid Build Coastguard Worker// data is a TypedArray or ArrayBuffer e.g. from fetch().then(resp.arrayBuffer()) 1259*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.MakeImageFromEncoded = function(data) { 1260*c8dee2aaSAndroid Build Coastguard Worker data = new Uint8Array(data); 1261*c8dee2aaSAndroid Build Coastguard Worker 1262*c8dee2aaSAndroid Build Coastguard Worker var iptr = CanvasKit._malloc(data.byteLength); 1263*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.HEAPU8.set(data, iptr); 1264*c8dee2aaSAndroid Build Coastguard Worker var img = CanvasKit._decodeImage(iptr, data.byteLength); 1265*c8dee2aaSAndroid Build Coastguard Worker if (!img) { 1266*c8dee2aaSAndroid Build Coastguard Worker Debug('Could not decode image'); 1267*c8dee2aaSAndroid Build Coastguard Worker return null; 1268*c8dee2aaSAndroid Build Coastguard Worker } 1269*c8dee2aaSAndroid Build Coastguard Worker return img; 1270*c8dee2aaSAndroid Build Coastguard Worker}; 1271*c8dee2aaSAndroid Build Coastguard Worker 1272*c8dee2aaSAndroid Build Coastguard Worker// A variable to hold a canvasElement which can be reused once created the first time. 1273*c8dee2aaSAndroid Build Coastguard Workervar memoizedCanvas2dElement = null; 1274*c8dee2aaSAndroid Build Coastguard Worker 1275*c8dee2aaSAndroid Build Coastguard Worker// Alternative to CanvasKit.MakeImageFromEncoded. Allows for CanvasKit users to take advantage of 1276*c8dee2aaSAndroid Build Coastguard Worker// browser APIs to decode images instead of using codecs included in the CanvasKit wasm binary. 1277*c8dee2aaSAndroid Build Coastguard Worker// Expects that the canvasImageSource has already loaded/decoded. 1278*c8dee2aaSAndroid Build Coastguard Worker// CanvasImageSource reference: https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource 1279*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.MakeImageFromCanvasImageSource = function(canvasImageSource) { 1280*c8dee2aaSAndroid Build Coastguard Worker var width = canvasImageSource.width; 1281*c8dee2aaSAndroid Build Coastguard Worker var height = canvasImageSource.height; 1282*c8dee2aaSAndroid Build Coastguard Worker 1283*c8dee2aaSAndroid Build Coastguard Worker if (!memoizedCanvas2dElement) { 1284*c8dee2aaSAndroid Build Coastguard Worker memoizedCanvas2dElement = document.createElement('canvas'); 1285*c8dee2aaSAndroid Build Coastguard Worker } 1286*c8dee2aaSAndroid Build Coastguard Worker memoizedCanvas2dElement.width = width; 1287*c8dee2aaSAndroid Build Coastguard Worker memoizedCanvas2dElement.height = height; 1288*c8dee2aaSAndroid Build Coastguard Worker 1289*c8dee2aaSAndroid Build Coastguard Worker var ctx2d = memoizedCanvas2dElement.getContext('2d', {willReadFrequently: true}); 1290*c8dee2aaSAndroid Build Coastguard Worker ctx2d.drawImage(canvasImageSource, 0, 0); 1291*c8dee2aaSAndroid Build Coastguard Worker 1292*c8dee2aaSAndroid Build Coastguard Worker var imageData = ctx2d.getImageData(0, 0, width, height); 1293*c8dee2aaSAndroid Build Coastguard Worker 1294*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit.MakeImage({ 1295*c8dee2aaSAndroid Build Coastguard Worker 'width': width, 1296*c8dee2aaSAndroid Build Coastguard Worker 'height': height, 1297*c8dee2aaSAndroid Build Coastguard Worker 'alphaType': CanvasKit.AlphaType.Unpremul, 1298*c8dee2aaSAndroid Build Coastguard Worker 'colorType': CanvasKit.ColorType.RGBA_8888, 1299*c8dee2aaSAndroid Build Coastguard Worker 'colorSpace': CanvasKit.ColorSpace.SRGB 1300*c8dee2aaSAndroid Build Coastguard Worker }, imageData.data, 4 * width); 1301*c8dee2aaSAndroid Build Coastguard Worker}; 1302*c8dee2aaSAndroid Build Coastguard Worker 1303*c8dee2aaSAndroid Build Coastguard Worker// pixels may be an array but Uint8Array or Uint8ClampedArray is recommended, 1304*c8dee2aaSAndroid Build Coastguard Worker// with the bytes representing the pixel values. 1305*c8dee2aaSAndroid Build Coastguard Worker// (e.g. each set of 4 bytes could represent RGBA values for a single pixel). 1306*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.MakeImage = function(info, pixels, bytesPerRow) { 1307*c8dee2aaSAndroid Build Coastguard Worker var pptr = CanvasKit._malloc(pixels.length); 1308*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.HEAPU8.set(pixels, pptr); // We always want to copy the bytes into the WASM heap. 1309*c8dee2aaSAndroid Build Coastguard Worker // No need to _free pptr, Image takes it with SkData::MakeFromMalloc 1310*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit._MakeImage(info, pptr, pixels.length, bytesPerRow); 1311*c8dee2aaSAndroid Build Coastguard Worker}; 1312*c8dee2aaSAndroid Build Coastguard Worker 1313*c8dee2aaSAndroid Build Coastguard Worker// Colors may be a Uint32Array of int colors, a Flat Float32Array of float colors 1314*c8dee2aaSAndroid Build Coastguard Worker// or a 2d Array of Float32Array(4) (deprecated) 1315*c8dee2aaSAndroid Build Coastguard Worker// the underlying Skia function accepts only int colors so it is recommended 1316*c8dee2aaSAndroid Build Coastguard Worker// to pass an array of int colors to avoid an extra conversion. 1317*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.MakeVertices = function(mode, positions, textureCoordinates, colors, 1318*c8dee2aaSAndroid Build Coastguard Worker indices, isVolatile) { 1319*c8dee2aaSAndroid Build Coastguard Worker // Default isVolatile to true if not set 1320*c8dee2aaSAndroid Build Coastguard Worker isVolatile = isVolatile === undefined ? true : isVolatile; 1321*c8dee2aaSAndroid Build Coastguard Worker var idxCount = (indices && indices.length) || 0; 1322*c8dee2aaSAndroid Build Coastguard Worker 1323*c8dee2aaSAndroid Build Coastguard Worker var flags = 0; 1324*c8dee2aaSAndroid Build Coastguard Worker // These flags are from SkVertices.h and should be kept in sync with those. 1325*c8dee2aaSAndroid Build Coastguard Worker if (textureCoordinates && textureCoordinates.length) { 1326*c8dee2aaSAndroid Build Coastguard Worker flags |= (1 << 0); 1327*c8dee2aaSAndroid Build Coastguard Worker } 1328*c8dee2aaSAndroid Build Coastguard Worker if (colors && colors.length) { 1329*c8dee2aaSAndroid Build Coastguard Worker flags |= (1 << 1); 1330*c8dee2aaSAndroid Build Coastguard Worker } 1331*c8dee2aaSAndroid Build Coastguard Worker if (!isVolatile) { 1332*c8dee2aaSAndroid Build Coastguard Worker flags |= (1 << 2); 1333*c8dee2aaSAndroid Build Coastguard Worker } 1334*c8dee2aaSAndroid Build Coastguard Worker 1335*c8dee2aaSAndroid Build Coastguard Worker var builder = new CanvasKit._VerticesBuilder(mode, positions.length / 2, idxCount, flags); 1336*c8dee2aaSAndroid Build Coastguard Worker 1337*c8dee2aaSAndroid Build Coastguard Worker copy1dArray(positions, 'HEAPF32', builder.positions()); 1338*c8dee2aaSAndroid Build Coastguard Worker if (builder.texCoords()) { 1339*c8dee2aaSAndroid Build Coastguard Worker copy1dArray(textureCoordinates, 'HEAPF32', builder.texCoords()); 1340*c8dee2aaSAndroid Build Coastguard Worker } 1341*c8dee2aaSAndroid Build Coastguard Worker if (builder.colors()) { 1342*c8dee2aaSAndroid Build Coastguard Worker copy1dArray(assureIntColors(colors), 'HEAPU32', builder.colors()); 1343*c8dee2aaSAndroid Build Coastguard Worker } 1344*c8dee2aaSAndroid Build Coastguard Worker if (builder.indices()) { 1345*c8dee2aaSAndroid Build Coastguard Worker copy1dArray(indices, 'HEAPU16', builder.indices()); 1346*c8dee2aaSAndroid Build Coastguard Worker } 1347*c8dee2aaSAndroid Build Coastguard Worker 1348*c8dee2aaSAndroid Build Coastguard Worker // Create the vertices, which owns the memory that the builder had allocated. 1349*c8dee2aaSAndroid Build Coastguard Worker return builder.detach(); 1350*c8dee2aaSAndroid Build Coastguard Worker}; 1351