71 lines
2.1 KiB
JavaScript
71 lines
2.1 KiB
JavaScript
// Minimal PNG generator — run before build to create icon files
|
|
const { writeFileSync, mkdirSync } = require('fs')
|
|
|
|
function crc32(buf) {
|
|
const table = new Int32Array(256)
|
|
for (let i = 0; i < 256; i++) {
|
|
let c = i
|
|
for (let k = 0; k < 8; k++) c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1)
|
|
table[i] = c
|
|
}
|
|
let crc = -1
|
|
for (let i = 0; i < buf.length; i++) crc = table[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8)
|
|
return crc ^ -1
|
|
}
|
|
|
|
function pngChunk(type, data) {
|
|
const len = data.length
|
|
const chunk = new Uint8Array(4 + 4 + len + 4)
|
|
const view = new DataView(chunk.buffer)
|
|
view.setUint32(0, len, false)
|
|
chunk.set(new TextEncoder().encode(type), 4)
|
|
chunk.set(data, 8)
|
|
const crc = crc32(chunk.slice(4, 8 + len))
|
|
view.setUint32(8 + len, crc, false)
|
|
return chunk
|
|
}
|
|
|
|
function generatePNG(size, color) {
|
|
const header = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
|
|
const ihdr = new Uint8Array(13)
|
|
const v = new DataView(ihdr.buffer)
|
|
v.setUint32(0, size, false)
|
|
v.setUint32(4, size, false)
|
|
v.setUint8(8, 8)
|
|
v.setUint8(9, 2)
|
|
v.setUint8(10, 0)
|
|
v.setUint8(11, 0)
|
|
v.setUint8(12, 0)
|
|
|
|
const rowLen = 1 + size * 3
|
|
const raw = new Uint8Array(size * rowLen)
|
|
for (let y = 0; y < size; y++) {
|
|
raw[y * rowLen] = 0
|
|
for (let x = 0; x < size; x++) {
|
|
const off = y * rowLen + 1 + x * 3
|
|
raw[off] = color[0]
|
|
raw[off + 1] = color[1]
|
|
raw[off + 2] = color[2]
|
|
}
|
|
}
|
|
|
|
const compressed = new Uint8Array(require('zlib').deflateSync(raw))
|
|
const idat = pngChunk('IDAT', compressed)
|
|
const iend = pngChunk('IEND', new Uint8Array(0))
|
|
|
|
const out = new Uint8Array(header.length + 4 + 4 + 13 + 4 + idat.length + iend.length)
|
|
let p = 0
|
|
out.set(header, p); p += header.length
|
|
out.set(pngChunk('IHDR', ihdr), p); p += 4 + 4 + 13 + 4
|
|
out.set(idat, p); p += idat.length
|
|
out.set(iend, p)
|
|
return out
|
|
}
|
|
|
|
mkdirSync('icons', { recursive: true })
|
|
const teal = [0, 180, 170]
|
|
writeFileSync('icons/icon16.png', generatePNG(16, teal))
|
|
writeFileSync('icons/icon48.png', generatePNG(48, teal))
|
|
writeFileSync('icons/icon128.png', generatePNG(128, teal))
|
|
console.log('Icons generated')
|