136 lines
4.8 KiB
JavaScript
136 lines
4.8 KiB
JavaScript
import outlineStroke from 'svg-outline-stroke'
|
|
import { asyncForEach, getAllIcons, getCompileOptions, getPackageDir, HOME_DIR } from '../../../.build/helpers.mjs'
|
|
import fs from 'fs'
|
|
import { resolve, basename } from 'path'
|
|
import crypto from 'crypto'
|
|
import { glob } from 'glob'
|
|
import { optimize } from 'svgo'
|
|
import { fixOutline } from './fix-outline.mjs'
|
|
|
|
const DIR = getPackageDir('icons-webfont')
|
|
|
|
const strokes = {
|
|
200: 1,
|
|
300: 1.5,
|
|
400: 2,
|
|
}
|
|
|
|
const buildOutline = async () => {
|
|
let filesList = {}
|
|
const icons = getAllIcons(true)
|
|
|
|
const compileOptions = getCompileOptions()
|
|
|
|
for (const strokeName in strokes) {
|
|
const stroke = strokes[strokeName]
|
|
|
|
await asyncForEach(Object.entries(icons), async ([type, icons]) => {
|
|
fs.mkdirSync(resolve(DIR, `icons-outlined/${strokeName}/${type}`), { recursive: true })
|
|
filesList[type] = []
|
|
|
|
await asyncForEach(icons, async function ({ name, content, unicode }) {
|
|
if (compileOptions.includeIcons.length === 0 || compileOptions.includeIcons.indexOf(name) >= 0) {
|
|
|
|
if (unicode) {
|
|
console.log(`Stroke ${strokeName} for:`, name, unicode)
|
|
|
|
let filename = `${name}.svg`
|
|
if (unicode) {
|
|
filename = `u${unicode.toUpperCase()}-${name}.svg`
|
|
}
|
|
|
|
filesList[type].push(filename)
|
|
|
|
content = content
|
|
.replace('width="24"', 'width="1000"')
|
|
.replace('height="24"', 'height="1000"')
|
|
|
|
content = content
|
|
.replace('stroke-width="2"', `stroke-width="${stroke}"`)
|
|
|
|
const cachedFilename = `u${unicode.toUpperCase()}-${name}.svg`;
|
|
|
|
if (unicode && fs.existsSync(resolve(DIR, `icons-outlined/${strokeName}/${type}/${cachedFilename}`))) {
|
|
// Get content
|
|
let cachedContent = fs.readFileSync(resolve(DIR, `icons-outlined/${strokeName}/${type}/${cachedFilename}`), 'utf-8')
|
|
|
|
// Get hash
|
|
let cachedHash = '';
|
|
cachedContent = cachedContent.replace(/<!--\!cache:([a-z0-9]+)-->/, function (m, hash) {
|
|
cachedHash = hash;
|
|
return '';
|
|
})
|
|
|
|
// Check hash
|
|
if (crypto.createHash('sha1').update(cachedContent).digest("hex") === cachedHash) {
|
|
console.log('Cached stroke for:', name, unicode)
|
|
return true;
|
|
}
|
|
}
|
|
|
|
await outlineStroke(content, {
|
|
optCurve: true,
|
|
steps: 4,
|
|
round: 0,
|
|
centerHorizontally: true,
|
|
fixedWidth: false,
|
|
color: 'black'
|
|
}).then(outlined => {
|
|
// Fix outline direction (using JS instead of fontforge)
|
|
const fixed = fixOutline(outlined)
|
|
|
|
// Optimize with svgo (in memory, no subprocess)
|
|
const optimized = optimize(fixed, { multipass: true }).data
|
|
|
|
// Prepare final content with hash
|
|
const finalContent = optimized.replace(/\n/g, ' ').trim()
|
|
const hashString = `<!--!cache:${crypto.createHash('sha1').update(finalContent).digest("hex")}-->`
|
|
|
|
// Save file (single write instead of 3 file operations)
|
|
fs.writeFileSync(
|
|
resolve(DIR, `icons-outlined/${strokeName}/${type}/${filename}`),
|
|
finalContent + hashString,
|
|
'utf-8'
|
|
)
|
|
}).catch(error => console.log(error))
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
// Remove old files
|
|
await asyncForEach(Object.entries(icons), async ([type, icons]) => {
|
|
const existedFiles = (await glob(resolve(DIR, `icons-outlined/${strokeName}/${type}/*.svg`))).map(file => basename(file))
|
|
existedFiles.forEach(file => {
|
|
if (filesList[type].indexOf(file) === -1) {
|
|
console.log('Remove:', file)
|
|
fs.unlinkSync(resolve(DIR, `icons-outlined/${strokeName}/${type}/${file}`))
|
|
}
|
|
})
|
|
})
|
|
|
|
// Copy icons from firs to all directory
|
|
await asyncForEach(Object.entries(icons), async ([type, icons]) => {
|
|
fs.mkdirSync(resolve(DIR, `icons-outlined/${strokeName}/all`), { recursive: true })
|
|
|
|
await asyncForEach(icons, async function ({ name, unicode }) {
|
|
const iconName = `u${unicode.toUpperCase()}-${name}`
|
|
|
|
if (fs.existsSync(resolve(DIR, `icons-outlined/${strokeName}/${type}/${iconName}.svg`))) {
|
|
// Copy file
|
|
console.log(`Copy ${iconName} to all directory`)
|
|
|
|
fs.copyFileSync(
|
|
resolve(DIR, `icons-outlined/${strokeName}/${type}/${iconName}.svg`),
|
|
resolve(DIR, `icons-outlined/${strokeName}/all/${iconName}${type !== 'outline' ? `-${type}` : ''}.svg`)
|
|
)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
console.log('Done')
|
|
}
|
|
|
|
await buildOutline()
|