1.0.0 • Published 11 months ago
msdfgen-wasm v1.0.0
msdfgen-wasm
A webassembly build of https://github.com/Chlumsky/msdfgen (including skia preprocessing), together with typescript bindings and texture atlas generation.
Allows for generation of msdf fonts from browser with no external services.
Usage example (nodejs)
const fs = require("fs")
const Msdfgen = require("msdfgen-wasm").Msdfgen
async function run() {
// create the module
const wasm = fs.readFileSync("./wasm/msdfgen.wasm")
const msdfgen = await Msdfgen.create(wasm)
// load font file (supports ttf, otf and woff, woff2 not supported as brotli not included in build)
msdfgen.loadFont(fs.readFileSync(process.argv[2]))
// load glyphs by passing a array of unicode codes, only glyphs present in font are loaded
// preprocess enables skia preprocessing (enabled by default when second argument omitted)
msdfgen.loadGlyphs(new Array(256).fill(0).map((x, i) => i), {preprocess: true})
// log amount of loaded glyphs by accessing loaded glyphs array
console.log(`loaded ${msdfgen.glyphs.length} glyphs`)
// msdf generation configuration
const msdfOptions = {
size: 32,
range: 4,
// (optional) edgeColoring: "simple",
// (optional) edgeThresholdAngle: 3,
// (optional) scanline: false
}
// texture atlas generation configuration
const atlasOptions = {
maxWidth: 2048,
maxHeight: 2048,
padding: 1,
pot: true,
smart: true,
allowRotation: true,
// [...] other options from MaxRectsPacker
}
// resolve the texture packing
const bins = msdfgen.packGlyphs(msdfOptions, atlasOptions)
// generate glyph bitmaps and create packed png images
// see createAtlasImage implementation if you want to first generate all the
// glyphs bitmaps and then put them on the atlas (for example to do parallel processing)
const images = bins.map(bin => msdfgen.createAtlasImage(bin))
// example for getting a single glyph's bitmap
//
// const glyph = msdfdata.getGlyph(0x0042)
// const glpyhMsdfData = msdfdata.computeGlpyhMsdfData(glyph, msdfOptions)
// const bitmap = msdfdata.generateBitmap(glyph, glpyhMsdfData)
// const output = msdfdata.createPng(bitmap, 9)
// fs.writeFileSync("test.png", output)
// read loaded font metrics (metrics are in normalized em units)
const metrics = msdfgen.metrics
// generate a json in the bmfont format
const chars = []
const kernings = []
const round = x => Math.round(x * 100 * msdfOptions.size) / 100
for (let i = 0; i < bins.length; i += 1) {
const bin = bins[i]
for (const rect of bin.rects) {
const glyph = rect.glyph
const range = rect.msdfData.range
const hasSize = rect.width && rect.height
chars.push({
id: glyph.unicode,
width: rect.width,
height: rect.height,
x: rect.x,
y: rect.y,
rotated: rect.rot ? true : undefined,
page: i,
xadvance: round(glyph.advance),
xoffset: hasSize ? round(glyph.left - range / 2) : 0,
yoffset: hasSize ? round(metrics.ascenderY - (glyph.top + range / 2)) : 0
})
for (const kerning of glyph.kerning) {
kernings.push({
first: glyph.unicode,
second: kerning[0].unicode,
amount: round(kerning[1])
})
}
}
}
// not all bmfont fields are present in this example
const bmFontJson = {
pages: images.map((x, i) => `font_${i}.png`),
info: {
size: 1,
face: ""
},
common: {
lineHeight: round(metrics.lineHeight),
base: round(metrics.ascenderY)
},
distanceField: {
distanceRange: msdfOptions.range
},
chars,
kernings
}
fs.writeFileSync("font.json", JSON.stringify(bmFontJson))
images.map((x, i) => fs.writeFileSync(`font_${i}.png`, x))
}
run().catch(e => console.error(e))Building wasm module
module is pre-build in the npm package, but if you want to build it yourself make sure emsdk is installed and run npm run compile, no other dependencies are needed.
1.0.0
11 months ago