Skip to content

Commit

Permalink
temp: first implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
romgere committed Mar 9, 2024
1 parent f71b779 commit e89e325
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
28 changes: 28 additions & 0 deletions app/services/harfbuzz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Service from '@ember/service';
import hb from 'harfbuzzjs/hbjs';
import type { HBInstance } from 'harfbuzzjs/hbjs';

export default class HarfbuzzService extends Service {
declare hb: HBInstance;

loadWASMPromise: undefined | Promise<void> = undefined;

async loadWASM() {
if (!this.loadWASMPromise) {
this.loadWASMPromise = this._loadWASM();
}

await this.loadWASMPromise;
}

async _loadWASM() {
const result = await WebAssembly.instantiateStreaming(fetch('/hb.wasm'));
this.hb = hb(result.instance);
}
}

declare module '@ember/service' {
interface Registry {
harfbuzz: HarfbuzzService;
}
}
Binary file added public/hb.wasm
Binary file not shown.
68 changes: 68 additions & 0 deletions types/harfbuzzjs.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
declare module 'harfbuzzjs/hbjs' {
type Direction = 'ltr' | 'rtl' | 'ttb' | 'btt';
type BufferFlag =
| 'BOT'
| 'EOT'
| 'PRESERVE_DEFAULT_IGNORABLES'
| 'REMOVE_DEFAULT_IGNORABLES'
| 'DO_NOT_INSERT_DOTTED_CIRCLE'
| 'PRODUCE_UNSAFE_TO_CONCAT';

type HBBlob = unknown;

export interface HBFace {
upem: number; //units per em
reference_table(table: string): Uint8Array;
getAxisInfos(): Record<string, { min: number; default: number; max: number }>;
collectUnicodes(): Uint32Array;
destroy(): void;
}

export interface SVGPathSegment {
type: 'M' | 'L' | 'Q' | 'C' | 'Z';
values: number[];
}

export type BufferContent = {
g: number; //The glyph ID
cl: number; //The cluster ID
ax: number; //Advance width (width to advance after this glyph is painted)
ay: number; //Advance height (height to advance after this glyph is painted)
dx: number; //X displacement (adjustment in X dimension when painting this glyph)
dy: number; //Y displacement (adjustment in Y dimension when painting this glyph)
flags: number; // Glyph flags like `HB_GLYPH_FLAG_UNSAFE_TO_BREAK` (0x1)
}[];

export interface HBFont {
glyphName(glyphId: number): string;
glyphToPath(glyphId: number): string;
glyphToJson(glyphId: number): SVGPathSegment[];
setScale(xScale: number, yScale: number): void;
setVariations(variations: Record<string, string | number | boolean>): void;
destroy(): void;
}

interface HBBuffer {
addText(text: string): void;
guessSegmentProperties(): void;
setDirection(dir: Direction): void;
setFlags(flags: BufferFlag[]): void;
setLanguage(language: string): void;
setScript(script: string): void;
setClusterLevel(level: number): void;
json(): BufferContent;
destroy(): void;
}

export interface HBInstance {
createBlob(buffer: ArrayBuffer): HBBlob;
createFace(blob: HBBlob, fontIndex: number): HBFace;
createFont(face: HBFace): HBFont;
createBuffer(): HBBuffer;
shape(font: HBFont, buffer: HBBuffer): void;
}

const hb: (instance: WebAssembly.Instance) => HBInstance;

export default hb;
}

0 comments on commit e89e325

Please sign in to comment.