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