Skip to content

Commit 8f86652

Browse files
committed
iconfont cache
1 parent 28470c5 commit 8f86652

File tree

9 files changed

+758
-124
lines changed

9 files changed

+758
-124
lines changed

Diff for: package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,8 @@
117117
"release": true
118118
}
119119
},
120-
"packageManager": "[email protected]"
120+
"packageManager": "[email protected]",
121+
"dependencies": {
122+
"crypto-js": "^4.2.0"
123+
}
121124
}

Diff for: packages/icons-webfont/.build/build-outline.mjs

+76-16
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,61 @@
11
import outlineStroke from 'svg-outline-stroke'
22
import { asyncForEach, getCompileOptions, getPackageDir, HOME_DIR, readSvgs } from '../../../.build/helpers.mjs'
33
import fs from 'fs'
4-
import { resolve } from 'path'
4+
import { resolve, basename } from 'path'
5+
import crypto from 'crypto'
6+
import { glob } from 'glob'
7+
import { execSync } from 'child_process'
58

69
const DIR = getPackageDir('icons-webfont')
710

811
const buildOutline = async () => {
9-
let files = readSvgs()
10-
const compileOptions = getCompileOptions()
12+
let files = readSvgs(),
13+
filesList = []
1114

12-
const iconfontUnicode = JSON.parse(fs.readFileSync(resolve(HOME_DIR, 'tags.json'), 'utf-8'))
15+
const compileOptions = getCompileOptions(),
16+
iconfontUnicode = JSON.parse(fs.readFileSync(resolve(HOME_DIR, 'tags.json'), 'utf-8'))
1317

14-
await asyncForEach(files, async function({ name, contents }) {
18+
await asyncForEach(files, async function ({ name, contents }) {
1519
if (compileOptions.includeIcons.length === 0 || compileOptions.includeIcons.indexOf(name) >= 0) {
1620

1721
if (iconfontUnicode[name]) {
1822
const unicode = iconfontUnicode[name].unicode
19-
await console.log('Stroke for:', name, unicode)
23+
console.log('Stroke for:', name, unicode)
24+
25+
let filename = `${name}.svg`
26+
if (unicode) {
27+
filename = `u${unicode.toUpperCase()}-${name}.svg`
28+
}
29+
30+
filesList.push(filename)
2031

2132
contents = contents
22-
.replace('width="24"', 'width="1000"')
23-
.replace('height="24"', 'height="1000"')
33+
.replace('width="24"', 'width="1000"')
34+
.replace('height="24"', 'height="1000"')
2435

2536
if (compileOptions.strokeWidth) {
2637
contents = contents
27-
.replace('stroke-width="2"', `stroke-width="${compileOptions.strokeWidth}"`)
38+
.replace('stroke-width="2"', `stroke-width="${compileOptions.strokeWidth}"`)
39+
}
40+
41+
const cachedFilename = `u${unicode.toUpperCase()}-${name}.svg`;
42+
43+
if (unicode && fs.existsSync(resolve(DIR, `icons-outlined/${cachedFilename}`))) {
44+
// Get content
45+
let cachedContent = fs.readFileSync(resolve(DIR, `icons-outlined/${cachedFilename}`), 'utf-8')
46+
47+
// Get hash
48+
let cachedHash = '';
49+
cachedContent = cachedContent.replace(/<!--\!cache:([a-z0-9]+)-->/, function (m, hash) {
50+
cachedHash = hash;
51+
return '';
52+
})
53+
54+
// Check hash
55+
if (crypto.createHash('sha1').update(cachedContent).digest("hex") === cachedHash) {
56+
console.log('Cached stroke for:', name, unicode)
57+
return true;
58+
}
2859
}
2960

3061
await outlineStroke(contents, {
@@ -35,15 +66,44 @@ const buildOutline = async () => {
3566
fixedWidth: false,
3667
color: 'black'
3768
}).then(outlined => {
38-
if (unicode) {
39-
fs.writeFileSync(resolve(DIR, `icons-outlined/u${unicode.toUpperCase()}-${name}.svg`), outlined, 'utf-8')
40-
} else {
41-
fs.writeFileSync(resolve(DIR, `icons-outlined/${name}.svg`), outlined, 'utf-8')
42-
}
43-
}).catch(error => console.log(error))
44-
}
69+
filesList[filename]
70+
71+
// Save file
72+
fs.writeFileSync(resolve(DIR, `icons-outlined/${filename}`), outlined, 'utf-8')
73+
74+
// Fix outline
75+
execSync(`fontforge -lang=py -script .build/fix-outline.py icons-outlined/${filename}`)
76+
execSync(`svgo icons-outlined/${filename}`)
77+
78+
// Add hash
79+
const fixedFileContent = fs
80+
.readFileSync(resolve(DIR, `icons-outlined/${filename}`), 'utf-8')
81+
.replace(/\n/g, ' ')
82+
.trim(),
83+
hashString = `<!--!cache:${crypto.createHash('sha1').update(fixedFileContent).digest("hex")}-->`
84+
85+
// Save file
86+
fs.writeFileSync(
87+
resolve(DIR, `icons-outlined/${filename}`),
88+
fixedFileContent + hashString,
89+
'utf-8'
90+
)
91+
}).catch(error => console.log(error))
92+
}
4593
}
4694
})
95+
96+
// Remove old files
97+
const existedFiles = (await glob(resolve(DIR, `icons-outlined/*.svg`))).map(file => basename(file))
98+
99+
existedFiles.forEach(file => {
100+
if (filesList.indexOf(file) === -1) {
101+
console.log('Remove:', file)
102+
fs.unlinkSync(resolve(DIR, `icons-outlined/${file}`))
103+
}
104+
})
105+
106+
console.log('Done')
47107
}
48108

49109
await buildOutline()

Diff for: packages/icons-webfont/.build/fix-outline.py

+10-24
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,17 @@
11
import os
22
import fontforge
33

4-
# svg2ttf library does not support fill-rule="evenodd" so after converting icons to outlineStroke we fix path directions to work with "nonzero"
5-
# more: https://github.com/tabler/tabler-icons/issues/13 - thanks for awesome suggestions in the issue
6-
7-
8-
print ("Running fontforge to fix svg outline directions!")
9-
10-
def files(path):
11-
for file in os.listdir(path):
12-
if os.path.isfile(os.path.join(path, file)):
13-
yield file
14-
15-
# refer to https://fontforge.org/docs/scripting/python/fontforge.html for documentation
16-
# inspiration from https://github.com/FontCustom/fontcustom/blob/master/lib/fontcustom/scripts/generate.py
4+
file = sys.argv[1]
175

186
font = fontforge.font()
19-
for file in files("./icons-outlined"):
20-
print (f"Correcting outline for {file}")
21-
glyph = font.createChar(123, file)
22-
glyph.importOutlines("./icons-outlined/" + file)
23-
glyph.round()
24-
glyph.simplify()
25-
glyph.simplify()
26-
glyph.correctDirection()
27-
glyph.export("./icons-outlined/" + file)
28-
glyph.clear()
29-
7+
print (f"Correcting outline for {file}")
8+
glyph = font.createChar(123, file)
9+
glyph.importOutlines("./" + file)
10+
glyph.round()
11+
glyph.simplify()
12+
glyph.simplify()
13+
glyph.correctDirection()
14+
glyph.export("./" + file)
15+
glyph.clear()
3016

3117
print ("Finished fixing svg outline directions!")

Diff for: packages/icons-webfont/fonts/tabler-icons.eot

1.26 KB
Binary file not shown.

Diff for: packages/icons-webfont/fonts/tabler-icons.ttf

1.26 KB
Binary file not shown.

Diff for: packages/icons-webfont/fonts/tabler-icons.woff

888 Bytes
Binary file not shown.

Diff for: packages/icons-webfont/fonts/tabler-icons.woff2

176 Bytes
Binary file not shown.

Diff for: packages/icons-webfont/package.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@
1616
"directory": "packages/icons-webfont"
1717
},
1818
"scripts": {
19-
"build": "pnpm run clean && pnpm run copy && pnpm run build:prepare && pnpm run build:outline && pnpm run build:optimize && pnpm run build:fix-outline && pnpm run build:webfont && pnpm run build:css && pnpm run build:clean",
20-
"build:prepare": "mkdir -p icons-outlined fonts && rm -fd icons-outlined/* fonts/*",
19+
"build": "pnpm run copy && pnpm run build:prepare && pnpm run build:outline && pnpm run build:webfont && pnpm run build:css",
20+
"build:prepare": "mkdir -p icons-outlined fonts && rm -fd fonts/*",
2121
"build:outline": "node .build/build-outline.mjs",
22-
"build:optimize": "svgo icons-outlined/*",
23-
"build:fix-outline": "fontforge -lang=py -script .build/fix-outline.py",
2422
"build:webfont": "rm -fd fonts/* && node .build/build-webfont.mjs",
2523
"build:css": "sass tabler-icons.scss tabler-icons.css --style expanded && sass tabler-icons.scss tabler-icons.min.css --style compressed",
2624
"build:clean": "rm -rf ./icons-outlined",
27-
"clean": "rm -rf ./iconfont",
2825
"copy": "pnpm run copy:license",
2926
"copy:license": "cp ../../LICENSE ./LICENSE"
3027
},

0 commit comments

Comments
 (0)