Skip to content

Commit 46890a4

Browse files
committed
msdfonts: base64 distributed msdf fonts
1 parent 3f76da1 commit 46890a4

File tree

19 files changed

+6623
-17021
lines changed

19 files changed

+6623
-17021
lines changed

.github/workflows/packages.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ jobs:
5959
- name: Set publishing config
6060
run: pnpm config set '//registry.npmjs.org/:_authToken' "${{ secrets.NPM_TOKEN }}"
6161

62+
- name: Deploy msdfonts Package
63+
working-directory: ./packages/msdfonts
64+
run: pnpm publish --access public --no-git-checks --tag ${{ steps.gitversion.outputs.preReleaseLabel == '' && 'latest' || steps.gitversion.outputs.preReleaseLabel }}
65+
6266
- name: Deploy Uikit Vanilla Package
6367
working-directory: ./packages/uikit
6468
run: pnpm publish --access public --no-git-checks --tag ${{ steps.gitversion.outputs.preReleaseLabel == '' && 'latest' || steps.gitversion.outputs.preReleaseLabel }}

.github/workflows/static.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,60 +41,60 @@ jobs:
4141

4242
# Fonts
4343
- name: Make Dist Dir
44-
working-directory: ./packages/fonts
44+
working-directory: ./packages/msdfonts/docker-volume
4545
run: mkdir dist
4646

4747
# Inter
4848
- name: Generate Inter Light
49-
working-directory: ./packages/fonts
49+
working-directory: ./packages/msdfonts/docker-volume
5050
run: |
5151
node download.js "Inter" 300
5252
fontforge -lang=ff -c 'Open($1); SelectAll(); RemoveOverlap(); Generate($2)' font.ttf inter-light.ttf
53-
pnpm msdf-bmfont -f json inter-light.ttf -i charset.txt -m 256,512 -o dist/inter-light -s 48
53+
pnpm msdf-bmfont -f json inter-light.ttf -i docker-volume/charset.txt -m 256,512 -o dist/inter-light -s 48
5454
5555
- name: Generate Inter Normal
56-
working-directory: ./packages/fonts
56+
working-directory: ./packages/msdfonts/docker-volume
5757
run: |
5858
node download.js "Inter" 400
5959
fontforge -lang=ff -c 'Open($1); SelectAll(); RemoveOverlap(); Generate($2)' font.ttf inter-normal.ttf
60-
pnpm msdf-bmfont -f json inter-normal.ttf -i charset.txt -m 256,512 -o dist/inter-normal -s 48
60+
pnpm msdf-bmfont -f json inter-normal.ttf -i docker-volume/charset.txt -m 256,512 -o dist/inter-normal -s 48
6161
6262
- name: Generate Inter Medium
63-
working-directory: ./packages/fonts
63+
working-directory: ./packages/msdfonts/docker-volume
6464
run: |
6565
node download.js "Inter" 500
6666
fontforge -lang=ff -c 'Open($1); SelectAll(); RemoveOverlap(); Generate($2)' font.ttf inter-medium.ttf
67-
pnpm msdf-bmfont -f json inter-medium.ttf -i charset.txt -m 256,512 -o dist/inter-medium -s 48
67+
pnpm msdf-bmfont -f json inter-medium.ttf -i docker-volume/charset.txt -m 256,512 -o dist/inter-medium -s 48
6868
6969
- name: Generate Inter Semi Bold
70-
working-directory: ./packages/fonts
70+
working-directory: ./packages/msdfonts/docker-volume
7171
run: |
7272
node download.js "Inter" 600
7373
fontforge -lang=ff -c 'Open($1); SelectAll(); RemoveOverlap(); Generate($2)' font.ttf inter-semi-bold.ttf
74-
pnpm msdf-bmfont -f json inter-semi-bold.ttf -i charset.txt -m 256,512 -o dist/inter-semi-bold -s 48
74+
pnpm msdf-bmfont -f json inter-semi-bold.ttf -i docker-volume/charset.txt -m 256,512 -o dist/inter-semi-bold -s 48
7575
7676
- name: Generate Inter Bold
77-
working-directory: ./packages/fonts
77+
working-directory: ./packages/msdfonts/docker-volume
7878
run: |
7979
node download.js "Inter" 700
8080
fontforge -lang=ff -c 'Open($1); SelectAll(); RemoveOverlap(); Generate($2)' font.ttf inter-bold.ttf
81-
pnpm msdf-bmfont -f json inter-bold.ttf -i charset.txt -m 256,512 -o dist/inter-bold -s 48
81+
pnpm msdf-bmfont -f json inter-bold.ttf -i docker-volume/charset.txt -m 256,512 -o dist/inter-bold -s 48
8282
8383
- name: Convert to Webp
84-
working-directory: ./packages/fonts
84+
working-directory: ./packages/msdfonts/docker-volume
8585
run: pnpm sharp --lossless -i dist/*.png -o dist/ -f webp
8686

8787
- name: Replace file png files
88-
working-directory: ./packages/fonts
88+
working-directory: ./packages/msdfonts/docker-volume
8989
run: |
9090
sed -i 's/png/webp/g' dist/*.json
9191
rm dist/*.png
9292
9393
- name: Copy font files
9494
run: |
9595
mkdir -p public/fonts
96-
cp ./packages/fonts/dist/* ./public/fonts
97-
cp ./packages/fonts/LICENSE public/fonts/LICENSE
96+
cp ./packages/msdfonts/docker-volume/dist/* ./public/fonts
97+
cp ./packages/msdfonts/LICENSE public/fonts/LICENSE
9898
9999
- name: Upload Artifact
100100
uses: actions/upload-artifact@v4

packages/fonts/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/msdfonts/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# msdfonts
2+
3+
base64 msdf fonts distributed as npm packages
4+
5+
# usage with R3/uikit
6+
7+
```jsx
8+
import { inter } from '@pmndrs/msdfonts'
9+
10+
;<FontFamilyProvider inter={inter}>{...children}</FontFamilyProvider>
11+
```
12+
13+
# How to build
14+
15+
## First Step
16+
17+
`cd docker-volume`
18+
`docker build . -t msdfonts`
19+
`docker run -v ./docker-volume:/data/:rw -e GOOGLE_FONTS_API_KEY='<insert-api-key>' msdfonts`
20+
21+
for users on ARM architecture (e.g. Apple M-chips)
22+
23+
`cd docker-volume`
24+
`docker build . --platform linux/x86_64 -t msdfonts`
25+
`docker run -v ./docker-volume:/data/:rw -e GOOGLE_FONTS_API_KEY='<insert-api-key>' --platform linux/x86_64 msdfonts`
26+
27+
## Final Step
28+
29+
Now delete the file in `src/index.ts` and copy the file `docker-volume/index.ts` into `src/index.ts`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.json
2+
!package.json
3+
*.ttf
4+
*.png
5+
*.webp
6+
*.ts
File renamed without changes.

packages/fonts/download.js renamed to packages/msdfonts/docker-volume/download.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const https = require('https') // or 'https' for https:// URLs
2-
const http = require('http')
3-
const fs = require('fs')
1+
import https from 'https' // or 'https' for https:// URLs
2+
import http from 'http'
3+
import fs from 'fs'
44

55
const [, , fontFamily, variant] = process.argv
66

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import https from 'https'
2+
import http from 'http'
3+
import fs, { writeFileSync } from 'fs'
4+
import { exec } from 'child_process'
5+
import { dirname, resolve } from 'path'
6+
7+
async function generate(fontFamily, variant) {
8+
const response = await fetch(
9+
`https://www.googleapis.com/webfonts/v1/webfonts?family=${fontFamily}&key=${process.env.GOOGLE_FONTS_API_KEY}`,
10+
)
11+
const json = await response.json()
12+
if (json.error != null) {
13+
console.error('fetch font families', fontFamily, json.error)
14+
return
15+
}
16+
const result = Object.entries(json.items[0].files).find(
17+
([name]) => name.toLocaleLowerCase() === variant.toLocaleLowerCase(),
18+
)
19+
if (result == null) {
20+
return false
21+
}
22+
await download(result[1], 'font.ttf')
23+
await runCmd("fontforge -lang=ff -c 'Open($1); SelectAll(); RemoveOverlap(); Generate($2)' font.ttf fixed-font.ttf")
24+
await runCmd(`npm run msdf`)
25+
await runCmd(`npm run webp`)
26+
return true
27+
}
28+
29+
const variants = { light: '300', regular: '400', medium: '500', 'semi-bold': '600', bold: '700' }
30+
const fontFamilies = ['Inter']
31+
32+
async function main() {
33+
let result = ''
34+
for (const fontFamily of fontFamilies) {
35+
result += `export const ${fontFamily.toLowerCase()} = {`
36+
for (const [fontWeightName, fontWeightValue] of Object.entries(variants)) {
37+
if (!(await generate(fontFamily, fontWeightValue))) {
38+
continue
39+
}
40+
result += `\t"${fontWeightName}": ${fontToJson('fixed-font.json')},`
41+
}
42+
result += `}\n\n`
43+
}
44+
writeFileSync('./index.ts', result)
45+
}
46+
47+
main().catch(console.error)
48+
49+
function runCmd(cmd) {
50+
return new Promise((resolve, reject) =>
51+
exec(cmd, (error) => {
52+
if (error == null) {
53+
resolve()
54+
return
55+
}
56+
reject(error)
57+
}),
58+
)
59+
}
60+
61+
function download(url, to) {
62+
return new Promise((resolve, reject) => {
63+
const file = fs.createWriteStream(to)
64+
;(url.startsWith('https') ? https : http)
65+
.get(url, (response) => {
66+
response.pipe(file)
67+
file.on('finish', () => {
68+
file.close()
69+
resolve()
70+
})
71+
})
72+
.on('error', reject)
73+
})
74+
}
75+
76+
function fontToJson(jsonPath) {
77+
const json = JSON.parse(fs.readFileSync(jsonPath))
78+
79+
for (let i = 0; i < json.pages.length; i++) {
80+
const url = resolve(dirname(jsonPath), json.pages[i]).replace('.png', '.webp')
81+
json.pages[i] = toUrl(fs.readFileSync(url), 'image/webp')
82+
}
83+
84+
return JSON.stringify(json)
85+
}
86+
87+
function toUrl(buf, mimeType) {
88+
return `data:${mimeType};base64,${buf.toString('base64')}`
89+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"type": "module",
3+
"dependencies": {
4+
"msdf-bmfont-xml": "^2.7.0",
5+
"sharp-cli": "4.1"
6+
},
7+
"scripts": {
8+
"msdf": "msdf-bmfont -f json fixed-font.ttf -i charset.txt -m 256,512 -o fixed-font -s 48",
9+
"webp": "sharp --nearLossless -i fixed-font.png -o fixed-font.webp -f webp"
10+
}
11+
}

0 commit comments

Comments
 (0)