Skip to content

Commit 89b4be0

Browse files
authored
Switch to @resvg/resvg-wasm for generate-images (go-gitea#35415)
Use the WASM module of [`resvg-js`](https://github.com/thx/resvg-js) to replace `fabric` and the problematic native `canvas` dependency. WASM works cross-platform so we can include it in the main `package.json`.
1 parent 09d1f35 commit 89b4be0

File tree

11 files changed

+24
-1281
lines changed

11 files changed

+24
-1281
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ cpu.out
7474
/tests/*.ini
7575
/tests/**/*.git/**/*.sample
7676
/node_modules
77-
/tools/node_modules
7877
/.venv
7978
/yarn.lock
8079
/yarn-error.log

Makefile

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ node-check:
230230

231231
.PHONY: clean-all
232232
clean-all: clean ## delete backend, frontend and integration files
233-
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules tools/node_modules
233+
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules
234234

235235
.PHONY: clean
236236
clean: ## delete backend and integration files
@@ -847,10 +847,6 @@ node_modules: pnpm-lock.yaml
847847
pnpm install --frozen-lockfile
848848
@touch node_modules
849849

850-
tools/node_modules: tools/package.json
851-
cd tools && pnpm install
852-
@touch tools/node_modules
853-
854850
.venv: uv.lock
855851
uv sync
856852
@touch .venv
@@ -925,7 +921,7 @@ generate-gitignore: ## update gitignore files
925921
$(GO) run build/generate-gitignores.go
926922

927923
.PHONY: generate-images
928-
generate-images: | node_modules tools/node_modules ## generate images (requires cairo development packages)
924+
generate-images: | node_modules ## generate images
929925
cd tools && node generate-images.js $(TAGS)
930926

931927
.PHONY: generate-manpage

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"@github/text-expander-element": "2.9.2",
1616
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
1717
"@primer/octicons": "19.15.5",
18+
"@resvg/resvg-wasm": "2.6.2",
1819
"@silverwind/vue3-calendar-heatmap": "2.0.6",
1920
"@techknowlogick/license-checker-webpack-plugin": "0.3.0",
2021
"add-asset-webpack-plugin": "3.0.0",

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
-2.83 KB
Loading
-2.84 KB
Loading

public/assets/img/favicon.png

-2.52 KB
Loading

public/assets/img/logo.png

-8.14 KB
Loading

tools/generate-images.js

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env node
2-
import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node'; // eslint-disable-line import-x/no-unresolved
2+
import {initWasm, Resvg} from '@resvg/resvg-wasm';
33
import {optimize} from 'svgo';
44
import {readFile, writeFile} from 'node:fs/promises';
55
import {argv, exit} from 'node:process';
@@ -27,37 +27,23 @@ async function generate(svg, path, {size, bg}) {
2727
return;
2828
}
2929

30-
const {objects, options} = await loadSVGFromString(svg);
31-
const canvas = new Canvas();
32-
canvas.setDimensions({width: size, height: size});
33-
const ctx = canvas.getContext('2d');
34-
ctx.scale(options.width ? (size / options.width) : 1, options.height ? (size / options.height) : 1);
35-
36-
if (bg) {
37-
canvas.add(new Rect({
38-
left: 0,
39-
top: 0,
40-
height: size * (1 / (size / options.height)),
41-
width: size * (1 / (size / options.width)),
42-
fill: 'white',
43-
}));
44-
}
45-
46-
canvas.add(util.groupSVGElements(objects, options));
47-
canvas.renderAll();
48-
49-
let png = Buffer.from([]);
50-
for await (const chunk of canvas.createPNGStream()) {
51-
png = Buffer.concat([png, chunk]);
52-
}
53-
54-
await writeFile(outputFile, png);
30+
const resvgJS = new Resvg(svg, {
31+
fitTo: {
32+
mode: 'width',
33+
value: size,
34+
},
35+
...(bg && {background: 'white'}),
36+
});
37+
const renderedImage = resvgJS.render();
38+
const pngBytes = renderedImage.asPng();
39+
await writeFile(outputFile, Buffer.from(pngBytes));
5540
}
5641

5742
async function main() {
5843
const gitea = argv.slice(2).includes('gitea');
5944
const logoSvg = await readFile(new URL('../assets/logo.svg', import.meta.url), 'utf8');
6045
const faviconSvg = await readFile(new URL('../assets/favicon.svg', import.meta.url), 'utf8');
46+
await initWasm(await readFile(new URL(import.meta.resolve('@resvg/resvg-wasm/index_bg.wasm'))));
6147

6248
await Promise.all([
6349
generate(logoSvg, '../public/assets/img/logo.svg', {size: 32}),

tools/package.json

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)