diff --git a/benchmark/bench-wasm.ts b/benchmark/bench-wasm.ts new file mode 100755 index 00000000..cfd5068e --- /dev/null +++ b/benchmark/bench-wasm.ts @@ -0,0 +1,110 @@ +import { promises as fs } from 'fs' +import { join } from 'path' + +import b from 'benny' + +const wasm = require(`../wasm`) +const simd = require(`../wasm-simd`) + +async function run() { + await wasm.initWasm(fs.readFile(join(__dirname, '../wasm/index_bg.wasm'))) + await simd.initWasm(fs.readFile(join(__dirname, '../wasm-simd/index_bg.wasm'))) + + const svg1 = await fs.readFile(join(__dirname, '../example/text.svg')) + const tiger = await fs.readFile(join(__dirname, '../__test__/tiger.svg')) + const icon = await fs.readFile(join(__dirname, '../__test__/icon-alarm.svg')) + + await b.suite( + 'resize width', + b.add('resvg-js(Wasm)', () => { + const opts = { + background: '#eeebe6', + fitTo: { + mode: 'width', + value: 1200, + }, + logLevel: 'off', + } + const resvg = new wasm.Resvg(svg1, opts) + const pngData = resvg.render() + pngData.asPng() + }), + + b.add('resvg-js(Wasm SIMD)', () => { + const opts = { + background: '#eeebe6', + fitTo: { + mode: 'width', + value: 1200, + }, + logLevel: 'off', + } + const resvg = new simd.Resvg(svg1, opts) + const pngData = resvg.render() + pngData.asPng() + }), + + b.cycle(), + b.complete(), + ) + + await b.suite( + 'resize icon width', + b.add('resvg-js(Wasm)', () => { + const opts = { + fitTo: { + mode: 'width', + value: 386, + }, + logLevel: 'off', + } + const resvg = new wasm.Resvg(icon, opts) + const pngData = resvg.render() + pngData.asPng() + }), + + b.add('resvg-js(Wasm SIMD)', () => { + const opts = { + fitTo: { + mode: 'width', + value: 386, + }, + logLevel: 'off', + } + const resvg = new simd.Resvg(icon, opts) + const pngData = resvg.render() + pngData.asPng() + }), + + b.cycle(), + b.complete(), + ) + + await b.suite( + 'default options and no text', + b.add('resvg-js(Wasm)', () => { + const opts = { + logLevel: 'off', + } + const resvg = new wasm.Resvg(tiger, opts) + const pngData = resvg.render() + pngData.asPng() + }), + + b.add('resvg-js(Wasm SIMD)', () => { + const opts = { + logLevel: 'off', + } + const resvg = new simd.Resvg(tiger, opts) + const pngData = resvg.render() + pngData.asPng() + }), + + b.cycle(), + b.complete(), + ) +} + +run().catch((e) => { + console.error(e) +}) diff --git a/bundle.js b/bundle.js index 72c70dfd..959262a2 100644 --- a/bundle.js +++ b/bundle.js @@ -12,17 +12,17 @@ const commonOptions = { buildSync({ ...commonOptions, format: 'cjs', - outfile: 'wasm/index.js', + outfile: 'wasm-simd/index.js', }) buildSync({ ...commonOptions, format: 'esm', - outfile: 'wasm/index.mjs', + outfile: 'wasm-simd/index.mjs', }) buildSync({ ...commonOptions, format: 'iife', minify: true, globalName: 'resvg', - outfile: 'wasm/index.min.js', + outfile: 'wasm-simd/index.min.js', }) diff --git a/example/wasm-node.js b/example/wasm-node.js index e9b1afb0..e3a0487b 100644 --- a/example/wasm-node.js +++ b/example/wasm-node.js @@ -2,10 +2,16 @@ const fs = require('fs').promises const { join } = require('path') const { performance } = require('perf_hooks') -const { Resvg, initWasm } = require('../wasm') +const args = process.argv.slice(2) +const isSimd = args?.length > 0 && args[0] === '--simd' +const wasmDir = isSimd ? 'wasm-simd' : 'wasm' + +const { Resvg, initWasm } = require(`../${wasmDir}`) + +console.info(isSimd ? '🚀🚀 Enable SIMD' : '🐢🐢 Disable SIMD') async function main() { - await initWasm(fs.readFile(join(__dirname, '../wasm/index_bg.wasm'))) + await initWasm(fs.readFile(join(__dirname, `../${wasmDir}/index_bg.wasm`))) const svg = await fs.readFile(join(__dirname, './sprite.svg')) const opts = { diff --git a/package.json b/package.json index 2afb194f..e118b755 100644 --- a/package.json +++ b/package.json @@ -49,14 +49,19 @@ "scripts": { "artifacts": "napi artifacts", "bench": "node -r @swc-node/register benchmark/bench.ts", + "bench:wasm": "node -r @swc-node/register benchmark/bench-wasm.ts", "bundle": "run-p 'bundle:*'", "bundle:js": "node bundle.js", "bundle:dts": "dts-bundle-generator --external-types -o wasm/index.d.ts wasm-binding.ts", + "bundle:dts-simd": "dts-bundle-generator --external-types -o wasm-simd/index.d.ts wasm-binding.ts", "build": "napi build --platform --release --js js-binding.js --dts js-binding.d.ts", "build:debug": "napi build --platform --js js-binding.js --dts js-binding.d.ts", "build:wasm": "run-s build:wasm-web copy-wasm bundle", + "build:wasm-simd": "run-s build:wasm-simd-web copy-wasm-simd bundle", "build:wasm-web": "wasm-pack build --target web --out-name index --out-dir wasm/dist --release", + "build:wasm-simd-web": "RUSTFLAGS='-C target-feature=+simd128' wasm-pack build --target web --out-name index --out-dir wasm-simd/dist --release --mode no-install", "copy-wasm": "copyfiles -f wasm/dist/index_bg.wasm ./wasm", + "copy-wasm-simd": "copyfiles -f wasm-simd/dist/index_bg.wasm ./wasm-simd", "playground": "copyfiles -f playground/index.html ./wasm", "format": "run-p format:md format:json format:yaml format:source format:rs", "format:md": "prettier --parser markdown --write './**/*.md'", diff --git a/wasm-simd/index.d.ts b/wasm-simd/index.d.ts new file mode 100644 index 00000000..4bc10959 --- /dev/null +++ b/wasm-simd/index.d.ts @@ -0,0 +1,100 @@ +// Generated by dts-bundle-generator v6.12.0 + +declare class BBox { + free(): void; + /** + */ + height: number; + /** + */ + width: number; + /** + */ + x: number; + /** + */ + y: number; +} +declare class RenderedImage { + free(): void; + /** + * Write the image data to Uint8Array + * @returns {Uint8Array} + */ + asPng(): Uint8Array; + /** + * Get the PNG height + */ + readonly height: number; + /** + * Get the PNG width + */ + readonly width: number; +} +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; +export type ResvgRenderOptions = { + font?: { + loadSystemFonts?: boolean; + fontFiles?: string[]; + fontDirs?: string[]; + defaultFontFamily?: string; + defaultFontSize?: number; + serifFamily?: string; + sansSerifFamily?: string; + cursiveFamily?: string; + fantasyFamily?: string; + monospaceFamily?: string; + }; + dpi?: number; + languages?: string[]; + shapeRendering?: 0 // optimizeSpeed + | 1 // crispEdges + | 2; // geometricPrecision + textRendering?: 0 // optimizeSpeed + | 1 // optimizeLegibility + | 2; // geometricPrecision' + imageRendering?: 0 // optimizeQuality + | 1; // optimizeSpeed + fitTo?: { + mode: "original"; + } | { + mode: "width"; + value: number; + } | { + mode: "height"; + value: number; + } | { + mode: "zoom"; + value: number; + }; + background?: string; // Support CSS3 color, e.g. rgba(255, 255, 255, .8) + crop?: { + left: number; + top: number; + right?: number; + bottom?: number; + }; + logLevel?: "off" | "error" | "warn" | "info" | "debug" | "trace"; +}; +/** + * Initialize Wasm module + * @param module_or_path WebAssembly Module or .wasm url + * + */ +export declare const initWasm: (module_or_path: Promise | InitInput) => Promise; +export declare const Resvg: { + new (svg: Uint8Array | string, options?: ResvgRenderOptions): { + free(): void; + render(): RenderedImage; + toString(): string; + innerBBox(): BBox | undefined; + getBBox(): BBox | undefined; + cropByBBox(bbox: BBox): void; + imagesToResolve(): any[]; + resolveImage(href: string, buffer: Uint8Array): void; + readonly height: number; + readonly width: number; + }; +}; + +export {}; diff --git a/wasm-simd/index.js b/wasm-simd/index.js new file mode 100644 index 00000000..f502def4 --- /dev/null +++ b/wasm-simd/index.js @@ -0,0 +1,442 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// wasm-binding.ts +var wasm_binding_exports = {}; +__export(wasm_binding_exports, { + Resvg: () => Resvg2, + initWasm: () => initWasm +}); +module.exports = __toCommonJS(wasm_binding_exports); + +// wasm/dist/index.js +var wasm; +var heap = new Array(32).fill(void 0); +heap.push(void 0, null, true, false); +var heap_next = heap.length; +function addHeapObject(obj) { + if (heap_next === heap.length) + heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + heap[idx] = obj; + return idx; +} +function getObject(idx) { + return heap[idx]; +} +function dropObject(idx) { + if (idx < 36) + return; + heap[idx] = heap_next; + heap_next = idx; +} +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} +var WASM_VECTOR_LEN = 0; +var cachedUint8Memory0; +function getUint8Memory0() { + if (cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} +var cachedTextEncoder = new TextEncoder("utf-8"); +var encodeString = typeof cachedTextEncoder.encodeInto === "function" ? function(arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} : function(arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}; +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === void 0) { + const buf = cachedTextEncoder.encode(arg); + const ptr2 = malloc(buf.length); + getUint8Memory0().subarray(ptr2, ptr2 + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr2; + } + let len = arg.length; + let ptr = malloc(len); + const mem = getUint8Memory0(); + let offset = 0; + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 127) + break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3); + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + offset += ret.written; + } + WASM_VECTOR_LEN = offset; + return ptr; +} +function isLikeNone(x) { + return x === void 0 || x === null; +} +var cachedInt32Memory0; +function getInt32Memory0() { + if (cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} +var cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +function getStringFromWasm0(ptr, len) { + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} +function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); + } + return instance.ptr; +} +var BBox = class { + static __wrap(ptr) { + const obj = Object.create(BBox.prototype); + obj.ptr = ptr; + return obj; + } + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_bbox_free(ptr); + } + get x() { + const ret = wasm.__wbg_get_bbox_x(this.ptr); + return ret; + } + set x(arg0) { + wasm.__wbg_set_bbox_x(this.ptr, arg0); + } + get y() { + const ret = wasm.__wbg_get_bbox_y(this.ptr); + return ret; + } + set y(arg0) { + wasm.__wbg_set_bbox_y(this.ptr, arg0); + } + get width() { + const ret = wasm.__wbg_get_bbox_width(this.ptr); + return ret; + } + set width(arg0) { + wasm.__wbg_set_bbox_width(this.ptr, arg0); + } + get height() { + const ret = wasm.__wbg_get_bbox_height(this.ptr); + return ret; + } + set height(arg0) { + wasm.__wbg_set_bbox_height(this.ptr, arg0); + } +}; +var RenderedImage = class { + static __wrap(ptr) { + const obj = Object.create(RenderedImage.prototype); + obj.ptr = ptr; + return obj; + } + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_renderedimage_free(ptr); + } + get width() { + const ret = wasm.renderedimage_width(this.ptr); + return ret >>> 0; + } + get height() { + const ret = wasm.renderedimage_height(this.ptr); + return ret >>> 0; + } + asPng() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.renderedimage_asPng(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +}; +var Resvg = class { + static __wrap(ptr) { + const obj = Object.create(Resvg.prototype); + obj.ptr = ptr; + return obj; + } + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_resvg_free(ptr); + } + constructor(svg, options) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(options) ? 0 : passStringToWasm0(options, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + wasm.resvg_new(retptr, addHeapObject(svg), ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return Resvg.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + get width() { + const ret = wasm.resvg_width(this.ptr); + return ret; + } + get height() { + const ret = wasm.resvg_height(this.ptr); + return ret; + } + render() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.resvg_render(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return RenderedImage.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + toString() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.resvg_toString(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(r0, r1); + } + } + innerBBox() { + const ret = wasm.resvg_innerBBox(this.ptr); + return ret === 0 ? void 0 : BBox.__wrap(ret); + } + getBBox() { + const ret = wasm.resvg_getBBox(this.ptr); + return ret === 0 ? void 0 : BBox.__wrap(ret); + } + cropByBBox(bbox) { + _assertClass(bbox, BBox); + wasm.resvg_cropByBBox(this.ptr, bbox.ptr); + } + imagesToResolve() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.resvg_imagesToResolve(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + resolveImage(href, buffer) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(href, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + wasm.resvg_resolveImage(retptr, this.ptr, ptr0, len0, addHeapObject(buffer)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +}; +async function load(module2, imports) { + if (typeof Response === "function" && module2 instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === "function") { + try { + return await WebAssembly.instantiateStreaming(module2, imports); + } catch (e) { + if (module2.headers.get("Content-Type") != "application/wasm") { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + } else { + throw e; + } + } + } + const bytes = await module2.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + } else { + const instance = await WebAssembly.instantiate(module2, imports); + if (instance instanceof WebAssembly.Instance) { + return { instance, module: module2 }; + } else { + return instance; + } + } +} +function getImports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbg_new_651776e932b7e9c7 = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return addHeapObject(ret); + }; + imports.wbg.__wbg_buffer_de1150f91b23aa89 = function(arg0) { + const ret = getObject(arg0).buffer; + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_9ca61320599a2c84 = function(arg0, arg1, arg2) { + const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); + }; + imports.wbg.__wbg_new_97cf52648830a70d = function(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_instanceof_Uint8Array_fd17ec67c77de602 = function(arg0) { + const ret = getObject(arg0) instanceof Uint8Array; + return ret; + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof obj === "string" ? obj : void 0; + var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbg_new_2ab697f1555e0dbc = function() { + const ret = new Array(); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }; + imports.wbg.__wbg_push_811c8b08bf4ff9d5 = function(arg0, arg1) { + const ret = getObject(arg0).push(getObject(arg1)); + return ret; + }; + imports.wbg.__wbg_length_e09c0b925ab8de5d = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_set_a0172b213e2469e9 = function(arg0, arg1, arg2) { + getObject(arg0).set(getObject(arg1), arg2 >>> 0); + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + return imports; +} +function initMemory(imports, maybe_memory) { +} +function finalizeInit(instance, module2) { + wasm = instance.exports; + init.__wbindgen_wasm_module = module2; + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + return wasm; +} +async function init(input) { + if (typeof input === "undefined") { + input = new URL("index_bg.wasm", void 0); + } + const imports = getImports(); + if (typeof input === "string" || typeof Request === "function" && input instanceof Request || typeof URL === "function" && input instanceof URL) { + input = fetch(input); + } + initMemory(imports); + const { instance, module: module2 } = await load(await input, imports); + return finalizeInit(instance, module2); +} +var dist_default = init; + +// wasm-binding.ts +var initialized = false; +var initWasm = async (module_or_path) => { + if (initialized) { + throw new Error("Already initialized. The `initWasm()` function can be used only once."); + } + await dist_default(await module_or_path); + initialized = true; +}; +var Resvg2 = class extends Resvg { + constructor(svg, options) { + if (!initialized) + throw new Error("Wasm has not been initialized. Call `initWasm()` function."); + super(svg, JSON.stringify(options)); + } +}; diff --git a/wasm-simd/index.min.js b/wasm-simd/index.min.js new file mode 100644 index 00000000..a8a58673 --- /dev/null +++ b/wasm-simd/index.min.js @@ -0,0 +1 @@ +"use strict";var resvg=(()=>{var W=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var T=(e,t)=>{for(var n in t)W(e,n,{get:t[n],enumerable:!0})},L=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of E(t))!M.call(e,o)&&o!==n&&W(e,o,{get:()=>t[o],enumerable:!(i=S(t,o))||i.enumerable});return e};var C=e=>L(W({},"__esModule",{value:!0}),e);var V={};T(V,{Resvg:()=>J,initWasm:()=>H});var r,g=new Array(32).fill(void 0);g.push(void 0,null,!0,!1);var h=g.length;function b(e){h===g.length&&g.push(g.length+1);let t=h;return h=g[t],g[t]=e,t}function c(e){return g[e]}function z(e){e<36||(g[e]=h,h=e)}function d(e){let t=c(e);return z(e),t}var l=0,m;function v(){return m.byteLength===0&&(m=new Uint8Array(r.memory.buffer)),m}var x=new TextEncoder("utf-8"),P=typeof x.encodeInto=="function"?function(e,t){return x.encodeInto(e,t)}:function(e,t){let n=x.encode(e);return t.set(n),{read:e.length,written:n.length}};function k(e,t,n){if(n===void 0){let a=x.encode(e),w=t(a.length);return v().subarray(w,w+a.length).set(a),l=a.length,w}let i=e.length,o=t(i),f=v(),_=0;for(;_127)break;f[o+_]=a}if(_!==i){_!==0&&(e=e.slice(_)),o=n(o,i,i=_+e.length*3);let a=v().subarray(o+_,o+i);_+=P(e,a).written}return l=_,o}function j(e){return e==null}var A;function s(){return A.byteLength===0&&(A=new Int32Array(r.memory.buffer)),A}var B=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});B.decode();function I(e,t){return B.decode(v().subarray(e,e+t))}function F(e,t){if(!(e instanceof t))throw new Error(`expected instance of ${t.name}`);return e.ptr}var u=class{static __wrap(t){let n=Object.create(u.prototype);return n.ptr=t,n}__destroy_into_raw(){let t=this.ptr;return this.ptr=0,t}free(){let t=this.__destroy_into_raw();r.__wbg_bbox_free(t)}get x(){return r.__wbg_get_bbox_x(this.ptr)}set x(t){r.__wbg_set_bbox_x(this.ptr,t)}get y(){return r.__wbg_get_bbox_y(this.ptr)}set y(t){r.__wbg_set_bbox_y(this.ptr,t)}get width(){return r.__wbg_get_bbox_width(this.ptr)}set width(t){r.__wbg_set_bbox_width(this.ptr,t)}get height(){return r.__wbg_get_bbox_height(this.ptr)}set height(t){r.__wbg_set_bbox_height(this.ptr,t)}},y=class{static __wrap(t){let n=Object.create(y.prototype);return n.ptr=t,n}__destroy_into_raw(){let t=this.ptr;return this.ptr=0,t}free(){let t=this.__destroy_into_raw();r.__wbg_renderedimage_free(t)}get width(){return r.renderedimage_width(this.ptr)>>>0}get height(){return r.renderedimage_height(this.ptr)>>>0}asPng(){try{let o=r.__wbindgen_add_to_stack_pointer(-16);r.renderedimage_asPng(o,this.ptr);var t=s()[o/4+0],n=s()[o/4+1],i=s()[o/4+2];if(i)throw d(n);return d(t)}finally{r.__wbindgen_add_to_stack_pointer(16)}}},p=class{static __wrap(t){let n=Object.create(p.prototype);return n.ptr=t,n}__destroy_into_raw(){let t=this.ptr;return this.ptr=0,t}free(){let t=this.__destroy_into_raw();r.__wbg_resvg_free(t)}constructor(t,n){try{let w=r.__wbindgen_add_to_stack_pointer(-16);var i=j(n)?0:k(n,r.__wbindgen_malloc,r.__wbindgen_realloc),o=l;r.resvg_new(w,b(t),i,o);var f=s()[w/4+0],_=s()[w/4+1],a=s()[w/4+2];if(a)throw d(_);return p.__wrap(f)}finally{r.__wbindgen_add_to_stack_pointer(16)}}get width(){return r.resvg_width(this.ptr)}get height(){return r.resvg_height(this.ptr)}render(){try{let o=r.__wbindgen_add_to_stack_pointer(-16);r.resvg_render(o,this.ptr);var t=s()[o/4+0],n=s()[o/4+1],i=s()[o/4+2];if(i)throw d(n);return y.__wrap(t)}finally{r.__wbindgen_add_to_stack_pointer(16)}}toString(){try{let i=r.__wbindgen_add_to_stack_pointer(-16);r.resvg_toString(i,this.ptr);var t=s()[i/4+0],n=s()[i/4+1];return I(t,n)}finally{r.__wbindgen_add_to_stack_pointer(16),r.__wbindgen_free(t,n)}}innerBBox(){let t=r.resvg_innerBBox(this.ptr);return t===0?void 0:u.__wrap(t)}getBBox(){let t=r.resvg_getBBox(this.ptr);return t===0?void 0:u.__wrap(t)}cropByBBox(t){F(t,u),r.resvg_cropByBBox(this.ptr,t.ptr)}imagesToResolve(){try{let o=r.__wbindgen_add_to_stack_pointer(-16);r.resvg_imagesToResolve(o,this.ptr);var t=s()[o/4+0],n=s()[o/4+1],i=s()[o/4+2];if(i)throw d(n);return d(t)}finally{r.__wbindgen_add_to_stack_pointer(16)}}resolveImage(t,n){try{let f=r.__wbindgen_add_to_stack_pointer(-16),_=k(t,r.__wbindgen_malloc,r.__wbindgen_realloc),a=l;r.resvg_resolveImage(f,this.ptr,_,a,b(n));var i=s()[f/4+0],o=s()[f/4+1];if(o)throw d(i)}finally{r.__wbindgen_add_to_stack_pointer(16)}}};async function N(e,t){if(typeof Response=="function"&&e instanceof Response){if(typeof WebAssembly.instantiateStreaming=="function")try{return await WebAssembly.instantiateStreaming(e,t)}catch(i){if(e.headers.get("Content-Type")!="application/wasm")console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",i);else throw i}let n=await e.arrayBuffer();return await WebAssembly.instantiate(n,t)}else{let n=await WebAssembly.instantiate(e,t);return n instanceof WebAssembly.Instance?{instance:n,module:e}:n}}function q(){let e={};return e.wbg={},e.wbg.__wbg_new_651776e932b7e9c7=function(t,n){let i=new Error(I(t,n));return b(i)},e.wbg.__wbindgen_memory=function(){let t=r.memory;return b(t)},e.wbg.__wbg_buffer_de1150f91b23aa89=function(t){let n=c(t).buffer;return b(n)},e.wbg.__wbg_newwithbyteoffsetandlength_9ca61320599a2c84=function(t,n,i){let o=new Uint8Array(c(t),n>>>0,i>>>0);return b(o)},e.wbg.__wbindgen_object_drop_ref=function(t){d(t)},e.wbg.__wbg_new_97cf52648830a70d=function(t){let n=new Uint8Array(c(t));return b(n)},e.wbg.__wbg_instanceof_Uint8Array_fd17ec67c77de602=function(t){return c(t)instanceof Uint8Array},e.wbg.__wbindgen_string_get=function(t,n){let i=c(n),o=typeof i=="string"?i:void 0;var f=j(o)?0:k(o,r.__wbindgen_malloc,r.__wbindgen_realloc),_=l;s()[t/4+1]=_,s()[t/4+0]=f},e.wbg.__wbg_new_2ab697f1555e0dbc=function(){let t=new Array;return b(t)},e.wbg.__wbindgen_string_new=function(t,n){let i=I(t,n);return b(i)},e.wbg.__wbg_push_811c8b08bf4ff9d5=function(t,n){return c(t).push(c(n))},e.wbg.__wbg_length_e09c0b925ab8de5d=function(t){return c(t).length},e.wbg.__wbg_set_a0172b213e2469e9=function(t,n,i){c(t).set(c(n),i>>>0)},e.wbg.__wbindgen_throw=function(t,n){throw new Error(I(t,n))},e}function D(e,t){return r=e.exports,R.__wbindgen_wasm_module=t,A=new Int32Array(r.memory.buffer),m=new Uint8Array(r.memory.buffer),r}async function R(e){typeof e=="undefined"&&(e=new URL("index_bg.wasm",void 0));let t=q();(typeof e=="string"||typeof Request=="function"&&e instanceof Request||typeof URL=="function"&&e instanceof URL)&&(e=fetch(e));let{instance:n,module:i}=await N(await e,t);return D(n,i)}var U=R;var O=!1,H=async e=>{if(O)throw new Error("Already initialized. The `initWasm()` function can be used only once.");await U(await e),O=!0},J=class extends p{constructor(e,t){if(!O)throw new Error("Wasm has not been initialized. Call `initWasm()` function.");super(e,JSON.stringify(t))}};return C(V);})(); diff --git a/wasm-simd/index.mjs b/wasm-simd/index.mjs new file mode 100644 index 00000000..ede98fe8 --- /dev/null +++ b/wasm-simd/index.mjs @@ -0,0 +1,419 @@ +// wasm/dist/index.js +var wasm; +var heap = new Array(32).fill(void 0); +heap.push(void 0, null, true, false); +var heap_next = heap.length; +function addHeapObject(obj) { + if (heap_next === heap.length) + heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + heap[idx] = obj; + return idx; +} +function getObject(idx) { + return heap[idx]; +} +function dropObject(idx) { + if (idx < 36) + return; + heap[idx] = heap_next; + heap_next = idx; +} +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} +var WASM_VECTOR_LEN = 0; +var cachedUint8Memory0; +function getUint8Memory0() { + if (cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} +var cachedTextEncoder = new TextEncoder("utf-8"); +var encodeString = typeof cachedTextEncoder.encodeInto === "function" ? function(arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} : function(arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}; +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === void 0) { + const buf = cachedTextEncoder.encode(arg); + const ptr2 = malloc(buf.length); + getUint8Memory0().subarray(ptr2, ptr2 + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr2; + } + let len = arg.length; + let ptr = malloc(len); + const mem = getUint8Memory0(); + let offset = 0; + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 127) + break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3); + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + offset += ret.written; + } + WASM_VECTOR_LEN = offset; + return ptr; +} +function isLikeNone(x) { + return x === void 0 || x === null; +} +var cachedInt32Memory0; +function getInt32Memory0() { + if (cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} +var cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +function getStringFromWasm0(ptr, len) { + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} +function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); + } + return instance.ptr; +} +var BBox = class { + static __wrap(ptr) { + const obj = Object.create(BBox.prototype); + obj.ptr = ptr; + return obj; + } + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_bbox_free(ptr); + } + get x() { + const ret = wasm.__wbg_get_bbox_x(this.ptr); + return ret; + } + set x(arg0) { + wasm.__wbg_set_bbox_x(this.ptr, arg0); + } + get y() { + const ret = wasm.__wbg_get_bbox_y(this.ptr); + return ret; + } + set y(arg0) { + wasm.__wbg_set_bbox_y(this.ptr, arg0); + } + get width() { + const ret = wasm.__wbg_get_bbox_width(this.ptr); + return ret; + } + set width(arg0) { + wasm.__wbg_set_bbox_width(this.ptr, arg0); + } + get height() { + const ret = wasm.__wbg_get_bbox_height(this.ptr); + return ret; + } + set height(arg0) { + wasm.__wbg_set_bbox_height(this.ptr, arg0); + } +}; +var RenderedImage = class { + static __wrap(ptr) { + const obj = Object.create(RenderedImage.prototype); + obj.ptr = ptr; + return obj; + } + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_renderedimage_free(ptr); + } + get width() { + const ret = wasm.renderedimage_width(this.ptr); + return ret >>> 0; + } + get height() { + const ret = wasm.renderedimage_height(this.ptr); + return ret >>> 0; + } + asPng() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.renderedimage_asPng(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +}; +var Resvg = class { + static __wrap(ptr) { + const obj = Object.create(Resvg.prototype); + obj.ptr = ptr; + return obj; + } + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_resvg_free(ptr); + } + constructor(svg, options) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(options) ? 0 : passStringToWasm0(options, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + wasm.resvg_new(retptr, addHeapObject(svg), ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return Resvg.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + get width() { + const ret = wasm.resvg_width(this.ptr); + return ret; + } + get height() { + const ret = wasm.resvg_height(this.ptr); + return ret; + } + render() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.resvg_render(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return RenderedImage.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + toString() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.resvg_toString(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(r0, r1); + } + } + innerBBox() { + const ret = wasm.resvg_innerBBox(this.ptr); + return ret === 0 ? void 0 : BBox.__wrap(ret); + } + getBBox() { + const ret = wasm.resvg_getBBox(this.ptr); + return ret === 0 ? void 0 : BBox.__wrap(ret); + } + cropByBBox(bbox) { + _assertClass(bbox, BBox); + wasm.resvg_cropByBBox(this.ptr, bbox.ptr); + } + imagesToResolve() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.resvg_imagesToResolve(retptr, this.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r2 = getInt32Memory0()[retptr / 4 + 2]; + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + resolveImage(href, buffer) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(href, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + wasm.resvg_resolveImage(retptr, this.ptr, ptr0, len0, addHeapObject(buffer)); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +}; +async function load(module, imports) { + if (typeof Response === "function" && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === "function") { + try { + return await WebAssembly.instantiateStreaming(module, imports); + } catch (e) { + if (module.headers.get("Content-Type") != "application/wasm") { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + } else { + throw e; + } + } + } + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + } else { + const instance = await WebAssembly.instantiate(module, imports); + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + } else { + return instance; + } + } +} +function getImports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbg_new_651776e932b7e9c7 = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return addHeapObject(ret); + }; + imports.wbg.__wbg_buffer_de1150f91b23aa89 = function(arg0) { + const ret = getObject(arg0).buffer; + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_9ca61320599a2c84 = function(arg0, arg1, arg2) { + const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); + }; + imports.wbg.__wbg_new_97cf52648830a70d = function(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_instanceof_Uint8Array_fd17ec67c77de602 = function(arg0) { + const ret = getObject(arg0) instanceof Uint8Array; + return ret; + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof obj === "string" ? obj : void 0; + var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbg_new_2ab697f1555e0dbc = function() { + const ret = new Array(); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }; + imports.wbg.__wbg_push_811c8b08bf4ff9d5 = function(arg0, arg1) { + const ret = getObject(arg0).push(getObject(arg1)); + return ret; + }; + imports.wbg.__wbg_length_e09c0b925ab8de5d = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_set_a0172b213e2469e9 = function(arg0, arg1, arg2) { + getObject(arg0).set(getObject(arg1), arg2 >>> 0); + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + return imports; +} +function initMemory(imports, maybe_memory) { +} +function finalizeInit(instance, module) { + wasm = instance.exports; + init.__wbindgen_wasm_module = module; + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + return wasm; +} +async function init(input) { + if (typeof input === "undefined") { + input = new URL("index_bg.wasm", void 0); + } + const imports = getImports(); + if (typeof input === "string" || typeof Request === "function" && input instanceof Request || typeof URL === "function" && input instanceof URL) { + input = fetch(input); + } + initMemory(imports); + const { instance, module } = await load(await input, imports); + return finalizeInit(instance, module); +} +var dist_default = init; + +// wasm-binding.ts +var initialized = false; +var initWasm = async (module_or_path) => { + if (initialized) { + throw new Error("Already initialized. The `initWasm()` function can be used only once."); + } + await dist_default(await module_or_path); + initialized = true; +}; +var Resvg2 = class extends Resvg { + constructor(svg, options) { + if (!initialized) + throw new Error("Wasm has not been initialized. Call `initWasm()` function."); + super(svg, JSON.stringify(options)); + } +}; +export { + Resvg2 as Resvg, + initWasm +}; diff --git a/wasm-simd/index_bg.wasm b/wasm-simd/index_bg.wasm new file mode 100644 index 00000000..157b0275 Binary files /dev/null and b/wasm-simd/index_bg.wasm differ