Fixed-point ↔ float conversions for binary format I/O (SFNT, TIFF, DSP).
Module fixedPoint | Source packages/front/fw/src/io/math/fixed-point.js | Deps none | Worker-safe yes
Conversions between fixed-point representations (Fixed16.16, F2Dot14, FUnit) and JS floats. Covers SFNT / OpenType formats (matrices, axis coords, design units), TIFF and audio/DSP variants. Includes a generic parameterizable helper (arbitrary intBits + fracBits).
Resolve
const fp = runtime.resolve('fixedPoint');
// Returns: { fixed16ToFloat, floatToFixed16, ufixed16ToFloat, floatToUfixed16,
// f2dot14ToFloat, floatToF2dot14, funitToPx, fixedToFloat, floatToFixed }
API
| Method | Signature | Returns |
|---|---|---|
fixed16ToFloat |
(raw: number) => number |
Float from signed Fixed16.16 |
floatToFixed16 |
(value: number, opts?) => number |
Signed Fixed16.16 (bit-pattern uint32) |
ufixed16ToFloat |
(raw: number) => number |
Float from unsigned UFix16.16 |
floatToUfixed16 |
(value: number, opts?) => number |
UFix16.16 (bit-pattern uint32) |
f2dot14ToFloat |
(raw: number) => number |
Float from signed F2Dot14 (16 bits) |
floatToF2dot14 |
(value: number, opts?) => number |
F2Dot14 (bit-pattern uint16, 0x0000–0xFFFF) |
funitToPx |
(unitsPerEm: number, fontSize: number, funit: number) => number |
Design units → pixels |
fixedToFloat |
(raw, intBits, fracBits, signed?) => number |
Generic: raw → float |
floatToFixed |
(value, intBits, fracBits, signed?, opts?) => number |
Generic: float → bit-pattern |
Option opts
The floatTo* functions accept an optional { strict: boolean } object:
strict: false(default) — out-of-range values are clamped; NaN/Infinity return0or the max value.strict: true— throwsRangeErroron NaN, Infinity, or range overflow.
Supported formats
| Type | Total bits | Integer bits | Fraction bits | Range |
|---|---|---|---|---|
| Signed Fixed16.16 | 32 | 16 | 16 | -32768 to 32767.99998… |
| Unsigned UFix16.16 | 32 | 16 | 16 | 0 to 65535.99998… |
| Signed F2Dot14 | 16 | 2 | 14 | -2 to 1.99993… |
| FUnit | variable | — | — | integer × (1 / unitsPerEm) |
Examples
SFNT / OpenType — matrices and axis coords
const fp = runtime.resolve('fixedPoint');
// Read a Fixed16.16 matrix from a DataView
const m00 = fp.fixed16ToFloat(view.getUint32(offset, false)); // → e.g. 1.0
// Axis coordinate F2Dot14 (avar / gvar)
const coord = fp.f2dot14ToFloat(view.getUint16(offset, false)); // → -1.0 … 1.99993…
// Design-unit → pixels (layout)
const px = fp.funitToPx(2048, 16, 1024); // → 8.0
Generic Fixed8.8 (unsigned)
const fp = runtime.resolve('fixedPoint');
const value = fp.fixedToFloat(0x0180, 8, 8, false); // → 1.5
const raw = fp.floatToFixed(1.5, 8, 8, false); // → 0x0180
Strict conversion (throws on overflow)
const fp = runtime.resolve('fixedPoint');
fp.floatToFixed16(100000); // → 0x7FFFFFFF (clamp)
fp.floatToFixed16(100000, { strict: true }); // throws RangeError
fp.floatToFixed16(NaN); // → 0
fp.floatToFixed16(NaN, { strict: true }); // throws RangeError
Worker Usage
const worker = fw.createWorker(
function ({ libs, args }) {
const result = libs.fixedPoint.fixed16ToFloat(args.raw);
self.postMessage(result);
},
{ dependencies: ['fixedPoint'], args: { raw: 0x00018000 } } // → 1.5
);
Notes
- float64 precision: Fixed16.16 (32 bits) fits comfortably within
Number.MAX_SAFE_INTEGER; noBigIntneeded in v1. - F2Dot14 boundary:
floatToF2dot14(2.0)→0x7FFF(max representable),floatToF2dot14(-2.0)→0x8000(min). - Unsigned representation:
floatTo*methods always return an unsigned bit-pattern (positive JS integer), even for signed formats — conforming to the DataView/ArrayBuffer standard. - No npm dependencies: pure JS implementation, worker-safe.