Skip to content

Commit b67d05b

Browse files
committed
Add Direction class wrapping hb_direction_t
1 parent 5538abe commit b67d05b

6 files changed

Lines changed: 71 additions & 11 deletions

File tree

MIGRATING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Affected APIs:
7171
- `shape` and `shapeWithTrace` now take `Feature[]` instead of a comma-separated string. Use the new `Feature` class (e.g. `new Feature("liga", 0)` or `Feature.fromString("-liga")`).
7272
- `Buffer.setLanguage`, `Face.getName`, `Face.listNames`, and `otTagToLanguage` now use the new `Language` class instead of plain BCP 47 strings (e.g. `buffer.setLanguage(new Language("en"))`).
7373
- `Buffer.setScript` and `otTagToScript` now use the new `Script` class instead of plain ISO 15924 tag strings (e.g. `buffer.setScript(new Script("Latn"))` or, for the predefined ISO 15924 scripts, `buffer.setScript(Script.LATIN)`).
74+
- `Direction` is now a class with `INVALID`/`LTR`/`RTL`/`TTB`/`BTT` static instances and a string constructor. `Buffer.setDirection` takes a `Direction` instance; the call form `buffer.setDirection(Direction.RTL)` shown in the v0 → v1 table above keeps working.
7475
- `Buffer.addText` / `Buffer.addCodePoints`: `itemLength` accepts `undefined` (or omission), instead of `null`.
7576
- `Face.getFeatureNameIds`: returns `undefined` on failure, instead of `null`.
7677
- `Font.glyphHOrigin` / `glyphVOrigin` / `glyphExtents` / `glyphFromName`: return `undefined` on failure, instead of `null`.

harfbuzz.symbols

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ _hb_buffer_get_content_type
1616
_hb_buffer_guess_segment_properties
1717
_hb_buffer_set_cluster_level
1818
_hb_buffer_set_direction
19+
_hb_direction_from_string
20+
_hb_direction_to_string
1921
_hb_buffer_set_flags
2022
_hb_buffer_set_language
2123
_hb_buffer_set_script

src/buffer.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { GlyphInfo, GlyphPosition } from "./types";
1111
import { Font } from "./font";
1212
import type { Language } from "./language";
1313
import type { Script } from "./script";
14+
import type { Direction } from "./direction";
1415

1516
export const BufferContentType = {
1617
INVALID: 0,
@@ -45,15 +46,6 @@ export const BufferFlag = {
4546
} as const;
4647
export type BufferFlag = ValueOf<typeof BufferFlag>;
4748

48-
export const Direction = {
49-
INVALID: 0,
50-
LTR: 4,
51-
RTL: 5,
52-
TTB: 6,
53-
BTT: 7,
54-
} as const;
55-
export type Direction = ValueOf<typeof Direction>;
56-
5749
export const ClusterLevel = {
5850
MONOTONE_GRAPHEMES: 0,
5951
MONOTONE_CHARACTERS: 1,
@@ -162,10 +154,10 @@ export class Buffer {
162154

163155
/**
164156
* Set buffer direction explicitly.
165-
* @param dir A {@link Direction} value.
157+
* @param dir The buffer direction.
166158
*/
167159
setDirection(dir: Direction): void {
168-
exports.hb_buffer_set_direction(this.ptr, dir);
160+
exports.hb_buffer_set_direction(this.ptr, dir.value);
169161
}
170162

171163
/**

src/direction.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { exports, string_to_ascii_ptr, utf8_ptr_to_string } from "./helpers";
2+
3+
/**
4+
* The direction of a text segment or buffer.
5+
*
6+
* A segment can also be tested for horizontal or vertical orientation
7+
* (irrespective of specific direction).
8+
*/
9+
export class Direction {
10+
/** Initial, unset direction. */
11+
static readonly INVALID = new Direction(0);
12+
/** Text is set horizontally from left to right. */
13+
static readonly LTR = new Direction(4);
14+
/** Text is set horizontally from right to left. */
15+
static readonly RTL = new Direction(5);
16+
/** Text is set vertically from top to bottom. */
17+
static readonly TTB = new Direction(6);
18+
/** Text is set vertically from bottom to top. */
19+
static readonly BTT = new Direction(7);
20+
21+
readonly value: number;
22+
23+
/**
24+
* Converts a string to a Direction. Matching is loose and case-insensitive;
25+
* the first letter determines the direction (`l`/`L`: LTR, `r`/`R`: RTL,
26+
* `t`/`T`: TTB, `b`/`B`: BTT). Other strings yield `Direction.INVALID`.
27+
* @param name A string like `"ltr"`, `"rtl"`, `"ttb"`, or `"btt"`.
28+
*/
29+
constructor(name: string);
30+
/** @internal Wrap an existing hb_direction_t. */
31+
constructor(existingValue: number);
32+
constructor(arg: string | number) {
33+
if (typeof arg === "number") {
34+
this.value = arg;
35+
} else {
36+
const strPtr = string_to_ascii_ptr(arg);
37+
this.value = exports.hb_direction_from_string(strPtr.ptr, -1);
38+
strPtr.free();
39+
}
40+
}
41+
42+
/**
43+
* Converts the Direction to a string.
44+
* @returns A string like `"ltr"`, `"rtl"`, `"ttb"`, `"btt"`, or `"invalid"`.
45+
*/
46+
toString(): string {
47+
return utf8_ptr_to_string(exports.hb_direction_to_string(this.value));
48+
}
49+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export * from "./buffer";
1010
export * from "./feature";
1111
export * from "./language";
1212
export * from "./script";
13+
export * from "./direction";
1314
export * from "./shape";
1415

1516
init(await createHarfBuzz());

test/index.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,21 @@ describe("Buffer", function () {
10821082
});
10831083
});
10841084

1085+
describe("Direction", function () {
1086+
it("toString returns the lowercase direction name", function () {
1087+
expect(hb.Direction.LTR.toString()).to.equal("ltr");
1088+
expect(hb.Direction.RTL.toString()).to.equal("rtl");
1089+
expect(hb.Direction.TTB.toString()).to.equal("ttb");
1090+
expect(hb.Direction.BTT.toString()).to.equal("btt");
1091+
expect(hb.Direction.INVALID.toString()).to.equal("invalid");
1092+
});
1093+
1094+
it("string constructor parses the direction name", function () {
1095+
expect(new hb.Direction("ltr")).to.deep.equal(hb.Direction.LTR);
1096+
expect(new hb.Direction("RTL")).to.deep.equal(hb.Direction.RTL);
1097+
});
1098+
});
1099+
10851100
describe("Script", function () {
10861101
it("toString returns the ISO 15924 tag", function () {
10871102
expect(hb.Script.LATIN.toString()).to.equal("Latn");

0 commit comments

Comments
 (0)