0.3.2 • Published 10 months ago

@subframe7536/fonttools v0.3.2

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

@subframe7536/fonttools

fonttools for nodejs or web with vite plugin, powered by pyodide

ESM Only

Under development, breaking changes expected. Use at your own risk

  • pyodide version: 0.27.1

Why

The fonttools binary file is not included in pyodide by default, you need to download it from JsDelivr at runtime, and the URL seems not allowed to customize. So I package all the needed file and provide a vite plugin to optimize.

Install

npm install @subframe7536/fonttools
yarn add @subframe7536/fonttools
pnpm add @subframe7536/fonttools

Usage

NodeJS

import { readFileSync, writeFileSync } from 'node:fs'

import { loadInNode } from '@subframe7536/fonttools'
import { generateBasicScript, handleFontBuffer, NameId, processNameScriptUtil } from '@subframe7536/fonttools/utils'

const buf = new Uint8Array(readFileSync('./test.ttf'))

loadInNode({ woff2: true })
  .then(async (py) => {
    const data = await handleFontBuffer(
      py,
      buf,
      generateBasicScript(`${processNameScriptUtil}
set_font_name(font, 'Test', ${NameId.FamilyName})
`)
    )
    writeFileSync('change_name.ttf', data)
    return py
  })
  .then(async (py) => {
    const data = await handleFontBuffer(
      py,
      buf,
      (input, output) => `
from fontTools.ttLib.woff2 import compress
compress('${input}', '${output}')
`
    )
    writeFileSync('output.woff2', data)
  })

Web

import { generateBasicScript, handleFontBuffer, NameId } from '@subframe7536/fonttools/utils'
import { loadInBrowser } from '@subframe7536/fonttools/web'

import src from './test.ttf'

const buf = await (await fetch(src)).arrayBuffer()
const py = await loadInBrowser()
const data = await handleFontBuffer(
  py,
  new Uint8Array(buf),
  generateBasicScript(`
def set_font_name(font: TTFont, name: str, id: int):
    font["name"].setName(name, nameID=id, platformID=1, platEncID=0, langID=0x0)
    font["name"].setName(name, nameID=id, platformID=3, platEncID=1, langID=0x409)
set_font_name(font, 'Test', ${NameId.FamilyName})
`),
)
// download
const url = URL.createObjectURL(new Blob([data]))
const a = document.createElement('a')
a.href = url
a.download = 'output.ttf'
a.click()
a.remove()

Vite Plugin

Copy assets to root while building

import { fonttools } from '@subframe7536/fonttools/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [fonttools()],
})

Custom URL

There are 6 assets that the plugin handled:

  • 2 .whl file: For fonttools and brotli(for woff2)
  • 1 lock file: Load .whl
  • 1 asm.js file: EMScript generated file
  • 1 asm.wasm file: EMScript generated file
  • 1 zip file: Python stdlibs

And importer that use loadInBrowser imports lock file, asm.js, asm.wasm and zip file

Final loaded url pattern: {indexURL}{urlPrefix}{assetsName}

By default, all the assets is loaded from the same directory as importer in production. You should set it if your build.assetsDir or build.rollupOptions.output.assetFileNames is modified.

So, here is a example to custom assets url:

fonttools({
  customURL: (
    currentAssetsKey: AssetsKey,
    assetsNameMap: Map<AssetsKey, string>,
    finalAssetsPathMap: Map<AssetsKey, [path: string, source: string | Uint8Array]>,
    importer: [path: string, code: string]
  ) => `deep/${finalAssetsPathMap.get(currentAssetsKey)![0]}`
})

CDN Example

See in cdn.html

For esm.sh, you may need to setup options.stdlibURL and options.whlURL to correctly load

Credit

pyodide

License

MIT

0.3.0

11 months ago

0.3.2

10 months ago

0.3.1

10 months ago

0.2.2

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago