Fix fonts
This commit is contained in:
@@ -2,36 +2,42 @@ import {writeFile} from 'node:fs/promises'
|
||||
import * as path from 'node:path'
|
||||
import {fileURLToPath} from 'node:url'
|
||||
|
||||
const __DIRNAME = path.dirname(fileURLToPath(import.meta.url))
|
||||
import {
|
||||
ADDITIONAL_FONTS,
|
||||
ADDITIONAL_FONTS_POSTSCRIPT_NAMES,
|
||||
} from '../src/util/fonts.js'
|
||||
|
||||
const FONTS = [
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-jp@5.0/japanese-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-tc@5.0/chinese-traditional-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-sc@5.0/chinese-simplified-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-hk@5.0/chinese-hongkong-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-kr@5.0/korean-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-thai@5.0/thai-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-arabic@5.0/arabic-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-hebrew@5.0/hebrew-700-normal.ttf',
|
||||
]
|
||||
const __DIRNAME = path.dirname(fileURLToPath(import.meta.url))
|
||||
const outDir = path.join(__DIRNAME, '..', 'src', 'assets', 'fonts')
|
||||
|
||||
async function main() {
|
||||
await Promise.all(
|
||||
FONTS.map(async urlStr => {
|
||||
const url = new URL(urlStr)
|
||||
const res = await fetch(url)
|
||||
const font = await res.arrayBuffer()
|
||||
const filename = url.pathname
|
||||
.split('/')
|
||||
.slice(-2)
|
||||
.join('/')
|
||||
.replace(/@[\d.]+\//, '-')
|
||||
ADDITIONAL_FONTS.map(async urlStr => {
|
||||
// get last part of the URL
|
||||
const raw = urlStr.split('/').slice(-1).join('')
|
||||
// style and weight are known parts of the path, rest is the font family
|
||||
const [styleWithExtension, weight, ...fontFamilyParts] = raw
|
||||
.split('-')
|
||||
.reverse()
|
||||
const style = styleWithExtension.split('.')[0]
|
||||
// re-reverse the font family parts to get the original order
|
||||
const rawFontFamily = fontFamilyParts.reverse().join('-')
|
||||
// get the postscript name from the map
|
||||
const postScriptName = ADDITIONAL_FONTS_POSTSCRIPT_NAMES[rawFontFamily]
|
||||
// our filename format: `weight-postScriptName-style.ttf`
|
||||
const filename = `${weight}-${postScriptName}-${style}.ttf`
|
||||
// fetch the file
|
||||
const res = await fetch(urlStr)
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP ${res.status}: fetching failed for ${filename}`)
|
||||
throw new Error(`HTTP ${res.status}: fetching failed for ${urlStr}`)
|
||||
}
|
||||
|
||||
console.log(`Writing font ${filename}...`)
|
||||
|
||||
await writeFile(
|
||||
path.join(__DIRNAME, '..', 'src', 'assets', 'fonts', filename),
|
||||
Buffer.from(font),
|
||||
path.join(outDir, filename),
|
||||
Buffer.from(await res.arrayBuffer()),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {atoms as a, style as s, theme as t} from '../theme/index.js'
|
||||
import {FONT_FAMILY_DEF} from '../util/fonts.js'
|
||||
|
||||
const SCALE_MULTIPLIER = 1 - 0.0625
|
||||
|
||||
@@ -20,7 +21,7 @@ export function Text({
|
||||
a.tracking_wide,
|
||||
t.atoms.text,
|
||||
{
|
||||
fontFamily: 'Inter',
|
||||
fontFamily: FONT_FAMILY_DEF,
|
||||
fontWeight: 400,
|
||||
},
|
||||
...(cx ?? []),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {AtpAgent} from '@atproto/api'
|
||||
|
||||
import {Config} from './config.js'
|
||||
import {getFontFiles, readFonts} from './util/fonts.js'
|
||||
import {getFontDefinitions} from './util/fonts.js'
|
||||
|
||||
export type AppContextOptions = {
|
||||
cfg: Config
|
||||
@@ -23,8 +23,8 @@ export class AppContext {
|
||||
|
||||
static async fromConfig(cfg: Config, overrides?: Partial<AppContextOptions>) {
|
||||
const appviewAgent = new AtpAgent({service: cfg.service.appviewUrl})
|
||||
const fontFiles = getFontFiles()
|
||||
const fonts = readFonts(fontFiles)
|
||||
const fonts = getFontDefinitions()
|
||||
|
||||
return new AppContext({
|
||||
cfg,
|
||||
appviewAgent,
|
||||
|
||||
@@ -10,7 +10,6 @@ import {getPost} from '../data/getPost.js'
|
||||
import {getPostData} from '../data/getPostData.js'
|
||||
import {httpLogger} from '../logger.js'
|
||||
import {loadEmojiAsSvg} from '../util.js'
|
||||
import {getFontFiles} from '../util/fonts.js'
|
||||
import {
|
||||
getRenderOptions,
|
||||
parseDisplayOptionsFromQuery,
|
||||
@@ -72,15 +71,11 @@ export default function (ctx: AppContext, app: Express) {
|
||||
},
|
||||
)
|
||||
const output = await resvg.renderAsync(svg, {
|
||||
font: {
|
||||
fontFiles: getFontFiles(),
|
||||
defaultFontFamily: 'Inter',
|
||||
},
|
||||
fitTo: {
|
||||
mode: 'width',
|
||||
value: width * 2,
|
||||
},
|
||||
logLevel: 'trace',
|
||||
// logLevel: 'trace',
|
||||
})
|
||||
|
||||
res.statusCode = 200
|
||||
|
||||
@@ -3,6 +3,43 @@ import * as path from 'node:path'
|
||||
|
||||
const __DIRNAME = path.join(process.cwd(), 'src')
|
||||
|
||||
export const ADDITIONAL_FONTS = [
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-jp@5.0/japanese-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-tc@5.0/chinese-traditional-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-sc@5.0/chinese-simplified-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-hk@5.0/chinese-hongkong-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-kr@5.0/korean-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-thai@5.0/thai-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-arabic@5.0/arabic-700-normal.ttf',
|
||||
'https://cdn.jsdelivr.net/fontsource/fonts/noto-sans-hebrew@5.0/hebrew-700-normal.ttf',
|
||||
]
|
||||
|
||||
/**
|
||||
* CSS `fontFamily` defs must use the PostScript names of the fonts. When
|
||||
* adding additional fonts above, you'll need to figure out the PostScript name
|
||||
* and add it to the map below.
|
||||
*/
|
||||
export const ADDITIONAL_FONTS_POSTSCRIPT_NAMES: Record<string, string> = {
|
||||
arabic: 'Noto Sans Arabic',
|
||||
hebrew: 'Noto Sans Arabic',
|
||||
japanese: 'Noto Sans JP Thin',
|
||||
korean: 'Noto Sans KR',
|
||||
thai: 'Noto Sans Thai',
|
||||
'chinese-hongkong': 'Noto Sans HK',
|
||||
'chinese-simplified': 'Noto Sans SC',
|
||||
'chinese-traditional': 'Noto Sans TC',
|
||||
}
|
||||
|
||||
/**
|
||||
* Precomputed, for use in the runtime CSS defs
|
||||
*/
|
||||
export const FONT_FAMILY_DEF = `Inter, ${Object.values(
|
||||
ADDITIONAL_FONTS_POSTSCRIPT_NAMES,
|
||||
).join(', ')}, sans-serif`
|
||||
|
||||
/**
|
||||
* Get all TTF files from our fonts dir
|
||||
*/
|
||||
export function getFontFiles() {
|
||||
const fontDirectory = path.join(__DIRNAME, 'assets', 'fonts')
|
||||
return readdirSync(fontDirectory)
|
||||
@@ -10,13 +47,17 @@ export function getFontFiles() {
|
||||
.map(file => path.join(fontDirectory, file))
|
||||
}
|
||||
|
||||
export function readFonts(fontFiles: string[]) {
|
||||
return fontFiles.map(file => {
|
||||
/**
|
||||
* Get all font files and format for use by Satori
|
||||
*/
|
||||
export function getFontDefinitions() {
|
||||
return getFontFiles().map(file => {
|
||||
const basename = path.basename(file, path.extname(file))
|
||||
const italic = basename.includes('Italic')
|
||||
const [weight, name] = basename.split('-')
|
||||
const [weight, postScriptName] = basename.split('-')
|
||||
|
||||
return {
|
||||
name,
|
||||
name: postScriptName,
|
||||
data: readFileSync(file),
|
||||
weight: parseInt(weight),
|
||||
style: italic ? 'italic' : 'normal',
|
||||
|
||||
@@ -107,6 +107,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Other languages -->
|
||||
<section>
|
||||
<h1>Other languages</h1>
|
||||
<div class="grid">
|
||||
<div class="item"><img src="http://localhost:3000/profile/miyanushi.bsky.social/post/3lrqt3xxmuk2a?mat=1"><div>Japanese</div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Misc -->
|
||||
<section>
|
||||
<h1>Misc</h1>
|
||||
|
||||
Reference in New Issue
Block a user