pretrunc 0.0.0-stage → 0.1.0
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/CHANGELOG.md +7 -0
- package/DESIGN.md +235 -0
- package/LICENSE +21 -0
- package/README.md +200 -2
- package/dist/cut-D7qi2yZl.js +356 -0
- package/dist/cut-D7qi2yZl.js.map +1 -0
- package/dist/cut.d.ts +75 -0
- package/dist/dom-CPL0-qc3.js +52 -0
- package/dist/dom-CPL0-qc3.js.map +1 -0
- package/dist/dom.d.ts +22 -0
- package/dist/dom.js +1 -0
- package/dist/face-pICHAjvk.js +68 -0
- package/dist/face-pICHAjvk.js.map +1 -0
- package/dist/face.d.ts +46 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/lines-DOj2DQLl.js +334 -0
- package/dist/lines-DOj2DQLl.js.map +1 -0
- package/dist/lines.d.ts +32 -0
- package/dist/lines.js +1 -0
- package/dist/metrics-C2jv4JVL.js +49 -0
- package/dist/metrics-C2jv4JVL.js.map +1 -0
- package/dist/metrics-cli.js +19 -0
- package/dist/metrics-cli.js.map +1 -0
- package/dist/metrics.d.ts +36 -0
- package/dist/metrics.js +73 -0
- package/dist/metrics.js.map +1 -0
- package/dist/react-CnQfjWyS.js +156 -0
- package/dist/react-CnQfjWyS.js.map +1 -0
- package/dist/react-lines.d.ts +27 -0
- package/dist/react-lines.js +74 -0
- package/dist/react-lines.js.map +1 -0
- package/dist/react.d.ts +81 -0
- package/dist/react.js +1 -0
- package/dist/solid-BWC32VMg.js +155 -0
- package/dist/solid-BWC32VMg.js.map +1 -0
- package/dist/solid-lines.d.ts +27 -0
- package/dist/solid-lines.js +90 -0
- package/dist/solid-lines.js.map +1 -0
- package/dist/solid.d.ts +77 -0
- package/dist/solid.js +1 -0
- package/package.json +145 -3
- package/src/cut.ts +596 -0
- package/src/dom.ts +59 -0
- package/src/face.ts +112 -0
- package/src/index.ts +15 -0
- package/src/lines.ts +585 -0
- package/src/metrics.ts +106 -0
- package/src/react-lines.ts +99 -0
- package/src/react.ts +251 -0
- package/src/solid-lines.tsx +89 -0
- package/src/solid.tsx +225 -0
package/src/face.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
declare const opaque: unique symbol;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Measures text in one font: `canvasFace`, `tableFace` from a metrics table, or
|
|
5
|
+
* `face` over your own measure function. Its caches are pretrunc's, so the type shows
|
|
6
|
+
* none of them.
|
|
7
|
+
*/
|
|
8
|
+
export interface Face {
|
|
9
|
+
readonly [opaque]: true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** A face's measure function and caches, for pretrunc's own modules. */
|
|
13
|
+
export interface FaceData extends Face {
|
|
14
|
+
/** The width of a string in px, as one run of text. */
|
|
15
|
+
readonly m: (text: string) => number;
|
|
16
|
+
/** Widths already measured, by text: graphemes, grapheme pairs, words and ellipses. */
|
|
17
|
+
readonly c: Map<string, number>;
|
|
18
|
+
/** Widths of single characters below U+0300 by code, NaN until measured. */
|
|
19
|
+
readonly u: Float64Array;
|
|
20
|
+
/** Widths of pairs of characters below U+0300, by `first * 768 + second`. */
|
|
21
|
+
readonly p: Map<number, number>;
|
|
22
|
+
/** Widths of pairs of ASCII characters, by `first * 128 + second`, NaN until measured. */
|
|
23
|
+
readonly q: Float64Array;
|
|
24
|
+
/**
|
|
25
|
+
* Kerning beside each ellipsis, by ellipsis: `[code]` between a character below U+0300
|
|
26
|
+
* and the ellipsis after it, `[768 + code]` between the ellipsis and the character.
|
|
27
|
+
* Shared by every text in the face. NaN until measured.
|
|
28
|
+
*/
|
|
29
|
+
readonly e: Map<string, Float64Array>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const faceOver = (measure: (text: string) => number) =>
|
|
33
|
+
({
|
|
34
|
+
m: measure,
|
|
35
|
+
c: new Map(),
|
|
36
|
+
u: new Float64Array(768).fill(Number.NaN),
|
|
37
|
+
p: new Map(),
|
|
38
|
+
q: new Float64Array(16384).fill(Number.NaN),
|
|
39
|
+
e: new Map(),
|
|
40
|
+
}) as FaceData;
|
|
41
|
+
|
|
42
|
+
/** A face over your own measure function: node-canvas, a test double. */
|
|
43
|
+
export const face: (measure: (text: string) => number) => Face = faceOver;
|
|
44
|
+
|
|
45
|
+
let context: OffscreenCanvasRenderingContext2D | undefined;
|
|
46
|
+
// Setting `font` parses it every time, and reading it back gives a normalised string
|
|
47
|
+
// that differs from what was set, so the last font set is kept here instead.
|
|
48
|
+
let current = "";
|
|
49
|
+
const faces = new Map<string, FaceData>();
|
|
50
|
+
|
|
51
|
+
/** The canvas face for a CSS font shorthand, for pretrunc's own modules. */
|
|
52
|
+
export const faceOf = (font: string): FaceData => {
|
|
53
|
+
let f = faces.get(font);
|
|
54
|
+
if (!f) {
|
|
55
|
+
f = faceOver((text) => {
|
|
56
|
+
context ??= new OffscreenCanvas(0, 0).getContext("2d")!;
|
|
57
|
+
if (current !== font) context.font = current = font;
|
|
58
|
+
return context.measureText(text).width;
|
|
59
|
+
});
|
|
60
|
+
faces.set(font, f);
|
|
61
|
+
}
|
|
62
|
+
return f;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** The canvas face for a CSS font shorthand, shared by everything in that font. */
|
|
66
|
+
export const canvasFace: (font: string) => Face = faceOf;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Drops the canvas face for `font`, or every one, and with `pretrunc/lines` loaded
|
|
70
|
+
* every width pretext keeps, so text prepared afterwards is measured again. Call it
|
|
71
|
+
* once a web font loads: widths measured before are the fallback font's.
|
|
72
|
+
*/
|
|
73
|
+
export const forget = (font?: string): void => {
|
|
74
|
+
if (font === undefined) faces.clear();
|
|
75
|
+
else faces.delete(font);
|
|
76
|
+
for (const clear of clears) clear();
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Caches beyond the core's that hold widths too: pretext's, which `pretrunc/lines`
|
|
80
|
+
// registers so the core never imports pretext. pretext can't drop one font's widths,
|
|
81
|
+
// so a `forget` of one font drops all of its.
|
|
82
|
+
const clears: Array<() => void> = [];
|
|
83
|
+
export const alsoForget = (clear: () => void): void => void clears.push(clear);
|
|
84
|
+
|
|
85
|
+
/** The width of `text` in `f`, measured once. */
|
|
86
|
+
export const widthOf = (f: FaceData, text: string): number => {
|
|
87
|
+
let w = f.c.get(text);
|
|
88
|
+
if (w === undefined) f.c.set(text, (w = f.m(text)));
|
|
89
|
+
return w;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Most text is in characters below U+0300, one UTF-16 unit each, so their widths are
|
|
93
|
+
// found by code: no string is built unless one has to be measured.
|
|
94
|
+
export const unitOf = (f: FaceData, code: number): number => {
|
|
95
|
+
let w = f.u[code]!;
|
|
96
|
+
// NaN, not yet measured.
|
|
97
|
+
if (w !== w) f.u[code] = w = f.m(String.fromCharCode(code));
|
|
98
|
+
return w;
|
|
99
|
+
};
|
|
100
|
+
export const pairOf = (f: FaceData, first: number, second: number): number => {
|
|
101
|
+
// ASCII pairs, most of most text, come from a flat table, the rest from a map.
|
|
102
|
+
if (first < 128 && second < 128) {
|
|
103
|
+
const key = first * 128 + second;
|
|
104
|
+
let w = f.q[key]!;
|
|
105
|
+
if (w !== w) f.q[key] = w = f.m(String.fromCharCode(first, second));
|
|
106
|
+
return w;
|
|
107
|
+
}
|
|
108
|
+
const key = first * 768 + second;
|
|
109
|
+
let w = f.p.get(key);
|
|
110
|
+
if (w === undefined) f.p.set(key, (w = f.m(String.fromCharCode(first, second))));
|
|
111
|
+
return w;
|
|
112
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { type Face, canvasFace, face, forget } from "./face.ts";
|
|
2
|
+
export {
|
|
3
|
+
type Cut,
|
|
4
|
+
type CutOptions,
|
|
5
|
+
type Prepared,
|
|
6
|
+
type PrepareOptions,
|
|
7
|
+
type Protect,
|
|
8
|
+
type Protection,
|
|
9
|
+
cut,
|
|
10
|
+
head,
|
|
11
|
+
prepare,
|
|
12
|
+
tail,
|
|
13
|
+
toText,
|
|
14
|
+
truncated,
|
|
15
|
+
} from "./cut.ts";
|