mtx-decompressor

Zero-dependency TypeScript that decompresses MicroType Express (MTX) font data from EOT containers into standard TrueType (.ttf) fonts — in the browser or Node.

zero dependencies runs client-side MPL-2.0

npm  ·  GitHub

What is this?

MTX is a font-compression format from Monotype used inside EOT (Embedded OpenType) containers — common in older web pages and embedded in Microsoft Office documents (including PPTX). mtx-decompressor unpacks that compressed data and reconstructs a standard .ttf file you can use with any normal font API. It has no runtime dependencies and works entirely in the browser.

Install

npm i mtx-decompressor

Usage

import { decompressMtx, decompressEotFont } from 'mtx-decompressor';

// `fontData` is the MTX blob extracted from an EOT container (Uint8Array).
const ttfBytes = decompressMtx(fontData, { compressed: true, encrypted: false });
// => Uint8Array containing a valid TrueType font

// Convenience wrapper with explicit booleans: (fontData, compressed, encrypted)
const ttf = decompressEotFont(fontData, true, false);

// In the browser, register the recovered font and use it:
const face = new FontFace('MyFont', ttfBytes.buffer);
await face.load();
document.fonts.add(face);

Note: the library operates on the MTX font blob inside the EOT container. The live demo below includes a small EOT-header parser to locate that blob and read its compression/encryption flags before calling decompressMtx.

Try it live

Pick or drop an .eot file. Everything runs locally in your browser — nothing is uploaded.

Choose an .eot file to begin.

How it works

  1. Optional XOR decryption (key 0x50).
  2. MTX header parsing — splits the blob into three LZCOMP-compressed blocks.
  3. LZCOMP decompression — sliding-window LZ with adaptive Huffman coding.
  4. CTF parsing — reconstructs TrueType tables from the three Compact TrueType Font streams (glyph data, push instructions, hinting code).
  5. SFNT assembly — table directory, 4-byte alignment, and checksums.

Examples

The live demo above is the example: it reads an EOT file, calls decompressMtx, and renders the recovered font. The equivalent code, end to end:

// 1. Read the EOT file as bytes (e.g. from a file input).
const buffer = await file.arrayBuffer();
const view = new DataView(buffer);

// 2. EOT header (little-endian): locate the trailing font blob + flags.
const eotSize = view.getUint32(0, true);
const fontDataSize = view.getUint32(4, true);
const flags = view.getUint32(12, true);
const fontData = new Uint8Array(buffer, eotSize - fontDataSize, fontDataSize);

// 3. Decompress with the library.
const ttf = decompressMtx(fontData, {
  compressed: (flags & 0x00000004) !== 0, // TTEMBED_TTCOMPRESSED
  encrypted: (flags & 0x10000000) !== 0,  // TTEMBED_XORENCRYPTDATA
});

// 4. Use it: download, or register via FontFace.
const url = URL.createObjectURL(new Blob([ttf], { type: 'font/ttf' }));