@mark1russell7/typeset 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/build/breaking.d.ts +2 -1
- package/build/chunks/breaking.d.ts +2 -77
- package/build/chunks/breaking.d.ts.map +1 -1
- package/build/chunks/engines.d.ts +32 -0
- package/build/chunks/engines.d.ts.map +1 -0
- package/build/chunks/engines.js +35 -0
- package/build/chunks/engines.js.map +1 -0
- package/build/chunks/font.d.ts +203 -0
- package/build/chunks/font.d.ts.map +1 -0
- package/build/chunks/font.js +3550 -0
- package/build/chunks/font.js.map +1 -0
- package/build/chunks/fonts.d.ts +8 -0
- package/build/chunks/fonts.d.ts.map +1 -0
- package/build/chunks/fonts.js +13 -0
- package/build/chunks/fonts.js.map +1 -0
- package/build/chunks/measurer.d.ts +67 -0
- package/build/chunks/measurer.d.ts.map +1 -0
- package/build/chunks/measurer.js +277 -0
- package/build/chunks/measurer.js.map +1 -0
- package/build/chunks/paragraph.d.ts +78 -0
- package/build/chunks/paragraph.d.ts.map +1 -0
- package/build/chunks/sfnt.d.ts +22 -0
- package/build/chunks/sfnt.d.ts.map +1 -0
- package/build/chunks/text.d.ts +48 -0
- package/build/chunks/text.d.ts.map +1 -0
- package/build/chunks/text.js +237 -0
- package/build/chunks/text.js.map +1 -0
- package/build/fonts-inspect.d.ts +10 -0
- package/build/fonts-inspect.d.ts.map +1 -0
- package/build/fonts-inspect.js +1 -0
- package/build/fonts.d.ts +5 -0
- package/build/fonts.js +4 -0
- package/build/index.d.ts +4 -1
- package/build/index.js +5 -1
- package/build/measurer.d.ts +2 -0
- package/build/measurer.js +1 -0
- package/build/text.d.ts +2 -0
- package/build/text.js +1 -0
- package/package.json +22 -3
- package/src/fonts/bidi.ts +125 -0
- package/src/fonts/binary.ts +41 -0
- package/src/fonts/engines.ts +38 -0
- package/src/fonts/font.ts +442 -0
- package/src/fonts/gvar.ts +220 -0
- package/src/fonts/index.ts +10 -0
- package/src/fonts/indic.ts +585 -0
- package/src/fonts/joining.ts +141 -0
- package/src/fonts/kerning.ts +217 -0
- package/src/fonts/sfnt.ts +102 -0
- package/src/fonts/substitution.ts +586 -0
- package/src/fonts/tables.ts +140 -0
- package/src/fonts/variations.ts +175 -0
- package/src/fonts/words.ts +119 -0
- package/src/fonts-inspect.ts +8 -0
- package/src/fonts.ts +8 -0
- package/src/index.ts +3 -0
- package/src/measurer/advance.ts +307 -0
- package/src/measurer.ts +5 -0
- package/src/text/rope.ts +291 -0
- package/src/text.ts +1 -0
package/README.md
CHANGED
|
@@ -5,6 +5,9 @@ This package measures text and breaks it into lines. Each area has its own subpa
|
|
|
5
5
|
| Subpath | What it has |
|
|
6
6
|
| --- | --- |
|
|
7
7
|
| `@mark1russell7/typeset/breaking` | The paragraph model of boxes, glue and penalties, and the greedy, total fit and balanced line breakers. |
|
|
8
|
+
| `@mark1russell7/typeset/fonts` | The font model: it reads a font file and gives the width of a text as a browser engine gives it. |
|
|
9
|
+
| `@mark1russell7/typeset/measurer` | `fontAdvance`: the advance function of a layout engine, from the font files of the host. |
|
|
10
|
+
| `@mark1russell7/typeset/text` | The `Text` rope: a text with its width, and edits that measure only the changed parts. |
|
|
8
11
|
|
|
9
12
|
## Line breaking
|
|
10
13
|
|
|
@@ -20,4 +23,39 @@ const lines = linesOf(paragraph, knuthPlass.breaks(paragraph, 120));
|
|
|
20
23
|
- `greedy` fills each line as a browser does. `knuthPlass` chooses the breaks with the least sum of demerits. `balanced` keeps the greedy line count with more equal lines.
|
|
21
24
|
- The option `hyphenate` gives the offsets of the hyphen breaks of a word.
|
|
22
25
|
|
|
26
|
+
## The Text rope
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { Text } from "@mark1russell7/typeset/text";
|
|
30
|
+
|
|
31
|
+
const widthOf = (text: string): number => 8 * [...text].length;
|
|
32
|
+
const text = Text.from("The quick brown fox", widthOf);
|
|
33
|
+
const edited = text.insert(4, "very ").remove(0, 4);
|
|
34
|
+
console.log(edited.toString(), edited.width);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- Each edit gives a new rope. The old rope does not change, and the two share the parts that the edit does not touch.
|
|
38
|
+
- An edit uses the width function of the order of `log n` times, on the changed leaves and on short windows.
|
|
39
|
+
- The width is exact when the width function obeys the separator law: `width(p + s + q) = width(p + s) + width(s + q) - width(s)`.
|
|
40
|
+
- The separator `s` is a space or a tab. The option `separators` changes the set.
|
|
41
|
+
- The font model of `./fonts` obeys the law for its shaping `dom` and `canvas`, with the sum `exact`.
|
|
42
|
+
|
|
43
|
+
## The font model and the measurer
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { readFileSync } from "node:fs";
|
|
47
|
+
import { createMeasurer, layoutText } from "@mark1russell7/layout-contract/text";
|
|
48
|
+
import { fontAdvance } from "@mark1russell7/typeset/measurer";
|
|
49
|
+
|
|
50
|
+
const advance = fontAdvance({ faces: [{ family: "Noto Sans", data: readFileSync("NotoSans.ttf") }], engine: "freetype" });
|
|
51
|
+
const layout = layoutText("The quick brown fox", { font: "16px Noto Sans", measurer: createMeasurer(advance), lineHeight: 20, wrapWidth: 80 });
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- The host gives the bytes of each font file. The package has no font file.
|
|
55
|
+
- `fontAdvance` reads the CSS font, and finds the face with the CSS rules of the family, the style and the weight.
|
|
56
|
+
- Each run of the text gets the first family with a glyph for its first character.
|
|
57
|
+
- The width of a run is `measureWidth` of `./fonts`, with the script of the run and the rules of one engine of `engines`.
|
|
58
|
+
- The engine rows are `freetype` (Chromium on Linux), `coretext` (macOS) and `directwrite` (Windows).
|
|
59
|
+
- `readFont` reads TrueType, OpenType and WOFF2 files. A WOFF2 file needs a Brotli decompress function, for example `brotliDecompressSync` of `node:zlib`.
|
|
60
|
+
|
|
23
61
|
The repository [mark1russell7/typeset](https://github.com/mark1russell7/typeset) has the report of the breakers in `docs/BREAKING.md`.
|
package/build/breaking.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as Paragraph, c as WidthOf, d as lineWidth, f as linesOf, i as Line, l as isBreak, n as Glue, o as ParagraphOptions, p as paragraphOf, r as Item, s as Penalty, t as Box, u as lineStart } from "./chunks/paragraph.js";
|
|
2
|
+
import { a as Breaker, c as balancedBreaker, d as knuthPlass, f as totalFit, i as BalancedOptions, l as breakers, n as raggedness, o as TotalFitOptions, r as spread, s as balanced, u as greedy } from "./chunks/breaking.js";
|
|
2
3
|
export { type BalancedOptions, type Box, type Breaker, type Glue, type Item, type Line, type Paragraph, type ParagraphOptions, type Penalty, type TotalFitOptions, type WidthOf, balanced, balancedBreaker, breakers, greedy, isBreak, knuthPlass, lineStart, lineWidth, linesOf, paragraphOf, raggedness, spread, totalFit };
|
|
@@ -1,79 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* The paragraph model of the breakers: a list of boxes, glue and penalties, as Knuth and Plass define it. A builder makes
|
|
3
|
-
* the items of a text. The breakers read only the items, so a new rule of break opportunities is a new builder.
|
|
4
|
-
*/
|
|
5
|
-
/** A width function: the width of a run of text, in any unit. The breakers add the widths and compare them. */
|
|
6
|
-
type WidthOf = (text: string) => number;
|
|
7
|
-
/** A box: text that the breaker does not break. */
|
|
8
|
-
interface Box {
|
|
9
|
-
readonly type: "box";
|
|
10
|
-
readonly text: string;
|
|
11
|
-
readonly width: number;
|
|
12
|
-
}
|
|
13
|
-
/** Glue: a space between two boxes. A line can end at glue that comes after a box. The line then does not show the glue. */
|
|
14
|
-
interface Glue {
|
|
15
|
-
readonly type: "glue";
|
|
16
|
-
readonly text: string;
|
|
17
|
-
readonly width: number;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* A penalty: a break opportunity with a cost. A line that ends at the penalty shows its text, for example a hyphen. A cost of
|
|
21
|
-
* `Infinity` forbids the break, and a cost of `-Infinity` forces it.
|
|
22
|
-
*/
|
|
23
|
-
interface Penalty {
|
|
24
|
-
readonly type: "penalty";
|
|
25
|
-
readonly text: string;
|
|
26
|
-
readonly width: number;
|
|
27
|
-
readonly cost: number;
|
|
28
|
-
/** A flagged penalty is a hyphen. Total fit adds a cost to two flagged breaks in sequence. */
|
|
29
|
-
readonly flagged: boolean;
|
|
30
|
-
}
|
|
31
|
-
/** An item of a paragraph. */
|
|
32
|
-
type Item = Box | Glue | Penalty;
|
|
33
|
-
/** A paragraph: the items in the order of the text. */
|
|
34
|
-
interface Paragraph {
|
|
35
|
-
readonly items: readonly Item[];
|
|
36
|
-
}
|
|
37
|
-
/** The options of `paragraphOf`. */
|
|
38
|
-
interface ParagraphOptions {
|
|
39
|
-
/** The width function of the boxes, the spaces and the hyphens. */
|
|
40
|
-
readonly widthOf: WidthOf;
|
|
41
|
-
/**
|
|
42
|
-
* The hyphenation hook. It gives the offsets in a word where a break with a hyphen is possible. The default gives no
|
|
43
|
-
* offset. The width of each part of a word comes from `widthOf`, so the kerning across an offset is not in the sum.
|
|
44
|
-
*/
|
|
45
|
-
readonly hyphenate?: (word: string) => readonly number[];
|
|
46
|
-
/** The text that a line shows at a hyphen break. The default is "-". */
|
|
47
|
-
readonly hyphen?: string;
|
|
48
|
-
/** The cost of a hyphen break. The default is 50, as in TeX. */
|
|
49
|
-
readonly hyphenCost?: number;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* This function makes the paragraph of a text with the break opportunities of CSS `white-space: normal`. Each run of white
|
|
53
|
-
* space becomes one glue of the width of a space. Each word between two runs becomes a box, or boxes and hyphen penalties.
|
|
54
|
-
*/
|
|
55
|
-
declare function paragraphOf(text: string, options: ParagraphOptions): Paragraph;
|
|
56
|
-
/** A line of a broken paragraph. */
|
|
57
|
-
interface Line {
|
|
58
|
-
readonly text: string;
|
|
59
|
-
/** The width of the line: its boxes, the glue between them and the text of a penalty at its end. */
|
|
60
|
-
readonly width: number;
|
|
61
|
-
/** The index of the first item of the line. */
|
|
62
|
-
readonly start: number;
|
|
63
|
-
/** The index after the last item of the line. A break at glue or at a penalty has the index of that item. */
|
|
64
|
-
readonly end: number;
|
|
65
|
-
}
|
|
66
|
-
/** This function tells if a line can end at the item `index`: glue after a box, or a penalty with a cost below `Infinity`. */
|
|
67
|
-
declare function isBreak(items: readonly Item[], index: number): boolean;
|
|
68
|
-
/** This function gives the index of the first item of a line after a break at `index`. It skips the glue and the penalties. */
|
|
69
|
-
declare function lineStart(items: readonly Item[], index: number): number;
|
|
70
|
-
/** This function gives the width of the line from the item `start` to a break at `end`, with the text of a penalty at `end`. */
|
|
71
|
-
declare function lineWidth(items: readonly Item[], start: number, end: number): number;
|
|
72
|
-
/**
|
|
73
|
-
* This function gives the lines of a paragraph from the indices of its breaks. Each break is the index of glue or of a penalty.
|
|
74
|
-
* The last line ends at the end of the items.
|
|
75
|
-
*/
|
|
76
|
-
declare function linesOf(paragraph: Paragraph, breaks: readonly number[]): Line[];
|
|
1
|
+
import { a as Paragraph, c as WidthOf, d as lineWidth, f as linesOf, i as Line, l as isBreak, n as Glue, o as ParagraphOptions, p as paragraphOf, r as Item, s as Penalty, t as Box, u as lineStart } from "./paragraph.js";
|
|
77
2
|
/**
|
|
78
3
|
* A breaker: a strategy that chooses the breaks of a paragraph for the line width `width`. It gives the indices of the
|
|
79
4
|
* items where the lines end, in order. A breaker reads only the items, so any width function and any builder work with it.
|
|
@@ -126,5 +51,5 @@ declare function spread(lines: readonly Line[]): number;
|
|
|
126
51
|
declare namespace breaking_d_exports {
|
|
127
52
|
export { BalancedOptions, Box, Breaker, Glue, Item, Line, Paragraph, ParagraphOptions, Penalty, TotalFitOptions, WidthOf, balanced, balancedBreaker, breakers, greedy, isBreak, knuthPlass, lineStart, lineWidth, linesOf, paragraphOf, raggedness, spread, totalFit };
|
|
128
53
|
}
|
|
129
|
-
export {
|
|
54
|
+
export { Breaker as a, balancedBreaker as c, knuthPlass as d, totalFit as f, BalancedOptions as i, breakers as l, raggedness as n, TotalFitOptions as o, spread as r, balanced as s, breaking_d_exports as t, greedy as u };
|
|
130
55
|
//# sourceMappingURL=breaking.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breaking.d.ts","names":[],"sources":["../../src/breaking/
|
|
1
|
+
{"version":3,"file":"breaking.d.ts","names":[],"sources":["../../src/breaking/breakers.ts","../../src/breaking/measures.ts","../../src/breaking.ts"],"mappings":";;;;;UAMiB;WACN;EACT,OAAO,WAAW,WAAW;;;;;;cAOlB,QAAQ;;UAsCJ;;WAEN;;WAEA;;;;;;;iBAQK,SAAS,UAAS,kBAAuB;;cAU5C,YAAY;;UAsDR;;WAEN;;;;;;iBAOK,gBAAgB,UAAS,kBAAuB;;cAmBnD,UAAU;;cAGV,UAAU,SAAS,4CAA4C;;;;;iBC1J5D,WAAW,gBAAgB,QAAQ;;iBAWnC,OAAO,gBAAgB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The rules of one text engine for the widths of a font. The fields `deltas` and `metrics` are options of `readFont`, and
|
|
3
|
+
* the fields `rounding` and `sum` are options of `measureWidth`. Thus a caller spreads the same row into the two calls.
|
|
4
|
+
*/
|
|
5
|
+
interface EngineRules {
|
|
6
|
+
/** The rounding of the `HVAR` and `gvar` deltas of an instance. */
|
|
7
|
+
readonly deltas: "round" | "exact";
|
|
8
|
+
/** The advance of a composite glyph: its own advance, or the advance of its component with the flag USE_MY_METRICS. */
|
|
9
|
+
readonly metrics: "own" | "component";
|
|
10
|
+
/** The rounding of each advance: `pixel` rounds it to whole px, and `exact` keeps the fraction. */
|
|
11
|
+
readonly rounding: "exact" | "pixel";
|
|
12
|
+
/**
|
|
13
|
+
* The sum of the advances: `exact`, or `float32` as Blink adds the widths of the words of a canvas in single precision.
|
|
14
|
+
* A sum of whole px is exact in single precision, so the rounding `pixel` needs no `float32` sum.
|
|
15
|
+
*/
|
|
16
|
+
readonly sum: "exact" | "float32";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The rules of the text engines of Chromium, one row for each engine. The fonts runs of typeset#27 measured each row
|
|
20
|
+
* against the canvas, and the T1d diagnosis of the sum measured the field `sum`. A new engine is a new row.
|
|
21
|
+
*/
|
|
22
|
+
declare const engines: {
|
|
23
|
+
readonly freetype: EngineRules;
|
|
24
|
+
readonly coretext: EngineRules;
|
|
25
|
+
readonly directwrite: EngineRules;
|
|
26
|
+
};
|
|
27
|
+
/** The name of a text engine of the table `engines`. */
|
|
28
|
+
type EngineName = keyof typeof engines;
|
|
29
|
+
/** This function tells if a text is the name of an engine of the table `engines`. */
|
|
30
|
+
declare function isEngineName(name: string): name is EngineName;
|
|
31
|
+
export { isEngineName as i, EngineRules as n, engines as r, EngineName as t };
|
|
32
|
+
//# sourceMappingURL=engines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engines.d.ts","names":[],"sources":["../../src/fonts/engines.ts"],"mappings":";;;;UAIiB;;WAEN;;WAEA;;WAEA;;;;;WAKA;;;;;;cAOE;WAAoB,UAAU;WAAsB,UAAU;WAAsB,aAAa;;;KAUlG,0BAA0B;;iBAGtB,aAAa,eAAe,QAAQ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/fonts/engines.ts
|
|
2
|
+
/**
|
|
3
|
+
* The rules of the text engines of Chromium, one row for each engine. The fonts runs of typeset#27 measured each row
|
|
4
|
+
* against the canvas, and the T1d diagnosis of the sum measured the field `sum`. A new engine is a new row.
|
|
5
|
+
*/
|
|
6
|
+
const engines = {
|
|
7
|
+
/** FreeType, as Chromium on Linux uses it: rounded deltas, and each advance in whole px. */
|
|
8
|
+
freetype: {
|
|
9
|
+
deltas: "round",
|
|
10
|
+
metrics: "own",
|
|
11
|
+
rounding: "pixel",
|
|
12
|
+
sum: "exact"
|
|
13
|
+
},
|
|
14
|
+
/** CoreText on macOS: it keeps the fraction of the deltas. */
|
|
15
|
+
coretext: {
|
|
16
|
+
deltas: "exact",
|
|
17
|
+
metrics: "own",
|
|
18
|
+
rounding: "exact",
|
|
19
|
+
sum: "float32"
|
|
20
|
+
},
|
|
21
|
+
/** DirectWrite on Windows: a composite glyph has the advance of its USE_MY_METRICS component. */
|
|
22
|
+
directwrite: {
|
|
23
|
+
deltas: "round",
|
|
24
|
+
metrics: "component",
|
|
25
|
+
rounding: "exact",
|
|
26
|
+
sum: "float32"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/** This function tells if a text is the name of an engine of the table `engines`. */
|
|
30
|
+
function isEngineName(name) {
|
|
31
|
+
return Object.hasOwn(engines, name);
|
|
32
|
+
}
|
|
33
|
+
export { isEngineName as n, engines as t };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=engines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engines.js","names":[],"sources":["../../src/fonts/engines.ts"],"sourcesContent":["/**\n * The rules of one text engine for the widths of a font. The fields `deltas` and `metrics` are options of `readFont`, and\n * the fields `rounding` and `sum` are options of `measureWidth`. Thus a caller spreads the same row into the two calls.\n */\nexport interface EngineRules {\n /** The rounding of the `HVAR` and `gvar` deltas of an instance. */\n readonly deltas: \"round\" | \"exact\";\n /** The advance of a composite glyph: its own advance, or the advance of its component with the flag USE_MY_METRICS. */\n readonly metrics: \"own\" | \"component\";\n /** The rounding of each advance: `pixel` rounds it to whole px, and `exact` keeps the fraction. */\n readonly rounding: \"exact\" | \"pixel\";\n /**\n * The sum of the advances: `exact`, or `float32` as Blink adds the widths of the words of a canvas in single precision.\n * A sum of whole px is exact in single precision, so the rounding `pixel` needs no `float32` sum.\n */\n readonly sum: \"exact\" | \"float32\";\n}\n\n/**\n * The rules of the text engines of Chromium, one row for each engine. The fonts runs of typeset#27 measured each row\n * against the canvas, and the T1d diagnosis of the sum measured the field `sum`. A new engine is a new row.\n */\nexport const engines: { readonly freetype: EngineRules; readonly coretext: EngineRules; readonly directwrite: EngineRules } = {\n /** FreeType, as Chromium on Linux uses it: rounded deltas, and each advance in whole px. */\n freetype: { deltas: \"round\", metrics: \"own\", rounding: \"pixel\", sum: \"exact\" },\n /** CoreText on macOS: it keeps the fraction of the deltas. */\n coretext: { deltas: \"exact\", metrics: \"own\", rounding: \"exact\", sum: \"float32\" },\n /** DirectWrite on Windows: a composite glyph has the advance of its USE_MY_METRICS component. */\n directwrite: { deltas: \"round\", metrics: \"component\", rounding: \"exact\", sum: \"float32\" },\n};\n\n/** The name of a text engine of the table `engines`. */\nexport type EngineName = keyof typeof engines;\n\n/** This function tells if a text is the name of an engine of the table `engines`. */\nexport function isEngineName(name: string): name is EngineName {\n return Object.hasOwn(engines, name);\n}\n"],"mappings":";;;;;AAsBA,MAAa,UAAiH;;CAE5H,UAAU;EAAE,QAAQ;EAAS,SAAS;EAAO,UAAU;EAAS,KAAK;CAAQ;;CAE7E,UAAU;EAAE,QAAQ;EAAS,SAAS;EAAO,UAAU;EAAS,KAAK;CAAU;;CAE/E,aAAa;EAAE,QAAQ;EAAS,SAAS;EAAa,UAAU;EAAS,KAAK;CAAU;AAC1F;;AAMA,SAAgB,aAAa,MAAkC;CAC7D,OAAO,OAAO,OAAO,SAAS,IAAI;AACpC"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { t as Decompress } from "./sfnt.js";
|
|
2
|
+
/**
|
|
3
|
+
* The GSUB features that the default model applies: the features that HarfBuzz and Chromium apply to horizontal text
|
|
4
|
+
* when the page does not change them.
|
|
5
|
+
*/
|
|
6
|
+
declare const defaultFeatures: readonly string[];
|
|
7
|
+
/**
|
|
8
|
+
* The data that a syllabic shaper keeps with each glyph, as the `hb_glyph_info_t` of HarfBuzz keeps it. A substitution
|
|
9
|
+
* gives each new glyph a copy of the data of the glyph that it replaces. A ligature keeps the data of its first glyph.
|
|
10
|
+
*/
|
|
11
|
+
interface GlyphInfo {
|
|
12
|
+
/** The feature mask. A lookup starts only at a glyph with a bit of the mask of the lookup. */
|
|
13
|
+
mask: number;
|
|
14
|
+
/** The syllable byte of HarfBuzz: the serial number in the high 4 bits, and the syllable type in the low 4 bits. */
|
|
15
|
+
syllable: number;
|
|
16
|
+
/** The glyph properties `SUBSTITUTED`, `LIGATED` and `MULTIPLIED`. */
|
|
17
|
+
props: number;
|
|
18
|
+
/** The category of the shaper. */
|
|
19
|
+
category: number;
|
|
20
|
+
/** The position of the shaper. */
|
|
21
|
+
position: number;
|
|
22
|
+
/** The code point of the character of the glyph, after the normalization. */
|
|
23
|
+
readonly codePoint: number;
|
|
24
|
+
}
|
|
25
|
+
/** A lookup of GSUB for one script and one set of features. */
|
|
26
|
+
interface SubstitutionLookup {
|
|
27
|
+
/** The index of the lookup in the lookup list of GSUB. */
|
|
28
|
+
readonly index: number;
|
|
29
|
+
/** The lookup type, from 1 to 8. The type of an Extension lookup is the type of its subtables. */
|
|
30
|
+
readonly type: number;
|
|
31
|
+
/** The lookup flags. */
|
|
32
|
+
readonly flags: number;
|
|
33
|
+
/** The tags of the features that use the lookup. */
|
|
34
|
+
readonly features: readonly string[];
|
|
35
|
+
/**
|
|
36
|
+
* This function applies the lookup to all the glyphs of a text. It changes the array. The array `masks`, when it is
|
|
37
|
+
* given, has one mask for each glyph. Then the lookup starts only at a glyph whose mask has a bit of `mask`, as the
|
|
38
|
+
* feature masks of HarfBuzz do. The function keeps `masks` in step with the glyphs.
|
|
39
|
+
*/
|
|
40
|
+
apply(glyphs: number[], masks?: number[], mask?: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* This function applies the lookup with the data `infos` of the glyphs, as HarfBuzz applies a lookup of a syllabic shaper.
|
|
43
|
+
* The lookup starts at a glyph with a bit of `mask`, and each input glyph after it also needs a bit of `mask`. When
|
|
44
|
+
* `perSyllable` is true, all the matched glyphs have the syllable of the first glyph. The function keeps `infos` in step.
|
|
45
|
+
*/
|
|
46
|
+
applyInfos(glyphs: number[], infos: GlyphInfo[], mask: number, perSyllable: boolean): void;
|
|
47
|
+
/**
|
|
48
|
+
* This function tells if the lookup changes the glyph sequence `glyphs` when the sequence is all the text, as
|
|
49
|
+
* `hb_ot_layout_lookup_would_substitute` with zero context tells it. A context rule with backtrack or lookahead does not apply.
|
|
50
|
+
*/
|
|
51
|
+
wouldApply(glyphs: readonly number[]): boolean;
|
|
52
|
+
}
|
|
53
|
+
/** One axis of `fvar`, in the user units of the axis. */
|
|
54
|
+
interface Axis {
|
|
55
|
+
readonly tag: string;
|
|
56
|
+
readonly min: number;
|
|
57
|
+
readonly default: number;
|
|
58
|
+
readonly max: number;
|
|
59
|
+
}
|
|
60
|
+
/** The coordinates of an instance in user units, by axis tag. An axis that is absent has its default value. */
|
|
61
|
+
type Instance = Readonly<Record<string, number>>;
|
|
62
|
+
/** The change of the advances of two glyphs, in font units. A variable font can give a value that is not a whole number. */
|
|
63
|
+
interface PairValue {
|
|
64
|
+
readonly first: number;
|
|
65
|
+
readonly second: number;
|
|
66
|
+
/** The part of `first` that comes from a VariationIndex table. HarfBuzz scales this part and the rest in different ways. */
|
|
67
|
+
readonly firstDelta?: number;
|
|
68
|
+
/** The part of `second` that comes from a VariationIndex table. */
|
|
69
|
+
readonly secondDelta?: number;
|
|
70
|
+
/** It is true when the subtable has a value for the second glyph. Then the next pair starts after the second glyph. */
|
|
71
|
+
readonly skipSecond: boolean;
|
|
72
|
+
}
|
|
73
|
+
/** A lookup of pair adjustments, with the flags that tell which glyphs it skips. */
|
|
74
|
+
interface PairLookup {
|
|
75
|
+
readonly flags: number;
|
|
76
|
+
/**
|
|
77
|
+
* This function tells if the lookup skips a glyph, when the lookup uses a mark filtering set. Then the lookup skips each
|
|
78
|
+
* mark that is not in the set. Without the function, the flags alone tell which glyphs the lookup skips.
|
|
79
|
+
*/
|
|
80
|
+
readonly skip?: (glyph: number) => boolean;
|
|
81
|
+
/** This function gives the value for a pair, or `undefined` when no subtable applies. */
|
|
82
|
+
pair(first: number, second: number): PairValue | undefined;
|
|
83
|
+
}
|
|
84
|
+
/** The options of `readFont`. */
|
|
85
|
+
interface ReadOptions {
|
|
86
|
+
/** The Brotli decompress function. A WOFF2 file needs it. */
|
|
87
|
+
readonly decompress?: Decompress;
|
|
88
|
+
/**
|
|
89
|
+
* The instance of a variable font, in the user units of its axes, for example `{ wght: 400 }`. An absent axis has its
|
|
90
|
+
* default value. A browser uses the CSS weight, so a page with the weight `normal` needs `{ wght: 400 }`.
|
|
91
|
+
*/
|
|
92
|
+
readonly instance?: Instance;
|
|
93
|
+
/**
|
|
94
|
+
* The rounding of the `HVAR` deltas. `round` (the default) rounds each delta to whole font units, as FreeType does.
|
|
95
|
+
* `exact` keeps the fraction. The epoch tells the two modes apart.
|
|
96
|
+
*/
|
|
97
|
+
readonly deltas?: "round" | "exact";
|
|
98
|
+
/**
|
|
99
|
+
* The source of the advances of an instance. `auto` (the default) uses `HVAR` when the font has it, else the phantom
|
|
100
|
+
* points of `gvar`. `gvar` uses the phantom points also when the font has `HVAR`. The epoch tells the two modes apart.
|
|
101
|
+
*/
|
|
102
|
+
readonly advances?: "auto" | "gvar";
|
|
103
|
+
/**
|
|
104
|
+
* The advance of a composite glyph. `own` (the default) uses the advance of the glyph, as FreeType and CoreText do.
|
|
105
|
+
* `component` uses the advance of its component with the flag USE_MY_METRICS, as DirectWrite does.
|
|
106
|
+
*/
|
|
107
|
+
readonly metrics?: "own" | "component";
|
|
108
|
+
}
|
|
109
|
+
/** The source of the advances of an instance: the default advances of `hmtx`, the deltas of `HVAR`, or the phantom points of `gvar`. */
|
|
110
|
+
type AdvanceSource = "hmtx" | "HVAR" | "gvar";
|
|
111
|
+
/** The measured tables of one font file. */
|
|
112
|
+
interface Font {
|
|
113
|
+
/**
|
|
114
|
+
* The font epoch: the revision of `head` and an FNV-1a hash of the data that gives the widths. A cache of widths can use
|
|
115
|
+
* it as a key. The TrueType file and the WOFF2 file of one font give the same epoch.
|
|
116
|
+
*/
|
|
117
|
+
readonly epoch: string;
|
|
118
|
+
readonly unitsPerEm: number;
|
|
119
|
+
/** The axes of `fvar`. A font that is not variable has no axes. */
|
|
120
|
+
readonly axes: readonly Axis[];
|
|
121
|
+
/** The instance of the font: the value of each axis in user units, after the clamp to the range of the axis. */
|
|
122
|
+
readonly instance: Instance;
|
|
123
|
+
/** The normalized coordinates of the instance, one for each axis, after `avar`. */
|
|
124
|
+
readonly coordinates: readonly number[];
|
|
125
|
+
/** The source of the advances of this instance. The default instance and a font that is not variable use `hmtx`. */
|
|
126
|
+
readonly advanceSource: AdvanceSource;
|
|
127
|
+
readonly numGlyphs: number;
|
|
128
|
+
/** This function gives the glyph of a code point, or 0 when the font has no glyph for it. */
|
|
129
|
+
glyph(codePoint: number): number;
|
|
130
|
+
/** This function gives the advance of a glyph in font units, as the shaper uses it. A mark has the advance 0. */
|
|
131
|
+
advance(glyph: number): number;
|
|
132
|
+
/** This function gives the GDEF class of a glyph: 1 base, 2 ligature, 3 mark, 4 component, 0 none. */
|
|
133
|
+
glyphClass(glyph: number): number;
|
|
134
|
+
/** This function gives the pair lookups of the kerning for an OpenType script tag, for example `latn`. */
|
|
135
|
+
kerning(script: string): readonly PairLookup[];
|
|
136
|
+
/** This function gives the GSUB lookups of a list of feature tags for an OpenType script tag, in the order of the lookup list. */
|
|
137
|
+
substitutions(script: string, features: readonly string[]): readonly SubstitutionLookup[];
|
|
138
|
+
/** This function gives the same font at another instance. It uses the tables that are already read. */
|
|
139
|
+
at(instance: Instance): Font;
|
|
140
|
+
}
|
|
141
|
+
/** This function reads a TrueType, OpenType or WOFF2 file. */
|
|
142
|
+
declare function readFont(bytes: Uint8Array, options?: ReadOptions): Font;
|
|
143
|
+
/** The options of `measureWidth`. */
|
|
144
|
+
interface MeasureOptions {
|
|
145
|
+
/** The OpenType script tag of the text, for example `latn` or `cyrl`. The default is `DFLT`. */
|
|
146
|
+
readonly script?: string;
|
|
147
|
+
/**
|
|
148
|
+
* The rounding of the width. `exact` (the default) adds the advances with no rounding. `pixel` rounds each advance to
|
|
149
|
+
* 1/64 px and then to a whole px, and each kerning value to a whole px. Chromium on Linux does this at the device scale 1.
|
|
150
|
+
*/
|
|
151
|
+
readonly rounding?: "exact" | "pixel";
|
|
152
|
+
/** The pair kerning. When it is `false`, the width is the sum of the advances only. The default is `true`. */
|
|
153
|
+
readonly kerning?: boolean;
|
|
154
|
+
/**
|
|
155
|
+
* The GSUB features to apply before the kerning. The default is `defaultFeatures`: the features that a browser applies
|
|
156
|
+
* when the page does not change them. An empty list applies no feature of the list. The joining forms are not in the
|
|
157
|
+
* list. The option `joining` controls them.
|
|
158
|
+
*/
|
|
159
|
+
readonly features?: readonly string[];
|
|
160
|
+
/**
|
|
161
|
+
* The joining of the Arabic shaper of HarfBuzz. When it is `true` (the default), the scripts of `joiningScripts` get the
|
|
162
|
+
* joining forms, for example `init` and `fina`. Their features then go in the stages of `joiningStages`. The other
|
|
163
|
+
* scripts do not change. When it is `false`, all the scripts use the one stage of the other scripts.
|
|
164
|
+
*/
|
|
165
|
+
readonly joining?: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* The Indic shaper of HarfBuzz. When it is `true` (the default), the scripts of `indicScripts` get the syllables, the
|
|
168
|
+
* reordering and the stages of `indicShaper`. When it is `false`, they use the one stage of the other scripts.
|
|
169
|
+
*/
|
|
170
|
+
readonly indic?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* The shaping of the browser to model. `dom` (the default) shapes the words of `shapingWords` and then kerns all the
|
|
173
|
+
* text. `canvas` shapes and kerns each word of `canvasWords` alone, as Blink does for the text of a canvas.
|
|
174
|
+
*/
|
|
175
|
+
readonly shaping?: "dom" | "canvas";
|
|
176
|
+
/**
|
|
177
|
+
* The sum of the advances. `exact` (the default) adds them with no rounding. `float32` models the canvas of Blink with
|
|
178
|
+
* CoreText and DirectWrite. Then the option `shaping` has no effect. The rounding `pixel` ignores this option.
|
|
179
|
+
*/
|
|
180
|
+
readonly sum?: "exact" | "float32";
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* This function divides a text into the words that the GSUB pass shapes one at a time. Each space and each tab is a word
|
|
184
|
+
* alone. Blink shapes the text of a canvas in the same words, so no GSUB context goes across a space.
|
|
185
|
+
*/
|
|
186
|
+
declare function shapingWords(text: string): string[];
|
|
187
|
+
/**
|
|
188
|
+
* This function gives the glyphs of a text and their advances in font units. With the shaping `dom`, it applies the GSUB
|
|
189
|
+
* substitutions to each word of `shapingWords`, and then the pair kerning to all the text. With the shaping `canvas`, it
|
|
190
|
+
* applies the substitutions and the kerning to each word of `canvasWords` alone. A script of `joiningScripts` also gets
|
|
191
|
+
* the joining forms of each word, in the stages of `joiningStages`. A script of `indicScripts` uses `indicShaper`.
|
|
192
|
+
*/
|
|
193
|
+
declare function glyphAdvances(font: Font, text: string, options?: MeasureOptions): {
|
|
194
|
+
glyphs: number[];
|
|
195
|
+
advances: number[];
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* This function gives the width of a text in px at the size `size` in px. The width is the sum of the advances after the
|
|
199
|
+
* GSUB substitutions and the pair kerning.
|
|
200
|
+
*/
|
|
201
|
+
declare function measureWidth(font: Font, text: string, size: number, options?: MeasureOptions): number;
|
|
202
|
+
export { measureWidth as a, Axis as c, glyphAdvances as i, Instance as l, MeasureOptions as n, readFont as o, ReadOptions as r, shapingWords as s, Font as t, defaultFeatures as u };
|
|
203
|
+
//# sourceMappingURL=font.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font.d.ts","names":[],"sources":["../../src/fonts/substitution.ts","../../src/fonts/variations.ts","../../src/fonts/kerning.ts","../../src/fonts/font.ts"],"mappings":";;;;;cAQa;;;;;UA6CI;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;WAES;;;UAIM;;WAEN;;WAEA;;WAEA;;WAEA;;;;;;EAMT,MAAM,kBAAkB,kBAAkB;;;;;;EAM1C,WAAW,kBAAkB,OAAO,aAAa,cAAc;;;;;EAK/D,WAAW;;;UC3FI;WACN;WACA;WACA;WACA;;;KAIC,WAAW,SAAS;;UCLf;WACN;WACA;;WAEA;;WAEA;;WAEA;;;UAIM;WACN;;;;;WAKA,QAAQ;;EAEjB,KAAK,eAAe,iBAAiB;;;UCbtB;;WAEN,aAAa;;;;;WAKb,WAAW;;;;;WAKX;;;;;WAKA;;;;;WAKA;;;KAIC;;UAGK;;;;;WAKN;WACA;;WAEA,eAAe;;WAEf,UAAU;;WAEV;;WAEA,eAAe;WACf;;EAET,MAAM;;EAEN,QAAQ;;EAER,WAAW;;EAEX,QAAQ,0BAA0B;;EAElC,cAAc,gBAAgB,uCAAuC;;EAErE,GAAG,UAAU,WAAW;;;iBAIV,SAAS,OAAO,YAAY,UAAS,cAAmB;;UA8JvD;;WAEN;;;;;WAKA;;WAEA;;;;;;WAMA;;;;;;WAMA;;;;;WAKA;;;;;WAKA;;;;;WAKA;;;;;;iBAYK,aAAa;;;;;;;iBAgDb,cAAc,MAAM,MAAM,cAAc,UAAS;EAAwB;EAAkB;;;;;;iBAkG3F,aAAa,MAAM,MAAM,cAAc,cAAc,UAAS"}
|