1.0.0 • Published 3 months ago

msdfgen-wasm v1.0.0

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

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

3 months ago