2022-06-06 06:27:25 +03:00
#!/usr/bin/env node
2024-03-18 01:12:36 +03:00
import imageminZopfli from 'imagemin-zopfli' ; // eslint-disable-line i/no-unresolved
import { loadSVGFromString , Canvas , Rect , util } from 'fabric/node' ; // eslint-disable-line i/no-unresolved
2021-10-22 23:05:53 +03:00
import { optimize } from 'svgo' ;
2022-12-21 01:15:47 +03:00
import { readFile , writeFile } from 'node:fs/promises' ;
2024-02-23 02:31:24 +03:00
import { argv , exit } from 'node:process' ;
2020-12-19 04:17:27 +03:00
2024-02-23 02:31:24 +03:00
function doExit ( err ) {
2020-07-26 12:47:51 +03:00
if ( err ) console . error ( err ) ;
2024-02-23 02:31:24 +03:00
exit ( err ? 1 : 0 ) ;
2020-07-26 12:47:51 +03:00
}
2022-06-06 06:27:25 +03:00
async function generate ( svg , path , { size , bg } ) {
const outputFile = new URL ( path , import . meta . url ) ;
if ( String ( outputFile ) . endsWith ( '.svg' ) ) {
2021-03-22 07:04:19 +03:00
const { data } = optimize ( svg , {
2021-10-22 23:05:53 +03:00
plugins : [
'preset-default' ,
2021-03-22 07:04:19 +03:00
'removeDimensions' ,
{
name : 'addAttributesToSVGElement' ,
params : { attributes : [ { width : size } , { height : size } ] }
} ,
2021-10-22 23:05:53 +03:00
] ,
2021-01-01 22:04:35 +03:00
} ) ;
await writeFile ( outputFile , data ) ;
return ;
}
2020-12-19 04:17:27 +03:00
2024-02-23 02:31:24 +03:00
const { objects , options } = await loadSVGFromString ( svg ) ;
const canvas = new Canvas ( ) ;
2020-07-26 12:47:51 +03:00
canvas . setDimensions ( { width : size , height : size } ) ;
const ctx = canvas . getContext ( '2d' ) ;
ctx . scale ( options . width ? ( size / options . width ) : 1 , options . height ? ( size / options . height ) : 1 ) ;
if ( bg ) {
2024-02-23 02:31:24 +03:00
canvas . add ( new Rect ( {
2020-07-26 12:47:51 +03:00
left : 0 ,
top : 0 ,
height : size * ( 1 / ( size / options . height ) ) ,
width : size * ( 1 / ( size / options . width ) ) ,
fill : 'white' ,
} ) ) ;
}
2024-02-23 02:31:24 +03:00
canvas . add ( util . groupSVGElements ( objects , options ) ) ;
2020-07-26 12:47:51 +03:00
canvas . renderAll ( ) ;
let png = Buffer . from ( [ ] ) ;
for await ( const chunk of canvas . createPNGStream ( ) ) {
png = Buffer . concat ( [ png , chunk ] ) ;
}
png = await imageminZopfli ( { more : true } ) ( png ) ;
await writeFile ( outputFile , png ) ;
}
async function main ( ) {
2024-02-23 02:31:24 +03:00
const gitea = argv . slice ( 2 ) . includes ( 'gitea' ) ;
2022-06-06 06:27:25 +03:00
const logoSvg = await readFile ( new URL ( '../assets/logo.svg' , import . meta . url ) , 'utf8' ) ;
const faviconSvg = await readFile ( new URL ( '../assets/favicon.svg' , import . meta . url ) , 'utf8' ) ;
2021-01-01 22:04:35 +03:00
2020-12-19 04:17:27 +03:00
await Promise . all ( [
2023-07-18 19:06:43 +03:00
generate ( logoSvg , '../public/assets/img/logo.svg' , { size : 32 } ) ,
generate ( logoSvg , '../public/assets/img/logo.png' , { size : 512 } ) ,
generate ( faviconSvg , '../public/assets/img/favicon.svg' , { size : 32 } ) ,
generate ( faviconSvg , '../public/assets/img/favicon.png' , { size : 180 } ) ,
generate ( logoSvg , '../public/assets/img/avatar_default.png' , { size : 200 } ) ,
generate ( logoSvg , '../public/assets/img/apple-touch-icon.png' , { size : 180 , bg : true } ) ,
gitea && generate ( logoSvg , '../public/assets/img/gitea.svg' , { size : 32 } ) ,
2020-12-19 04:17:27 +03:00
] ) ;
2020-07-26 12:47:51 +03:00
}
2024-02-17 00:41:23 +03:00
try {
2024-02-23 02:31:24 +03:00
doExit ( await main ( ) ) ;
2024-02-17 00:41:23 +03:00
} catch ( err ) {
2024-02-23 02:31:24 +03:00
doExit ( err ) ;
2024-02-17 00:41:23 +03:00
}