Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions benchmark/bench-wasm.ts
Original file line number Diff line number Diff line change
@@ -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)
})
6 changes: 3 additions & 3 deletions bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
})
10 changes: 8 additions & 2 deletions example/wasm-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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'",
Expand Down
100 changes: 100 additions & 0 deletions wasm-simd/index.d.ts
Original file line number Diff line number Diff line change
@@ -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> | InitInput) => Promise<void>;
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 {};
Loading