Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions hbjs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/** @typedef {import('./types').HBModule} HBModule */
/** @typedef {import('./types').HBHandle} HBHandle */
/** @typedef {import('./types').HBBlob} HBBlob */
/** @typedef {import('./types').HBFace} HBFace */
/** @typedef {import('./types').HBFont} HBFont */
/** @typedef {import('./types').HBBuffer} HBBuffer */
/** @typedef {import('./types').HBFontFuncs} HBFontFuncs */

/**
* @param {HBModule} Module
* @returns {HBHandle}
*/
function hbjs(Module) {
'use strict';

Expand Down Expand Up @@ -133,7 +145,8 @@ function hbjs(Module) {

/**
* Create an object representing a Harfbuzz blob.
* @param {string} blob A blob of binary data (usually the contents of a font file).
* @param {ArrayBuffer|Uint8Array} blob A blob of binary data (usually the contents of a font file).
* @returns {HBBlob}
**/
function createBlob(blob) {
var blobPtr = exports.malloc(blob.byteLength);
Expand Down Expand Up @@ -165,9 +178,10 @@ function hbjs(Module) {

/**
* Create an object representing a Harfbuzz face.
* @param {object} blob An object returned from `createBlob`.
* @param {HBBlob} blob An object returned from `createBlob`.
* @param {number} index The index of the font in the blob. (0 for most files,
* or a 0-indexed font number if the `blob` came form a TTC/OTC file.)
* @returns {HBFace}
**/
function createFace(blob, index) {
var ptr = exports.hb_face_create(blob.ptr, index);
Expand Down Expand Up @@ -413,8 +427,9 @@ function hbjs(Module) {

/**
* Create an object representing a Harfbuzz font.
* @param {object} blob An object returned from `createFace`.
* @param {number} ptr Optional pointer to an existing font.
* @param {HBFace|null} face An object returned from `createFace`.
* @param {number} [ptr] Optional pointer to an existing font.
* @returns {HBFont}
**/
function createFont(face, ptr) {
var ptr = ptr ? exports.hb_font_reference(ptr) : exports.hb_font_create(face.ptr);
Expand Down Expand Up @@ -662,7 +677,8 @@ function hbjs(Module) {
}

/**
* Create a object representing a HarfBuzz font functions.
* Create an object representing HarfBuzz font functions.
* @returns {HBFontFuncs}
**/
function createFontFuncs() {
var ptr = exports.hb_font_funcs_create();
Expand Down Expand Up @@ -961,7 +977,8 @@ function hbjs(Module) {

/**
* Create an object representing a Harfbuzz buffer.
* @param {number} ptr Optional. The pointer to the buffer.
* @param {number} [ptr] Optional. The pointer to the buffer.
* @returns {HBBuffer}
**/
function createBuffer(ptr) {
var ptr = ptr ? exports.hb_buffer_reference(ptr) : exports.hb_buffer_create();
Expand Down Expand Up @@ -1261,10 +1278,10 @@ function hbjs(Module) {
*
* This returns nothing, but modifies the buffer.
*
* @param {object} font: A font returned from `createFont`
* @param {object} buffer: A buffer returned from `createBuffer` and suitably
* @param {HBFont} font A font returned from `createFont`
* @param {HBBuffer} buffer A buffer returned from `createBuffer` and suitably
* prepared.
* @param {object} features: A string of comma-separated OpenType features to apply.
* @param {string} [features] A string of comma-separated OpenType features to apply.
*/
function shape(font, buffer, features) {
var featuresPtr = 0;
Expand Down
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @typedef {import('./types').HBHandle} HBHandle */

var hbjs = require('./hbjs.js');
var hb = require('./hb.js');

/** @type {Promise<HBHandle>} */
module.exports = new Promise(function (resolve, reject) {
hb().then((instance) => {
resolve(hbjs(instance));
Expand Down
13 changes: 13 additions & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"checkJs": true,
"strict": false,
"noImplicitAny": false,
"moduleResolution": "node",
"target": "ES2020",
"module": "CommonJS",
"skipLibCheck": true
},
"include": ["hbjs.js", "index.js", "types.d.ts"],
"exclude": ["node_modules", "dist", "hb.js"]
}
210 changes: 210 additions & 0 deletions types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
export type HBModule = {
wasmExports: WebAssembly.Exports;
wasmMemory: WebAssembly.Memory;
HEAP8: Int8Array;
HEAP16: Int16Array;
HEAP32: Int32Array;
HEAPU8: Uint8Array;
HEAPU16: Uint16Array;
HEAPU32: Uint32Array;
HEAPF32: Float32Array;
HEAPF64: Float64Array;
addFunction: (fn: Function, signature: string) => number;
removeFunction: (ptr: number) => void;
stackSave: () => number;
stackRestore: (ptr: number) => void;
stackAlloc: (size: number) => number;
};

export type HBBlob = {
ptr: number;
destroy: () => void;
};

export type AxisInfo = {
min: number;
default: number;
max: number;
};

export type NameEntry = {
nameId: number;
language: string;
};

export type FeatureNameIds = {
uiLabelNameId: number | null;
uiTooltipTextNameId: number | null;
sampleTextNameId: number | null;
paramUiLabelNameIds: number[];
} | null;

export type HBFace = {
ptr: number;
upem: number;
reference_table: (table: string) => Uint8Array | undefined;
getAxisInfos: () => Record<string, AxisInfo>;
collectUnicodes: () => Uint32Array;
getTableScriptTags: (table: string) => string[];
getTableFeatureTags: (table: string) => string[];
getScriptLanguageTags: (table: string, scriptIndex: number) => string[];
getLanguageFeatureTags: (table: string, scriptIndex: number, languageIndex: number) => string[];
listNames: () => NameEntry[];
getName: (nameId: number, language: string) => string;
getFeatureNameIds: (table: string, featureIndex: number) => FeatureNameIds;
destroy: () => void;
};

export type SvgPathCommand =
| { type: "M"; values: number[] }
| { type: "L"; values: number[] }
| { type: "Q"; values: number[] }
| { type: "C"; values: number[] }
| { type: "Z"; values: number[] };

export type HBVariations = Record<string, number>;

export type FontExtents = {
ascender: number;
descender: number;
lineGap: number;
};

export type GlyphExtents = {
xBearing: number;
yBearing: number;
width: number;
height: number;
};

export type HBFont = {
ptr: number;
subFont: () => HBFont;
hExtents: () => FontExtents;
vExtents: () => FontExtents;
glyphName: (glyphId: number) => string;
glyphToPath: (glyphId: number) => string;
glyphToJson: (glyphId: number) => SvgPathCommand[];
glyphHAdvance: (glyphId: number) => number;
glyphVAdvance: (glyphId: number) => number;
glyphHOrigin: (glyphId: number) => [number, number] | null;
glyphVOrigin: (glyphId: number) => [number, number] | null;
glyphExtents: (glyphId: number) => GlyphExtents | null;
glyphFromName: (name: string) => number | null;
setScale: (xScale: number, yScale: number) => void;
setVariations: (variations: HBVariations) => void;
setFuncs: (fontFuncs: HBFontFuncs) => void;
destroy: () => void;
};

export type HBFontFuncs = {
ptr: number;
setGlyphExtentsFunc: (func: (font: HBFont, glyph: number) => GlyphExtents | null) => void;
setGlyphFromNameFunc: (func: (font: HBFont, name: string) => number | null) => void;
setGlyphHAdvanceFunc: (func: (font: HBFont, glyph: number) => number) => void;
setGlyphVAdvanceFunc: (func: (font: HBFont, glyph: number) => number) => void;
setGlyphHOriginFunc: (func: (font: HBFont, glyph: number) => [number, number] | null) => void;
setGlyphVOriginFunc: (func: (font: HBFont, glyph: number) => [number, number] | null) => void;
setGlyphHKerningFunc: (func: (font: HBFont, firstGlyph: number, secondGlyph: number) => number) => void;
setGlyphNameFunc: (func: (font: HBFont, glyph: number) => string | null) => void;
setNominalGlyphFunc: (func: (font: HBFont, unicode: number) => number | null) => void;
setVariationGlyphFunc: (func: (font: HBFont, unicode: number, variationSelector: number) => number | null) => void;
setFontHExtentsFunc: (func: (font: HBFont) => FontExtents | null) => void;
setFontVExtentsFunc: (func: (font: HBFont) => FontExtents | null) => void;
destroy: () => void;
};

export type HBFlag =
| "DEFAULT"
| "BOT"
| "EOT"
| "PRESERVE_DEFAULT_IGNORABLES"
| "REMOVE_DEFAULT_IGNORABLES"
| "DO_NOT_INSERT_DOTTED_CIRCLE"
| "VERIFY"
| "PRODUCE_UNSAFE_TO_CONCAT"
| "PRODUCE_SAFE_TO_INSERT_TATWEEL";

export type HBSerializeFlag =
| "DEFAULT"
| "NO_CLUSTERS"
| "NO_POSITIONS"
| "NO_GLYPH_NAMES"
| "GLYPH_EXTENTS"
| "GLYPH_FLAGS"
| "NO_ADVANCES";

export type HBDir = "ltr" | "rtl" | "ttb" | "btt";

export type HBContentType = "INVALID" | "UNICODE" | "GLYPHS";

export type GlyphInfo = {
codepoint: number;
cluster: number;
};

export type GlyphPosition = {
x_advance: number;
y_advance: number;
x_offset: number;
y_offset: number;
};

export type HBJson = {
g: number;
cl: number;
ax: number;
ay: number;
dx: number;
dy: number;
flags: number;
};

export type HBBuffer = {
ptr: number;
addText: (text: string, itemOffset?: number, itemLength?: number | null) => void;
addCodePoints: (codePoints: number[], itemOffset?: number, itemLength?: number | null) => void;
guessSegmentProperties: () => void;
setDirection: (dir: HBDir) => void;
setFlags: (flags: HBFlag[]) => void;
setLanguage: (language: string) => void;
setScript: (script: string) => void;
setClusterLevel: (level: number) => void;
reset: () => void;
clearContents: () => void;
setMessageFunc: (func: (buffer: HBBuffer, font: HBFont, message: string) => boolean) => void;
getLength: () => number;
getGlyphInfos: () => GlyphInfo[];
getGlyphPositions: () => GlyphPosition[];
updateGlyphPositions: (positions: GlyphPosition[]) => void;
serialize: (font?: HBFont | null, start?: number, end?: number | null, format?: string, flags?: HBSerializeFlag[]) => string;
getContentType: () => HBContentType;
json: () => HBJson[];
destroy: () => void;
};

export type TraceEntry = {
m: string;
t: object[];
glyphs: boolean;
};

export type HBVersion = {
major: number;
minor: number;
micro: number;
};

export type HBHandle = {
createBlob: (blob: ArrayBuffer | Uint8Array) => HBBlob;
createFace: (blob: HBBlob, index: number) => HBFace;
createFont: (face: HBFace) => HBFont;
createFontFuncs: () => HBFontFuncs;
createBuffer: () => HBBuffer;
shape: (font: HBFont, buffer: HBBuffer, features?: string) => void;
shapeWithTrace: (font: HBFont, buffer: HBBuffer, features: string, stop_at: number, stop_phase: number) => TraceEntry[];
version: () => HBVersion;
version_string: () => string;
otTagToScript: (tag: string) => string;
otTagToLanguage: (tag: string) => string;
};