1*c8dee2aaSAndroid Build Coastguard Worker// Adds compile-time JS functions to augment the CanvasKit interface. 2*c8dee2aaSAndroid Build Coastguard Worker// Specifically, anything that should only be on the Skottie builds of canvaskit. 3*c8dee2aaSAndroid Build Coastguard Worker 4*c8dee2aaSAndroid Build Coastguard Worker// assets is a dictionary of named blobs: { key: ArrayBuffer, ... } 5*c8dee2aaSAndroid Build Coastguard Worker// The keys should be well-behaved strings - they're turned into null-terminated 6*c8dee2aaSAndroid Build Coastguard Worker// strings for the native side. 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker// prop_filter_prefix is an optional string acting as a name filter for selecting 9*c8dee2aaSAndroid Build Coastguard Worker// "interesting" Lottie properties (surfaced in the embedded player controls) 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker// soundMap is an optional object that maps string names to AudioPlayers 12*c8dee2aaSAndroid Build Coastguard Worker// AudioPlayers manage a single audio layer with a seek function 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker// logger is an optional logging object, expected to provide two functions: 15*c8dee2aaSAndroid Build Coastguard Worker// - onError(err_str, json_node_str) 16*c8dee2aaSAndroid Build Coastguard Worker// - onWarning(wrn_str, json_node_str) 17*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.MakeManagedAnimation = function(json, assets, prop_filter_prefix, soundMap, logger) { 18*c8dee2aaSAndroid Build Coastguard Worker if (!CanvasKit._MakeManagedAnimation) { 19*c8dee2aaSAndroid Build Coastguard Worker throw 'Not compiled with MakeManagedAnimation'; 20*c8dee2aaSAndroid Build Coastguard Worker } 21*c8dee2aaSAndroid Build Coastguard Worker if (!prop_filter_prefix) { 22*c8dee2aaSAndroid Build Coastguard Worker prop_filter_prefix = ''; 23*c8dee2aaSAndroid Build Coastguard Worker } 24*c8dee2aaSAndroid Build Coastguard Worker if (!assets) { 25*c8dee2aaSAndroid Build Coastguard Worker return CanvasKit._MakeManagedAnimation(json, 0, nullptr, nullptr, nullptr, prop_filter_prefix, 26*c8dee2aaSAndroid Build Coastguard Worker soundMap, logger); 27*c8dee2aaSAndroid Build Coastguard Worker } 28*c8dee2aaSAndroid Build Coastguard Worker var assetNamePtrs = []; 29*c8dee2aaSAndroid Build Coastguard Worker var assetDataPtrs = []; 30*c8dee2aaSAndroid Build Coastguard Worker var assetSizes = []; 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker var assetKeys = Object.keys(assets || {}); 33*c8dee2aaSAndroid Build Coastguard Worker for (var i = 0; i < assetKeys.length; i++) { 34*c8dee2aaSAndroid Build Coastguard Worker var key = assetKeys[i]; 35*c8dee2aaSAndroid Build Coastguard Worker var buffer = assets[key]; 36*c8dee2aaSAndroid Build Coastguard Worker var data = new Uint8Array(buffer); 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker var iptr = CanvasKit._malloc(data.byteLength); 39*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.HEAPU8.set(data, iptr); 40*c8dee2aaSAndroid Build Coastguard Worker assetDataPtrs.push(iptr); 41*c8dee2aaSAndroid Build Coastguard Worker assetSizes.push(data.byteLength); 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker // lengthBytesUTF8 and stringToUTF8Array are defined in the emscripten 44*c8dee2aaSAndroid Build Coastguard Worker // JS. See https://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#stringToUTF8 45*c8dee2aaSAndroid Build Coastguard Worker // Add 1 for null terminator 46*c8dee2aaSAndroid Build Coastguard Worker var strLen = lengthBytesUTF8(key) + 1; 47*c8dee2aaSAndroid Build Coastguard Worker var strPtr = CanvasKit._malloc(strLen); 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker stringToUTF8(key, strPtr, strLen); 50*c8dee2aaSAndroid Build Coastguard Worker assetNamePtrs.push(strPtr); 51*c8dee2aaSAndroid Build Coastguard Worker } 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker // Not entirely sure if it matters, but the uintptr_t are 32 bits 54*c8dee2aaSAndroid Build Coastguard Worker // we want to copy our array of uintptr_t into the right size memory. 55*c8dee2aaSAndroid Build Coastguard Worker var namesPtr = copy1dArray(assetNamePtrs, "HEAPU32"); 56*c8dee2aaSAndroid Build Coastguard Worker var assetsPtr = copy1dArray(assetDataPtrs, "HEAPU32"); 57*c8dee2aaSAndroid Build Coastguard Worker var assetSizesPtr = copy1dArray(assetSizes, "HEAPU32"); 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker var anim = CanvasKit._MakeManagedAnimation(json, assetKeys.length, namesPtr, 60*c8dee2aaSAndroid Build Coastguard Worker assetsPtr, assetSizesPtr, prop_filter_prefix, 61*c8dee2aaSAndroid Build Coastguard Worker soundMap, logger); 62*c8dee2aaSAndroid Build Coastguard Worker 63*c8dee2aaSAndroid Build Coastguard Worker // The C++ code has made copies of the asset and string data, so free our copies. 64*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(namesPtr); 65*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(assetsPtr); 66*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._free(assetSizesPtr); 67*c8dee2aaSAndroid Build Coastguard Worker 68*c8dee2aaSAndroid Build Coastguard Worker return anim; 69*c8dee2aaSAndroid Build Coastguard Worker}; 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard WorkerCanvasKit.SlottableTextProperty = function(t) { 72*c8dee2aaSAndroid Build Coastguard Worker // Use [''] to tell closure not to minify the names 73*c8dee2aaSAndroid Build Coastguard Worker t['text'] = t['text'] || ""; 74*c8dee2aaSAndroid Build Coastguard Worker t['textSize'] = t['textSize'] || 0; 75*c8dee2aaSAndroid Build Coastguard Worker t['minTextSize'] = t['minTextSize'] || 0; 76*c8dee2aaSAndroid Build Coastguard Worker t['maxTextSize'] = t['maxTextSize'] || Number.MAX_VALUE; 77*c8dee2aaSAndroid Build Coastguard Worker t['strokeWidth'] = t['strokeWidth'] || 0; 78*c8dee2aaSAndroid Build Coastguard Worker t['lineHeight'] = t['lineHeight'] || 0; 79*c8dee2aaSAndroid Build Coastguard Worker t['lineShift'] = t['lineShift'] || 0; 80*c8dee2aaSAndroid Build Coastguard Worker t['ascent'] = t['ascent'] || 0; 81*c8dee2aaSAndroid Build Coastguard Worker t['maxLines'] = t['maxLines'] || 0; 82*c8dee2aaSAndroid Build Coastguard Worker t['horizAlign'] = t['horizAlign'] || CanvasKit.TextAlign.Left; 83*c8dee2aaSAndroid Build Coastguard Worker t['vertAlign'] = t['vertAlign'] || CanvasKit.VerticalTextAlign.Top; 84*c8dee2aaSAndroid Build Coastguard Worker t['strokeJoin'] = t['strokeJoin'] || CanvasKit.StrokeJoin.Miter; 85*c8dee2aaSAndroid Build Coastguard Worker t['direction'] = t['direction'] || CanvasKit.TextDirection.LTR; 86*c8dee2aaSAndroid Build Coastguard Worker t['linebreak'] = t['linebreak'] || CanvasKit.LineBreakType.HardLineBreak; 87*c8dee2aaSAndroid Build Coastguard Worker t['resize'] = t['resize'] || CanvasKit.ResizePolicy.None; 88*c8dee2aaSAndroid Build Coastguard Worker 89*c8dee2aaSAndroid Build Coastguard Worker if (!t['fillColor']) { 90*c8dee2aaSAndroid Build Coastguard Worker t['fillColor'] = CanvasKit.TRANSPARENT; 91*c8dee2aaSAndroid Build Coastguard Worker } 92*c8dee2aaSAndroid Build Coastguard Worker if (!t['strokeColor']) { 93*c8dee2aaSAndroid Build Coastguard Worker t['strokeColor'] = CanvasKit.TRANSPARENT; 94*c8dee2aaSAndroid Build Coastguard Worker } 95*c8dee2aaSAndroid Build Coastguard Worker if (!t['boundingBox']) { 96*c8dee2aaSAndroid Build Coastguard Worker t['boundingBox'] = [0,0,0,0]; 97*c8dee2aaSAndroid Build Coastguard Worker } 98*c8dee2aaSAndroid Build Coastguard Worker return t; 99*c8dee2aaSAndroid Build Coastguard Worker}; 100*c8dee2aaSAndroid Build Coastguard Worker 101*c8dee2aaSAndroid Build Coastguard Worker(function(CanvasKit){ 102*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._extraInitializations = CanvasKit._extraInitializations || []; 103*c8dee2aaSAndroid Build Coastguard Worker CanvasKit._extraInitializations.push(function() { 104*c8dee2aaSAndroid Build Coastguard Worker 105*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Animation.prototype.render = function(canvas, dstRect) { 106*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(dstRect, _scratchFourFloatsAPtr); 107*c8dee2aaSAndroid Build Coastguard Worker this._render(canvas, _scratchFourFloatsAPtr); 108*c8dee2aaSAndroid Build Coastguard Worker }; 109*c8dee2aaSAndroid Build Coastguard Worker 110*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.Animation.prototype.size = function(optSize) { 111*c8dee2aaSAndroid Build Coastguard Worker // This will copy 2 floats into a space for 4 floats 112*c8dee2aaSAndroid Build Coastguard Worker this._size(_scratchFourFloatsAPtr); 113*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 114*c8dee2aaSAndroid Build Coastguard Worker if (optSize) { 115*c8dee2aaSAndroid Build Coastguard Worker // We cannot call optSize.set() because it is an error to call .set() with 116*c8dee2aaSAndroid Build Coastguard Worker // a source bigger than the destination. 117*c8dee2aaSAndroid Build Coastguard Worker optSize[0] = ta[0]; 118*c8dee2aaSAndroid Build Coastguard Worker optSize[1] = ta[1]; 119*c8dee2aaSAndroid Build Coastguard Worker return optSize; 120*c8dee2aaSAndroid Build Coastguard Worker } 121*c8dee2aaSAndroid Build Coastguard Worker // Be sure to return a copy of just the first 2 values. 122*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(0, 2); 123*c8dee2aaSAndroid Build Coastguard Worker }; 124*c8dee2aaSAndroid Build Coastguard Worker 125*c8dee2aaSAndroid Build Coastguard Worker if (CanvasKit.ManagedAnimation) { 126*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.render = function(canvas, dstRect) { 127*c8dee2aaSAndroid Build Coastguard Worker copyRectToWasm(dstRect, _scratchFourFloatsAPtr); 128*c8dee2aaSAndroid Build Coastguard Worker this._render(canvas, _scratchFourFloatsAPtr); 129*c8dee2aaSAndroid Build Coastguard Worker }; 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.seek = function(t, optDamageRect) { 132*c8dee2aaSAndroid Build Coastguard Worker this._seek(t, _scratchFourFloatsAPtr); 133*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 134*c8dee2aaSAndroid Build Coastguard Worker if (optDamageRect) { 135*c8dee2aaSAndroid Build Coastguard Worker optDamageRect.set(ta); 136*c8dee2aaSAndroid Build Coastguard Worker return optDamageRect; 137*c8dee2aaSAndroid Build Coastguard Worker } 138*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 139*c8dee2aaSAndroid Build Coastguard Worker }; 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.seekFrame = function(frame, optDamageRect) { 142*c8dee2aaSAndroid Build Coastguard Worker this._seekFrame(frame, _scratchFourFloatsAPtr); 143*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 144*c8dee2aaSAndroid Build Coastguard Worker if (optDamageRect) { 145*c8dee2aaSAndroid Build Coastguard Worker optDamageRect.set(ta); 146*c8dee2aaSAndroid Build Coastguard Worker return optDamageRect; 147*c8dee2aaSAndroid Build Coastguard Worker } 148*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(); 149*c8dee2aaSAndroid Build Coastguard Worker }; 150*c8dee2aaSAndroid Build Coastguard Worker 151*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.setColor = function(key, color) { 152*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color); 153*c8dee2aaSAndroid Build Coastguard Worker return this._setColor(key, cPtr); 154*c8dee2aaSAndroid Build Coastguard Worker }; 155*c8dee2aaSAndroid Build Coastguard Worker 156*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.setColorSlot = function(key, color) { 157*c8dee2aaSAndroid Build Coastguard Worker var cPtr = copyColorToWasm(color); 158*c8dee2aaSAndroid Build Coastguard Worker return this._setColorSlot(key, cPtr); 159*c8dee2aaSAndroid Build Coastguard Worker }; 160*c8dee2aaSAndroid Build Coastguard Worker 161*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.getColorSlot = function(key) { 162*c8dee2aaSAndroid Build Coastguard Worker this._getColorSlot(key, _scratchColorPtr); 163*c8dee2aaSAndroid Build Coastguard Worker var fourFloats = copyColorFromWasm(_scratchColorPtr); 164*c8dee2aaSAndroid Build Coastguard Worker if (fourFloats[0] == -1) { 165*c8dee2aaSAndroid Build Coastguard Worker return null; 166*c8dee2aaSAndroid Build Coastguard Worker } 167*c8dee2aaSAndroid Build Coastguard Worker return fourFloats; 168*c8dee2aaSAndroid Build Coastguard Worker } 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.setVec2Slot = function(key, vec) { 171*c8dee2aaSAndroid Build Coastguard Worker copy1dArray(vec, 'HEAPF32', _scratchThreeFloatsAPtr); 172*c8dee2aaSAndroid Build Coastguard Worker return this._setVec2Slot(key, _scratchThreeFloatsAPtr); 173*c8dee2aaSAndroid Build Coastguard Worker }; 174*c8dee2aaSAndroid Build Coastguard Worker 175*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.getVec2Slot = function(key) { 176*c8dee2aaSAndroid Build Coastguard Worker this._getVec2Slot(key, _scratchThreeFloatsAPtr); 177*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchThreeFloatsA['toTypedArray'](); 178*c8dee2aaSAndroid Build Coastguard Worker if (ta[2] === -1) { 179*c8dee2aaSAndroid Build Coastguard Worker return null; 180*c8dee2aaSAndroid Build Coastguard Worker } 181*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(0, 2); 182*c8dee2aaSAndroid Build Coastguard Worker } 183*c8dee2aaSAndroid Build Coastguard Worker 184*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.setTextSlot = function(key, textValue) { 185*c8dee2aaSAndroid Build Coastguard Worker var fillPtr = copyColorToWasm(textValue['fillColor'], _scratchColorPtr); 186*c8dee2aaSAndroid Build Coastguard Worker var strokePtr = copyColorToWasm(textValue['strokeColor'], _scratchFourFloatsAPtr); 187*c8dee2aaSAndroid Build Coastguard Worker var boxPtr = copyRectToWasm(textValue['boundingBox'], _scratchFourFloatsBPtr); 188*c8dee2aaSAndroid Build Coastguard Worker 189*c8dee2aaSAndroid Build Coastguard Worker textValue['_fillColorPtr'] = fillPtr; 190*c8dee2aaSAndroid Build Coastguard Worker textValue['_strokeColorPtr'] = strokePtr; 191*c8dee2aaSAndroid Build Coastguard Worker textValue['_boundingBoxPtr'] = boxPtr; 192*c8dee2aaSAndroid Build Coastguard Worker 193*c8dee2aaSAndroid Build Coastguard Worker return this._setTextSlot(key, textValue); 194*c8dee2aaSAndroid Build Coastguard Worker } 195*c8dee2aaSAndroid Build Coastguard Worker 196*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.setTransform = function(key, anchor, position, scale, rotation, skew, skew_axis) { 197*c8dee2aaSAndroid Build Coastguard Worker let transformData = [anchor[0], anchor[1], position[0], position[1], scale[0], scale[1], rotation, skew, skew_axis]; 198*c8dee2aaSAndroid Build Coastguard Worker const tPtr = copy1dArray(transformData, 'HEAPF32', _scratch3x3MatrixPtr); 199*c8dee2aaSAndroid Build Coastguard Worker return this._setTransform(key, tPtr); 200*c8dee2aaSAndroid Build Coastguard Worker }; 201*c8dee2aaSAndroid Build Coastguard Worker 202*c8dee2aaSAndroid Build Coastguard Worker CanvasKit.ManagedAnimation.prototype.size = function(optSize) { 203*c8dee2aaSAndroid Build Coastguard Worker // This will copy 2 floats into a space for 4 floats 204*c8dee2aaSAndroid Build Coastguard Worker this._size(_scratchFourFloatsAPtr); 205*c8dee2aaSAndroid Build Coastguard Worker var ta = _scratchFourFloatsA['toTypedArray'](); 206*c8dee2aaSAndroid Build Coastguard Worker if (optSize) { 207*c8dee2aaSAndroid Build Coastguard Worker // We cannot call optSize.set() because it is an error to call .set() with 208*c8dee2aaSAndroid Build Coastguard Worker // a source bigger than the destination. 209*c8dee2aaSAndroid Build Coastguard Worker optSize[0] = ta[0]; 210*c8dee2aaSAndroid Build Coastguard Worker optSize[1] = ta[1]; 211*c8dee2aaSAndroid Build Coastguard Worker return optSize; 212*c8dee2aaSAndroid Build Coastguard Worker } 213*c8dee2aaSAndroid Build Coastguard Worker // Be sure to return a copy of just the first 2 values. 214*c8dee2aaSAndroid Build Coastguard Worker return ta.slice(0, 2); 215*c8dee2aaSAndroid Build Coastguard Worker }; 216*c8dee2aaSAndroid Build Coastguard Worker } 217*c8dee2aaSAndroid Build Coastguard Worker 218*c8dee2aaSAndroid Build Coastguard Worker 219*c8dee2aaSAndroid Build Coastguard Worker}); 220*c8dee2aaSAndroid Build Coastguard Worker}(Module)); // When this file is loaded in, the high level object is "Module"; 221