52e1dc6eda
- 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
56 lines
1.8 KiB
JavaScript
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');
|