Files
SonicForgeStudio/tools/gen_favicon_ico.js
T
3dtours 52e1dc6eda FEAT: icon exe = favicon cua app — favicon.svg -> PNG -> ICO (6 sizes 16-128)
- engine.spec: icon='src-tauri/icons/favicon.ico' (cung nguon voi icon hien thi trong app, truoc day dung icon.ico mac dinh khac favicon)
- tools/gen_favicon_ico.js: script tai sinh ICO tu app/templates/favicon.svg (resvg-js WASM, khong can libcairo)
- Verify: ICO 6 sizes (16/24/32/48/64/128), 571 mau, binary chay OK
2026-08-09 02:59:11 +00:00

56 lines
1.8 KiB
JavaScript

// Sinh src-tauri/icons/favicon.ico tu app/templates/favicon.svg (icon exe).
// Dung: node tools/gen_favicon_ico.js
// (Can @resvg/resvg-js — npm install @resvg/resvg-js trong thu muc lam viec,
// hoac chay trong thu muc da cai. Output: src-tauri/icons/favicon.ico.)
// ICO chua cac size 16/24/32/48/64/128 — Windows dung cho exe icon.
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '..');
const SVG = path.join(ROOT, 'app', 'templates', 'favicon.svg');
const OUT = path.join(ROOT, 'src-tauri', 'icons', 'favicon.ico');
let Resvg;
try {
({ Resvg } = require('@resvg/resvg-js'));
} catch (e) {
console.error('Thieu @resvg/resvg-js. Chay: npm install @resvg/resvg-js');
process.exit(1);
}
const svg = fs.readFileSync(SVG, 'utf8');
const SIZES = [16, 24, 32, 48, 64, 128];
function buildIco(images) {
const header = Buffer.alloc(6);
header.writeUInt16LE(0, 0);
header.writeUInt16LE(1, 2);
header.writeUInt16LE(images.length, 4);
const entries = [];
const datas = [];
let offset = 6 + 16 * images.length;
for (const { size, data } of images) {
const entry = Buffer.alloc(16);
const dim = size >= 256 ? 0 : size;
entry.writeUInt8(dim, 0);
entry.writeUInt8(dim, 1);
entry.writeUInt8(0, 2);
entry.writeUInt8(0, 3);
entry.writeUInt16LE(1, 4);
entry.writeUInt16LE(32, 6);
entry.writeUInt32LE(data.length, 8);
entry.writeUInt32LE(offset, 12);
entries.push(entry);
datas.push(data);
offset += data.length;
}
return Buffer.concat([header, ...entries, ...datas]);
}
const pngs = SIZES.map(s => ({
size: s,
data: new Resvg(svg, { fitTo: { mode: 'width', value: s }, background: 'rgba(0,0,0,0)' }).render().asPng(),
}));
fs.writeFileSync(OUT, buildIco(pngs));
console.log('favicon.ico ->', OUT, fs.statSync(OUT).size, 'bytes');