Skip to content

Creating an OTF

This guide is for building a single CFF-based OpenType font (.otf).

Required tables

These are the practical minimum required by Font Flux validation for a valid single-font export.

  • cmap: Unicode code point to glyph mapping.
  • head: Global font header and bounds metadata.
  • hhea: Horizontal layout header values.
  • hmtx: Horizontal advance/side-bearing metrics.
  • maxp: Glyph count and profile limits.
  • name: Family/style/version naming records.
  • post: PostScript-oriented metadata.

Outline requirement (choose exactly one):

  • CFF : Compact Font Format v1 outlines.
  • CFF2: Compact Font Format v2 outlines.
  • OS/2: Platform metrics/flags used widely by layout engines.

Optional tables (grouped by function)

Layout and Typography

  • BASE: Baseline coordination across scripts.
  • GDEF: Glyph classes and attachment metadata for layout.
  • GPOS: Advanced glyph positioning rules.
  • GSUB: Advanced glyph substitution rules.
  • JSTF: Script-specific justification behavior.
  • kern: Legacy kerning pairs.
  • MATH: Math typography layout data.

Variations (Variable Fonts)

  • fvar: Variation axis definitions.
  • avar: Non-linear axis mapping.
  • STAT: Style attributes and axis naming.
  • HVAR: Horizontal metrics variation deltas.
  • MVAR: Global metrics variation deltas.
  • VVAR: Vertical metrics variation deltas.

Color and Emoji Presentation

  • COLR: Layered or paint-graph color glyph composition.
  • CPAL: Color palettes consumed by COLR.
  • SVG : SVG glyph outlines.
  • CBDT: Color bitmap glyph image data.
  • CBLC: Index/location data for CBDT strikes.
  • EBDT: Embedded bitmap glyph image data.
  • EBLC: Embedded bitmap location/index data.
  • EBSC: Embedded bitmap scaling metadata.
  • sbix: Apple bitmap glyphs.

Vertical Layout

  • vhea: Vertical header metrics.
  • vmtx: Vertical metrics per glyph.
  • VORG: CFF vertical origin defaults.

Device, Grid-Fit, and Legacy Metrics

  • hdmx: Device-specific horizontal metrics.
  • LTSH: Linear threshold hints.
  • VDMX: Vertical device metrics data.
  • PCLT: PCL printer-oriented metrics.

Metadata and Miscellaneous

  • meta: Arbitrary metadata tags.
  • DSIG: Digital signature container (legacy/deprecated use).
  • MERG: Merge metadata (rare).

Notes

  • Use CFF for CFF v1 workflows and CFF2 for modern variable-friendly CFF2 workflows.

Working with CFF outlines

CFF fonts store glyph outlines as Type 2 charstring byte arrays — an opaque binary program format. Font Flux decodes these into editable cubic Bézier contour data.

Reading outlines

When you open an OTF with FontFlux.open(), each glyph includes:

  • contours — decoded cubic Bézier commands: M (moveTo), L (lineTo), C (curveTo)
  • charString — the raw charstring bytes (for lossless export)
  • charStringDisassembly — human-readable charstring text
js
const font = FontFlux.open(buffer);
const glyph = font.getGlyph('A');
console.log(glyph.contours); // [[{ type: 'M', x, y }, { type: 'C', ... }, ...]]
console.log(glyph.charStringDisassembly); // "100 700 rmoveto 300 0 rlineto ..."

For table-level work, use FontFlux.interpretCharString() and FontFlux.disassembleCharString() directly on charstring byte arrays. See the CFF or CFF2 table docs.

Editing outlines via SVG

Convert contours to SVG path strings for visual editing, then convert back:

js
import { FontFlux } from 'font-flux-js';

const svg = FontFlux.contoursToSVG(glyph.contours); // "M100 700 C... Z"
// ... edit the SVG path string ...
const newContours = FontFlux.svgToContours(svg, 'cff');

CFF outlines produce C (cubic) SVG commands. The round-trip is lossless for cubic paths. See the SVG path conversion docs for details on supported SVG commands and coordinate handling.

Creating CFF glyphs from scratch

For a complete guide to hand-authoring glyph data — including .addGlyph(), all outline formats, metadata reference, and examples — see Creating Glyphs.

  • Keep required metrics tables (head, hhea, hmtx, maxp) consistent with your outline and glyph count.
  • Validate early with .validate().

Creating an OTC (OpenType Collection)

An .otc file bundles multiple CFF-based OpenType font faces into a single binary. Each face is a complete OTF — it must satisfy all the requirements above.

Required collection shape

At the top level, collection JSON uses this shape:

json
{
	"collection": {
		"tag": "ttcf",
		"majorVersion": 2,
		"minorVersion": 0,
		"numFonts": 2
	},
	"fonts": [
		{ "header": {}, "tables": {} },
		{ "header": {}, "tables": {} }
	]
}

Each entry in fonts[] is validated as a normal single font — it needs the same required tables listed above (cmap, head, hhea, hmtx, maxp, name, post, plus CFF or CFF2).

Optional collection-level fields

  • collection.dsigTag: DSIG tag for TTC v2+ metadata.
  • collection.dsigLength: DSIG block length.
  • collection.dsigOffset: DSIG block offset.

Notes

  • collection.numFonts should match fonts.length.
  • Faces in a collection can mix CFF v1 and CFF v2 as long as each face is internally valid.
  • Validate full collection JSON with .validate() before export.