Import Cobalt 21.master.0.253153
diff --git a/src/third_party/skia/modules/pathkit/helper.js b/src/third_party/skia/modules/pathkit/helper.js
new file mode 100644
index 0000000..82713ba
--- /dev/null
+++ b/src/third_party/skia/modules/pathkit/helper.js
@@ -0,0 +1,108 @@
+// Adds any extra JS functions/helpers we want to the PathKit Library.
+// Wrapped in a function to avoid leaking global variables.
+(function(PathKit){
+
+ // Caching the Float32Arrays can save having to reallocate them
+ // over and over again.
+ var Float32ArrayCache = {};
+
+ // Takes a 2D array of commands and puts them into the WASM heap
+ // as a 1D array. This allows them to referenced from the C++ code.
+ // Returns a 2 element array, with the first item being essentially a
+ // pointer to the array and the second item being the length of
+ // the new 1D array.
+ //
+ // Example usage:
+ // let cmds = [
+ // [PathKit.MOVE_VERB, 0, 10],
+ // [PathKit.LINE_VERB, 30, 40],
+ // [PathKit.QUAD_VERB, 20, 50, 45, 60],
+ // ];
+ //
+ // // The following uses ES6 syntactic sugar "Array Destructuring".
+ // // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring
+ // let [ptr, len] = PathKit.loadCmdsTypedArray(cmds);
+ // let path = PathKit.FromCmds(ptr, len);
+ //
+ // If arguments at index 1... in each cmd row are strings, they will be
+ // parsed as hex, and then converted to floats using SkBits2FloatUnsigned
+ PathKit.loadCmdsTypedArray = function(arr) {
+ var len = 0;
+ for (var r = 0; r < arr.length; r++) {
+ len += arr[r].length;
+ }
+
+ var ta;
+ if (Float32ArrayCache[len]) {
+ ta = Float32ArrayCache[len];
+ } else {
+ ta = new Float32Array(len);
+ Float32ArrayCache[len] = ta;
+ }
+ // Flatten into a 1d array
+ var i = 0;
+ for (var r = 0; r < arr.length; r++) {
+ for (var c = 0; c < arr[r].length; c++) {
+ var item = arr[r][c];
+ if (typeof item === 'string') {
+ // Converts hex to an int, which can be passed to SkBits2FloatUnsigned
+ item = PathKit.SkBits2FloatUnsigned(parseInt(item));
+ }
+ ta[i] = item;
+ i++;
+ }
+ }
+
+ var ptr = PathKit._malloc(ta.length * ta.BYTES_PER_ELEMENT);
+ PathKit.HEAPF32.set(ta, ptr / ta.BYTES_PER_ELEMENT);
+ return [ptr, len];
+ }
+
+ // Experimentation has shown that using TypedArrays to pass arrays from
+ // JS to C++ is faster than passing the JS Arrays across.
+ // See above for example of cmds.
+ PathKit.FromCmds = function(cmds) {
+ var ptrLen = PathKit.loadCmdsTypedArray(cmds);
+ var path = PathKit._FromCmds(ptrLen[0], ptrLen[1]);
+ // TODO(kjlubick): cache this memory blob somehow.
+ PathKit._free(ptrLen[0]);
+ return path;
+ }
+
+ /**
+ * A common pattern is to call this function in sequence with the same
+ * params. We can just remember the last one to speed things up.
+ * Caching in this way is about a 10-15x speed up.
+ * See externs.js for this definition
+ * @type {CubicMap}
+ */
+ var cachedMap;
+ var _cpx1, _cpy1, _cpx2, _cpy2;
+
+ PathKit.cubicYFromX = function(cpx1, cpy1, cpx2, cpy2, X) {
+ if (!cachedMap || _cpx1 !== cpx1 || _cpy1 !== cpy1 ||
+ _cpx2 !== cpx2 || _cpy2 !== cpy2) {
+ if (cachedMap) {
+ // Delete previous cached map to avoid memory leaks.
+ cachedMap.delete()
+ }
+ cachedMap = new PathKit._SkCubicMap([cpx1, cpy1], [cpx2, cpy2]);
+ _cpx1 = cpx1, _cpy1 = cpy1, _cpx2 = cpx2, _cpy2 = cpy2;
+ }
+ return cachedMap.computeYFromX(X);
+ }
+
+ PathKit.cubicPtFromT = function(cpx1, cpy1, cpx2, cpy2, T) {
+ if (!cachedMap || _cpx1 !== cpx1 || _cpy1 !== cpy1 ||
+ _cpx2 !== cpx2 || _cpy2 !== cpy2) {
+ if (cachedMap) {
+ // Delete previous cached map to avoid memory leaks.
+ cachedMap.delete()
+ }
+ cachedMap = new PathKit._SkCubicMap([cpx1, cpy1], [cpx2, cpy2]);
+ _cpx1 = cpx1, _cpy1 = cpy1, _cpx2 = cpx2, _cpy2 = cpy2;
+ }
+ return cachedMap.computePtFromT(T);
+ }
+}(Module)); // When this file is loaded in, the high level object is "Module";
+