postext-pdf 1.14.1 → 1.15.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/README.md +13 -1
- package/dist/__bench__/arabicShaping.bench.test.d.ts +2 -0
- package/dist/__bench__/arabicShaping.bench.test.d.ts.map +1 -0
- package/dist/__bench__/arabicShaping.bench.test.js +53 -0
- package/dist/__bench__/arabicShaping.bench.test.js.map +1 -0
- package/dist/__tests__/arabicShaping.test.d.ts +2 -0
- package/dist/__tests__/arabicShaping.test.d.ts.map +1 -0
- package/dist/__tests__/arabicShaping.test.js +261 -0
- package/dist/__tests__/arabicShaping.test.js.map +1 -0
- package/dist/__tests__/complexShaping.test.d.ts +2 -0
- package/dist/__tests__/complexShaping.test.d.ts.map +1 -0
- package/dist/__tests__/complexShaping.test.js +145 -0
- package/dist/__tests__/complexShaping.test.js.map +1 -0
- package/dist/__tests__/designTextRtl.test.d.ts +2 -0
- package/dist/__tests__/designTextRtl.test.d.ts.map +1 -0
- package/dist/__tests__/designTextRtl.test.js +136 -0
- package/dist/__tests__/designTextRtl.test.js.map +1 -0
- package/dist/__tests__/harfbuzz.test.d.ts +2 -0
- package/dist/__tests__/harfbuzz.test.d.ts.map +1 -0
- package/dist/__tests__/harfbuzz.test.js +103 -0
- package/dist/__tests__/harfbuzz.test.js.map +1 -0
- package/dist/__tests__/measuredLines.test.js +13 -5
- package/dist/__tests__/measuredLines.test.js.map +1 -1
- package/dist/__tests__/mirroredPdf.test.d.ts +2 -0
- package/dist/__tests__/mirroredPdf.test.d.ts.map +1 -0
- package/dist/__tests__/mirroredPdf.test.js +104 -0
- package/dist/__tests__/mirroredPdf.test.js.map +1 -0
- package/dist/__tests__/rtlPdf.test.d.ts +2 -0
- package/dist/__tests__/rtlPdf.test.d.ts.map +1 -0
- package/dist/__tests__/rtlPdf.test.js +312 -0
- package/dist/__tests__/rtlPdf.test.js.map +1 -0
- package/dist/__tests__/verticalText.test.js +4 -4
- package/dist/__tests__/verticalText.test.js.map +1 -1
- package/dist/complexShaping.d.ts +113 -0
- package/dist/complexShaping.d.ts.map +1 -0
- package/dist/complexShaping.js +188 -0
- package/dist/complexShaping.js.map +1 -0
- package/dist/faceFiles.d.ts +9 -1
- package/dist/faceFiles.d.ts.map +1 -1
- package/dist/faceFiles.js +47 -5
- package/dist/faceFiles.js.map +1 -1
- package/dist/harfbuzz.d.ts +119 -0
- package/dist/harfbuzz.d.ts.map +1 -0
- package/dist/harfbuzz.js +280 -0
- package/dist/harfbuzz.js.map +1 -0
- package/dist/harfbuzz.wasm +0 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pdf-backend/blockRender.d.ts.map +1 -1
- package/dist/pdf-backend/blockRender.js +113 -40
- package/dist/pdf-backend/blockRender.js.map +1 -1
- package/dist/pdf-backend/chip.d.ts.map +1 -1
- package/dist/pdf-backend/chip.js +11 -2
- package/dist/pdf-backend/chip.js.map +1 -1
- package/dist/pdf-backend/directedLine.d.ts +38 -0
- package/dist/pdf-backend/directedLine.d.ts.map +1 -0
- package/dist/pdf-backend/directedLine.js +103 -0
- package/dist/pdf-backend/directedLine.js.map +1 -0
- package/dist/pdf-backend/fontHelpers.d.ts.map +1 -1
- package/dist/pdf-backend/fontHelpers.js +6 -0
- package/dist/pdf-backend/fontHelpers.js.map +1 -1
- package/dist/pdf-backend/headerFooter.d.ts.map +1 -1
- package/dist/pdf-backend/headerFooter.js +11 -3
- package/dist/pdf-backend/headerFooter.js.map +1 -1
- package/dist/pdf-backend/index.d.ts +32 -3
- package/dist/pdf-backend/index.d.ts.map +1 -1
- package/dist/pdf-backend/index.js +40 -6
- package/dist/pdf-backend/index.js.map +1 -1
- package/dist/pdf-backend/links.d.ts +7 -2
- package/dist/pdf-backend/links.d.ts.map +1 -1
- package/dist/pdf-backend/links.js +9 -3
- package/dist/pdf-backend/links.js.map +1 -1
- package/dist/pdf-backend/outlines.js +2 -2
- package/dist/pdf-backend/outlines.js.map +1 -1
- package/dist/pdf-backend/primitives.d.ts +46 -2
- package/dist/pdf-backend/primitives.d.ts.map +1 -1
- package/dist/pdf-backend/primitives.js +67 -5
- package/dist/pdf-backend/primitives.js.map +1 -1
- package/dist/pdf-backend/renderResourceBlock.d.ts.map +1 -1
- package/dist/pdf-backend/renderResourceBlock.js +48 -14
- package/dist/pdf-backend/renderResourceBlock.js.map +1 -1
- package/dist/pdf-backend/rtlRun.d.ts +12 -0
- package/dist/pdf-backend/rtlRun.d.ts.map +1 -0
- package/dist/pdf-backend/rtlRun.js +31 -0
- package/dist/pdf-backend/rtlRun.js.map +1 -0
- package/dist/pdf-backend/shapedText.d.ts +122 -0
- package/dist/pdf-backend/shapedText.d.ts.map +1 -0
- package/dist/pdf-backend/shapedText.js +635 -0
- package/dist/pdf-backend/shapedText.js.map +1 -0
- package/dist/pdf-backend/svgVector.d.ts +9 -2
- package/dist/pdf-backend/svgVector.d.ts.map +1 -1
- package/dist/pdf-backend/svgVector.js +42 -18
- package/dist/pdf-backend/svgVector.js.map +1 -1
- package/dist/worker/client.d.ts.map +1 -1
- package/dist/worker/client.js +10 -1
- package/dist/worker/client.js.map +1 -1
- package/dist/worker/protocol.d.ts +5 -1
- package/dist/worker/protocol.d.ts.map +1 -1
- package/package.json +6 -5
package/dist/harfbuzz.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HarfBuzz from its WebAssembly binary, without the Emscripten glue
|
|
3
|
+
* (issue #380).
|
|
4
|
+
*
|
|
5
|
+
* harfbuzzjs ships `harfbuzz.wasm` with a JavaScript module that loads it,
|
|
6
|
+
* and that module works out where it runs from `process`: in Node it
|
|
7
|
+
* imports `module` to read the file. A CDN that compiles packages for the
|
|
8
|
+
* browser (esm.sh) defines a `process` of its own, so in a page that
|
|
9
|
+
* imports postext-pdf from it the glue took the Node path and threw, and
|
|
10
|
+
* every Arabic PDF fell back to fontkit, its marks unplaced.
|
|
11
|
+
*
|
|
12
|
+
* The binary needs very little from its host: five imports (a heap that
|
|
13
|
+
* grows, an abort, a timer and an exit Emscripten never calls for
|
|
14
|
+
* shaping), and the static constructors run once. This module provides
|
|
15
|
+
* them and binds the dozen `hb_*` functions postext-pdf shapes with, so
|
|
16
|
+
* HarfBuzz loads the same way in Node, a page, a Worker and a bundle.
|
|
17
|
+
*
|
|
18
|
+
* The binary is taken from, in order: the source the caller gave
|
|
19
|
+
* (`RenderToPdfOptions.harfbuzzWasm`); `harfbuzz.wasm` beside this module
|
|
20
|
+
* (the build copies it into `dist`; a bundler sees the literal
|
|
21
|
+
* `new URL(…, import.meta.url)` and emits it as an asset; Node reads the
|
|
22
|
+
* file); in the source tree, the harfbuzzjs package itself; and, for a
|
|
23
|
+
* page whose CDN rebuilt the module somewhere else (esm.sh puts it under
|
|
24
|
+
* `/es2022/`, where no `.wasm` sits beside it), the same harfbuzzjs
|
|
25
|
+
* release from jsDelivr, then from esm.sh.
|
|
26
|
+
*/
|
|
27
|
+
/** The harfbuzzjs release whose `harfbuzz.wasm` this binding is written
|
|
28
|
+
* for, and fetched from a CDN when no copy sits beside the module. A test
|
|
29
|
+
* keeps it equal to the installed package. */
|
|
30
|
+
export const HARFBUZZ_VERSION = '1.6.2';
|
|
31
|
+
// hb-common.h, hb-buffer.h, hb-blob.h.
|
|
32
|
+
const HB_DIRECTION_LTR = 4;
|
|
33
|
+
const HB_DIRECTION_RTL = 5;
|
|
34
|
+
const HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0;
|
|
35
|
+
const HB_MEMORY_MODE_READONLY = 1;
|
|
36
|
+
/** `hb_feature_t`: tag, value, start, end, four `uint32`. */
|
|
37
|
+
const FEATURE_BYTES = 16;
|
|
38
|
+
const FEATURE_GLOBAL_END = 0xffffffff;
|
|
39
|
+
/** `hb_glyph_info_t` and `hb_glyph_position_t` are five 32-bit words each. */
|
|
40
|
+
const GLYPH_WORDS = 5;
|
|
41
|
+
/** The heap's ceiling, as Emscripten built it (`getHeapMax`). */
|
|
42
|
+
const HEAP_MAX = 2 ** 31;
|
|
43
|
+
const WASM_PAGE = 65536;
|
|
44
|
+
function hbTag(tag) {
|
|
45
|
+
return ((tag.charCodeAt(0) & 0xff) << 24 | (tag.charCodeAt(1) & 0xff) << 16 | (tag.charCodeAt(2) & 0xff) << 8 | (tag.charCodeAt(3) & 0xff)) >>> 0;
|
|
46
|
+
}
|
|
47
|
+
/** A running HarfBuzz: one WebAssembly instance and one shaping buffer. */
|
|
48
|
+
export class HarfBuzz {
|
|
49
|
+
hb;
|
|
50
|
+
buffer;
|
|
51
|
+
/** Frees a face's memory once the font file it was made from is
|
|
52
|
+
* collected (the caller keys faces by the file's bytes). */
|
|
53
|
+
faces = new FinalizationRegistry((f) => {
|
|
54
|
+
this.hb.hb_font_destroy(f.font);
|
|
55
|
+
this.hb.hb_face_destroy(f.face);
|
|
56
|
+
this.hb.free(f.data);
|
|
57
|
+
});
|
|
58
|
+
constructor(hb) {
|
|
59
|
+
this.hb = hb;
|
|
60
|
+
this.buffer = hb.hb_buffer_create();
|
|
61
|
+
}
|
|
62
|
+
/** The heap as bytes. A fresh view each time: growing the memory
|
|
63
|
+
* detaches the old one. */
|
|
64
|
+
get u8() {
|
|
65
|
+
return new Uint8Array(this.hb.memory.buffer);
|
|
66
|
+
}
|
|
67
|
+
/** Copy `str` (ASCII: a script or language tag) into the heap, NUL
|
|
68
|
+
* terminated; the caller frees it. */
|
|
69
|
+
ascii(str) {
|
|
70
|
+
const ptr = this.hb.malloc(str.length + 1);
|
|
71
|
+
const u8 = this.u8;
|
|
72
|
+
for (let i = 0; i < str.length; i++)
|
|
73
|
+
u8[ptr + i] = str.charCodeAt(i) & 0x7f;
|
|
74
|
+
u8[ptr + str.length] = 0;
|
|
75
|
+
return ptr;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A face for the font file `bytes` (its first face). The bytes are
|
|
79
|
+
* copied into the heap and freed, with the face, when `owner` (the
|
|
80
|
+
* caller's handle for this face) is collected.
|
|
81
|
+
*/
|
|
82
|
+
openFont(bytes, owner) {
|
|
83
|
+
const hb = this.hb;
|
|
84
|
+
const data = hb.malloc(bytes.byteLength);
|
|
85
|
+
this.u8.set(bytes, data);
|
|
86
|
+
// Read-only: HarfBuzz copies a table it must patch, and never frees
|
|
87
|
+
// the data (no destroy callback); the registry does.
|
|
88
|
+
const blob = hb.hb_blob_create(data, bytes.byteLength, HB_MEMORY_MODE_READONLY, 0, 0);
|
|
89
|
+
const face = hb.hb_face_create(blob, 0);
|
|
90
|
+
hb.hb_blob_destroy(blob);
|
|
91
|
+
const font = hb.hb_font_create(face);
|
|
92
|
+
const handle = { font, upem: hb.hb_face_get_upem(face) };
|
|
93
|
+
this.faces.register(owner, { data, face, font });
|
|
94
|
+
return handle;
|
|
95
|
+
}
|
|
96
|
+
/** Shape `text` (one bidi run) with `font`. Glyphs in visual order;
|
|
97
|
+
* clusters are UTF-16 offsets, a letter and its marks one cluster. */
|
|
98
|
+
shape(font, text, request) {
|
|
99
|
+
const hb = this.hb;
|
|
100
|
+
const buf = this.buffer;
|
|
101
|
+
hb.hb_buffer_reset(buf);
|
|
102
|
+
hb.hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES);
|
|
103
|
+
const textPtr = hb.malloc(text.length * 2 || 2);
|
|
104
|
+
const u16 = new Uint16Array(hb.memory.buffer, textPtr, text.length);
|
|
105
|
+
for (let i = 0; i < text.length; i++)
|
|
106
|
+
u16[i] = text.charCodeAt(i);
|
|
107
|
+
hb.hb_buffer_add_utf16(buf, textPtr, text.length, 0, text.length);
|
|
108
|
+
hb.free(textPtr);
|
|
109
|
+
hb.hb_buffer_guess_segment_properties(buf);
|
|
110
|
+
hb.hb_buffer_set_direction(buf, request.direction === 'rtl' ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
|
|
111
|
+
if (request.script) {
|
|
112
|
+
const s = this.ascii(request.script);
|
|
113
|
+
hb.hb_buffer_set_script(buf, hb.hb_script_from_string(s, -1));
|
|
114
|
+
hb.free(s);
|
|
115
|
+
}
|
|
116
|
+
if (request.language) {
|
|
117
|
+
const s = this.ascii(request.language);
|
|
118
|
+
hb.hb_buffer_set_language(buf, hb.hb_language_from_string(s, -1));
|
|
119
|
+
hb.free(s);
|
|
120
|
+
}
|
|
121
|
+
const features = request.features ?? [];
|
|
122
|
+
let featuresPtr = 0;
|
|
123
|
+
if (features.length > 0) {
|
|
124
|
+
featuresPtr = hb.malloc(features.length * FEATURE_BYTES);
|
|
125
|
+
const words = new Uint32Array(hb.memory.buffer, featuresPtr, features.length * 4);
|
|
126
|
+
features.forEach(([tag, value], i) => {
|
|
127
|
+
words[i * 4] = hbTag(tag);
|
|
128
|
+
words[i * 4 + 1] = value >>> 0;
|
|
129
|
+
words[i * 4 + 2] = 0;
|
|
130
|
+
words[i * 4 + 3] = FEATURE_GLOBAL_END;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
hb.hb_shape(font.font, buf, featuresPtr, features.length);
|
|
134
|
+
if (featuresPtr)
|
|
135
|
+
hb.free(featuresPtr);
|
|
136
|
+
const n = hb.hb_buffer_get_length(buf);
|
|
137
|
+
const infos = hb.hb_buffer_get_glyph_infos(buf, 0) >>> 2;
|
|
138
|
+
const positions = hb.hb_buffer_get_glyph_positions(buf, 0) >>> 2;
|
|
139
|
+
const u32 = new Uint32Array(hb.memory.buffer);
|
|
140
|
+
const i32 = new Int32Array(hb.memory.buffer);
|
|
141
|
+
const glyphs = new Array(n);
|
|
142
|
+
for (let i = 0; i < n; i++) {
|
|
143
|
+
const info = infos + i * GLYPH_WORDS;
|
|
144
|
+
const pos = positions + i * GLYPH_WORDS;
|
|
145
|
+
glyphs[i] = {
|
|
146
|
+
gid: u32[info],
|
|
147
|
+
cluster: u32[info + 2],
|
|
148
|
+
xAdvance: i32[pos],
|
|
149
|
+
yAdvance: i32[pos + 1],
|
|
150
|
+
xOffset: i32[pos + 2],
|
|
151
|
+
yOffset: i32[pos + 3],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return glyphs;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Instantiate HarfBuzz from its binary. */
|
|
158
|
+
export async function instantiateHarfBuzz(wasm) {
|
|
159
|
+
// The heap is the module's own export, known once it is instantiated.
|
|
160
|
+
const heap = {};
|
|
161
|
+
const abort = (what) => {
|
|
162
|
+
throw new WebAssembly.RuntimeError(`HarfBuzz aborted (${what})`);
|
|
163
|
+
};
|
|
164
|
+
const imports = {
|
|
165
|
+
env: {
|
|
166
|
+
_abort_js: () => abort('abort'),
|
|
167
|
+
// Emscripten's event loop: nothing here keeps it alive or sets a
|
|
168
|
+
// timer (`alarm`, `setitimer`), and shaping never asks for one.
|
|
169
|
+
_emscripten_runtime_keepalive_clear: () => { },
|
|
170
|
+
_setitimer_js: () => 0,
|
|
171
|
+
// Grow the heap to hold `requested` bytes: double it, as Emscripten
|
|
172
|
+
// does, up to its ceiling. 1 on success, 0 when it cannot.
|
|
173
|
+
emscripten_resize_heap: (requested) => {
|
|
174
|
+
const mem = heap.memory;
|
|
175
|
+
const old = mem.buffer.byteLength;
|
|
176
|
+
requested >>>= 0;
|
|
177
|
+
if (requested > HEAP_MAX)
|
|
178
|
+
return 0;
|
|
179
|
+
const target = Math.min(HEAP_MAX, Math.max(requested, old * 2));
|
|
180
|
+
try {
|
|
181
|
+
mem.grow(Math.ceil((target - old) / WASM_PAGE));
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
try {
|
|
186
|
+
mem.grow(Math.ceil((requested - old) / WASM_PAGE));
|
|
187
|
+
return 1;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
wasi_snapshot_preview1: {
|
|
196
|
+
proc_exit: (code) => abort(`exit ${code}`),
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
const { instance } = await WebAssembly.instantiate(wasm, imports);
|
|
200
|
+
const hb = instance.exports;
|
|
201
|
+
heap.memory = hb.memory;
|
|
202
|
+
hb.__wasm_call_ctors();
|
|
203
|
+
return new HarfBuzz(hb);
|
|
204
|
+
}
|
|
205
|
+
/** The literal, so a bundler emits the binary beside the chunk. */
|
|
206
|
+
function besideThisModule() {
|
|
207
|
+
return new URL('./harfbuzz.wasm', import.meta.url);
|
|
208
|
+
}
|
|
209
|
+
/** Whether `bytes` start as a WebAssembly module (`\0asm`): a server that
|
|
210
|
+
* answers a missing file with a page must not reach `instantiate`. */
|
|
211
|
+
function isWasm(bytes) {
|
|
212
|
+
return bytes.length > 8 && bytes[0] === 0 && bytes[1] === 0x61 && bytes[2] === 0x73 && bytes[3] === 0x6d;
|
|
213
|
+
}
|
|
214
|
+
/** Read a `file:` URL. `node:fs` is named through a variable, so a
|
|
215
|
+
* bundler or a CDN leaves it alone, and only a host that runs from files
|
|
216
|
+
* (Node, Deno, Bun) ever imports it. */
|
|
217
|
+
async function readFileUrl(url) {
|
|
218
|
+
const fsModule = 'node:fs/promises';
|
|
219
|
+
const fs = (await import(/* webpackIgnore: true */ /* turbopackIgnore: true */ /* @vite-ignore */ fsModule));
|
|
220
|
+
return new Uint8Array(await fs.readFile(url));
|
|
221
|
+
}
|
|
222
|
+
async function fetchBytes(url) {
|
|
223
|
+
if (url.protocol === 'file:')
|
|
224
|
+
return readFileUrl(url);
|
|
225
|
+
const response = await fetch(url);
|
|
226
|
+
if (!response.ok)
|
|
227
|
+
throw new Error(`HTTP ${response.status}`);
|
|
228
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
229
|
+
}
|
|
230
|
+
/** What a relative `source` resolves against: the page's (or worker's)
|
|
231
|
+
* location, as a `fetch` would; this module's URL where there is none. */
|
|
232
|
+
export function sourceBase() {
|
|
233
|
+
return globalThis.location?.href ?? import.meta.url;
|
|
234
|
+
}
|
|
235
|
+
/** The places the binary is looked for when the caller gave none. */
|
|
236
|
+
function defaultLocations() {
|
|
237
|
+
const beside = besideThisModule();
|
|
238
|
+
if (beside.protocol === 'file:') {
|
|
239
|
+
// From `src` (tests) or a `dist` built without the copy: the package
|
|
240
|
+
// this binding is written against. Resolved against `beside`, not
|
|
241
|
+
// `import.meta.url`, so no bundler takes it for an asset to emit.
|
|
242
|
+
return [beside, new URL('../node_modules/harfbuzzjs/dist/harfbuzz.wasm', beside)];
|
|
243
|
+
}
|
|
244
|
+
return [
|
|
245
|
+
beside,
|
|
246
|
+
new URL(`https://cdn.jsdelivr.net/npm/harfbuzzjs@${HARFBUZZ_VERSION}/dist/harfbuzz.wasm`),
|
|
247
|
+
new URL(`https://esm.sh/harfbuzzjs@${HARFBUZZ_VERSION}/dist/harfbuzz.wasm`),
|
|
248
|
+
];
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Load HarfBuzz from `source`, or from the default locations in turn.
|
|
252
|
+
* Rejects with every place tried and why it failed.
|
|
253
|
+
*/
|
|
254
|
+
export async function loadHarfBuzz(source) {
|
|
255
|
+
if (source !== undefined && typeof source !== 'string' && !(source instanceof URL)) {
|
|
256
|
+
const bytes = ArrayBuffer.isView(source)
|
|
257
|
+
? new Uint8Array(source.buffer, source.byteOffset, source.byteLength)
|
|
258
|
+
: new Uint8Array(source);
|
|
259
|
+
return instantiateHarfBuzz(bytes);
|
|
260
|
+
}
|
|
261
|
+
const locations = source !== undefined ? [new URL(source, sourceBase())] : defaultLocations();
|
|
262
|
+
const failures = [];
|
|
263
|
+
for (const url of locations) {
|
|
264
|
+
let bytes;
|
|
265
|
+
try {
|
|
266
|
+
bytes = await fetchBytes(url);
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
failures.push(`${url.href}: ${err instanceof Error ? err.message : String(err)}`);
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (!isWasm(bytes)) {
|
|
273
|
+
failures.push(`${url.href}: not a WebAssembly file`);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
return instantiateHarfBuzz(bytes);
|
|
277
|
+
}
|
|
278
|
+
throw new Error(failures.join('; '));
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=harfbuzz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harfbuzz.js","sourceRoot":"","sources":["../src/harfbuzz.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { renderToPdf } from './pdf-backend';
|
|
2
|
-
export type { RenderToPdfOptions, RenderProgress, PdfFontProvider, PdfFontRequest, PdfWarning, PdfFontWarning, PdfFontFallbackWarning, PdfMissingGlyphWarning, PdfVariableFontWarning, PdfCffEmbeddedWholeWarning, ResourceBytesProvider, } from './pdf-backend';
|
|
2
|
+
export type { RenderToPdfOptions, RenderProgress, PdfFontProvider, PdfFontRequest, PdfWarning, PdfFontWarning, PdfFontFallbackWarning, PdfMissingGlyphWarning, PdfVariableFontWarning, PdfCffEmbeddedWholeWarning, PdfComplexShapingWarning, ResourceBytesProvider, } from './pdf-backend';
|
|
3
3
|
export { decompressWoff2 } from './woff2';
|
|
4
|
+
export type { HarfBuzzWasmSource } from './harfbuzz';
|
|
4
5
|
export { svgToVectorDrawing, type VectorDrawing } from './pdf-backend/svgVector';
|
|
5
6
|
export { sniffBytes, rasterizeSvgWithDom, type SvgRasterizer } from './pdf-backend/renderResourceBlock';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,mCAAmC,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAe5C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAsB,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAsB,MAAM,mCAAmC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blockRender.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/blockRender.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAuC,MAAM,SAAS,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"blockRender.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/blockRender.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAuC,MAAM,SAAS,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,KAAK,OAAO,EAAiO,MAAM,cAAc,CAAC;AAI3Q,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOrD,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAwjBD,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,WAAW,CAAC,EAAE,qBAAqB,GAClC,IAAI,CAoEN"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { popGraphicsState, pushGraphicsState } from 'pdf-lib';
|
|
2
|
-
import { segmentOrientation } from 'postext';
|
|
2
|
+
import { lineTextAlign, segmentOrientation } from 'postext';
|
|
3
3
|
import { parseFontString } from '../fontString';
|
|
4
|
-
import { alphaOf, alphaStateOp, beginActualTextSpan, cjkLineText, compressedMarkSpacingPx, drawLinePx, drawMeasuredTextPx, drawSwatchPx, drawTextPx, colorFromHex, endActualTextSpan, setTrackingPx } from './primitives';
|
|
4
|
+
import { alphaOf, alphaStateOp, beginActualTextSpan, counterFlipPx, cjkLineText, compressedMarkSpacingPx, drawLinePx, drawMeasuredTextPx, drawSwatchPx, drawTextPx, colorFromHex, endActualTextSpan, setTrackingPx } from './primitives';
|
|
5
5
|
import { paintChip } from './chip';
|
|
6
6
|
import { pickSegmentColor, pickSegmentFont } from './fontHelpers';
|
|
7
7
|
import { renderHeaderFooterSlot } from './headerFooter';
|
|
@@ -10,6 +10,9 @@ import { RefRun, refTarget, UriRuns } from './links';
|
|
|
10
10
|
import { tagArtifact, tagContent } from './tagging';
|
|
11
11
|
import { paintLineMarks, paintRuby, paintWarichu } from './annotations';
|
|
12
12
|
import { inkScaleOperators } from './inkScale';
|
|
13
|
+
import { drawShapedTextPx, drawStyledWordPx } from './shapedText';
|
|
14
|
+
import { segmentLanguages, segmentOffsets, wordParts } from './directedLine';
|
|
15
|
+
import { needsComplexShaping } from '../complexShaping';
|
|
13
16
|
/** The link destination of a footnote of the document being drawn
|
|
14
17
|
* (`LinkRegistry.documentIndex`: note ids repeat from chapter to chapter).
|
|
15
18
|
* A key no resource id takes: it opens with a NUL. */
|
|
@@ -24,6 +27,10 @@ function renderMathRender(ctx, render, topLeftXPx, topLeftYPx, fallbackColor) {
|
|
|
24
27
|
const S = pxPerVb * pxToPt;
|
|
25
28
|
const x = topLeftXPx * pxToPt - render.viewBox.minX * S;
|
|
26
29
|
const y = pageHeightPt - topLeftYPx * pxToPt + render.viewBox.minY * S;
|
|
30
|
+
// A formula on a mirrored page reads unmirrored in its box.
|
|
31
|
+
counterFlipPx(ctx, topLeftXPx, render.widthPx, () => paintMathPaths(ctx, render, x, y, S, fallbackColor));
|
|
32
|
+
}
|
|
33
|
+
function paintMathPaths(ctx, render, x, y, S, fallbackColor) {
|
|
27
34
|
for (const path of render.paths) {
|
|
28
35
|
// MathJax fills are `currentColor` or a hex; an unpainted path (`none`,
|
|
29
36
|
// as a stroke-only rule leaves after flattening) draws nothing, and any
|
|
@@ -99,6 +106,21 @@ function paintComposedText(ctx, seg, x, baseline, font, size, color, colorHex, a
|
|
|
99
106
|
* `/ActualText`. Any other line was set word by word and carries none of
|
|
100
107
|
* them: its segments are painted as every line was before the CJK
|
|
101
108
|
* features, with no further look at each one.
|
|
109
|
+
*
|
|
110
|
+
* A line that carries directions ({@link isDirected}: a right-to-left run
|
|
111
|
+
* on it) is laid out in `line.order`, left to right on the sheet (flow
|
|
112
|
+
* order on a mirrored page), each right-to-left segment shaped as one run
|
|
113
|
+
* by HarfBuzz (`shapedText.ts`), its glyphs shown in visual order, as every
|
|
114
|
+
* right-to-left PDF shows them. The segments are then painted, and tagged,
|
|
115
|
+
* in logical order, each at the place `order` gave it: the content stream,
|
|
116
|
+
* the marked-content sequences and the structure tree read the line as it
|
|
117
|
+
* was written, and readers that order text by position (Poppler) place it
|
|
118
|
+
* by its glyphs. A run of such a line in another language than the
|
|
119
|
+
* document's ({@link segmentLanguages}) is a `Span` with its own `/Lang`.
|
|
120
|
+
*
|
|
121
|
+
* A word set in several styles (`VDTLineSegment.runs`, a bold letter in an
|
|
122
|
+
* Arabic word) is shaped whole and each glyph painted in its run's style
|
|
123
|
+
* (`drawStyledWordPx`).
|
|
102
124
|
*/
|
|
103
125
|
function renderSegments(ctx, segments, startX, baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, justifiedSpaceWidth,
|
|
104
126
|
/** The character spacing the line is painted with (block + line, px);
|
|
@@ -109,6 +131,24 @@ tracking = 0) {
|
|
|
109
131
|
const uris = new UriRuns(ctx, line, linkRegistry, elem);
|
|
110
132
|
const repeatedAt = repeatedHyphenSegment(line, segments);
|
|
111
133
|
const composed = line.cjkComposed === true || ctx.vertical !== undefined;
|
|
134
|
+
const directed = isDirected(line);
|
|
135
|
+
// The order segments are laid out in, left to right (by default
|
|
136
|
+
// theirs), and the x it gives each: they are painted in logical order.
|
|
137
|
+
const order = directed && line.order && line.order.length === segments.length ? line.order : undefined;
|
|
138
|
+
const xs = order ? segmentOffsets(segments, order, startX, (seg) => (seg.kind === 'space' ? (composed && seg.autospace ? seg.width : justifiedSpaceWidth ?? seg.width) : seg.width)) : undefined;
|
|
139
|
+
// Runs in another language than the document's (tagged render only).
|
|
140
|
+
const langs = elem && directed ? segmentLanguages(segments, elem.tree.options.lang) : undefined;
|
|
141
|
+
let langSpan;
|
|
142
|
+
const textElemOf = (i) => {
|
|
143
|
+
const lang = langs?.[i];
|
|
144
|
+
if (!lang) {
|
|
145
|
+
langSpan = undefined;
|
|
146
|
+
return elem;
|
|
147
|
+
}
|
|
148
|
+
if (langSpan?.lang !== lang)
|
|
149
|
+
langSpan = { lang, elem: elem.child('Span', { lang }) };
|
|
150
|
+
return langSpan.elem;
|
|
151
|
+
};
|
|
112
152
|
// A composed CJK line (spread characters, Han–Latin spaces) reads as
|
|
113
153
|
// written, not with the gaps between its pieces.
|
|
114
154
|
// A vertical line is painted in runs and cells down the column: it reads
|
|
@@ -129,11 +169,16 @@ tracking = 0) {
|
|
|
129
169
|
}
|
|
130
170
|
for (let i = 0; i < segments.length; i++) {
|
|
131
171
|
const seg = segments[i];
|
|
172
|
+
if (xs)
|
|
173
|
+
x = xs[i];
|
|
174
|
+
const textElem = langs ? textElemOf(i) : elem;
|
|
132
175
|
if (seg.kind === 'space') {
|
|
133
176
|
const inLink = uris.space(seg.text);
|
|
134
177
|
if (ctx.tags && seg.text) {
|
|
135
|
-
tagContent(ctx, inLink ??
|
|
136
|
-
|
|
178
|
+
tagContent(ctx, inLink ?? textElem);
|
|
179
|
+
// The gap of a poem's bayt holds the tab of its plain text (#378),
|
|
180
|
+
// which no face draws: it reads as a space.
|
|
181
|
+
drawTextPx(ctx, seg.text.replace(/\t/g, ' '), x, baseline, blockFont, blockSize, blockColor);
|
|
137
182
|
}
|
|
138
183
|
// A Han–Latin space keeps the width the composer set.
|
|
139
184
|
x += composed && seg.autospace ? seg.width : justifiedSpaceWidth ?? seg.width;
|
|
@@ -189,16 +234,24 @@ tracking = 0) {
|
|
|
189
234
|
// A footnote marker links to its note, like a `:ref` to its resource
|
|
190
235
|
// and a cross-reference to its anchor (#264).
|
|
191
236
|
const target = refTarget(seg) ?? (seg.footnoteId !== undefined ? footnoteDestination(linkRegistry, seg.footnoteId) : undefined);
|
|
192
|
-
const link = refRun.enter(seg, x,
|
|
237
|
+
const link = refRun.enter(seg, x, textElem, target, seg.width);
|
|
193
238
|
// A page number of the index links to its page.
|
|
194
239
|
const pageElem = seg.pageLink !== undefined && elem && !link ? elem.child('Link') : undefined;
|
|
195
240
|
// A ruby base is the `RB` of a `Ruby` whose `RT` holds its reading (#194).
|
|
196
|
-
const holder = link ?? pageElem ?? uriElem ??
|
|
241
|
+
const holder = link ?? pageElem ?? uriElem ?? textElem;
|
|
197
242
|
const rubyElem = composed && seg.ruby && holder ? holder.child('Ruby') : undefined;
|
|
198
243
|
tagContent(ctx, rubyElem ? rubyElem.child('RB') : holder);
|
|
199
244
|
// The hyphen repeated from the line before is painted but not read.
|
|
200
245
|
const actualText = i === repeatedAt ? seg.text.slice(1) : undefined;
|
|
201
|
-
|
|
246
|
+
// On a line with directions each segment is one run: HarfBuzz shapes a
|
|
247
|
+
// right-to-left one (and any complex text), and a word set in several
|
|
248
|
+
// styles. The kashidas justification inserted are painted, not read.
|
|
249
|
+
const shaped = (seg.runs !== undefined || (directed && (seg.rtl || needsComplexShaping(seg.text))))
|
|
250
|
+
&& paintShapedSegment(ctx, seg, x, baseline + (seg.baselineShift ?? 0), font, size, color, block, fontCache, actualText, kashidaOf(seg, line));
|
|
251
|
+
if (shaped) {
|
|
252
|
+
// Painted by HarfBuzz.
|
|
253
|
+
}
|
|
254
|
+
else if (!composed)
|
|
202
255
|
drawTextPx(ctx, seg.text, x, baseline + (seg.baselineShift ?? 0), font, size, color, undefined, actualText);
|
|
203
256
|
else
|
|
204
257
|
paintComposedText(ctx, seg, x, baseline, font, size, color, colorHex, actualText, tracking, fontCache, blockFont, rubyElem);
|
|
@@ -209,8 +262,8 @@ tracking = 0) {
|
|
|
209
262
|
const ref = refRun.leave(seg, segments[i + 1], target);
|
|
210
263
|
if (ref && linkRegistry) {
|
|
211
264
|
const { scale, pageHeightPt } = ctx;
|
|
212
|
-
const x1 = ref.
|
|
213
|
-
const x2 = (x + seg.width) * scale;
|
|
265
|
+
const x1 = ref.left * scale;
|
|
266
|
+
const x2 = Math.max(ref.right, x + seg.width) * scale;
|
|
214
267
|
const y2 = pageHeightPt - line.bbox.y * scale;
|
|
215
268
|
const y1 = pageHeightPt - (line.bbox.y + line.bbox.height) * scale;
|
|
216
269
|
linkRegistry.addLink(ctx.page, sheetRect(ctx, [x1, y1, x2, y2]), ref.resourceId, link ? { elem: link, contents: ref.text } : undefined);
|
|
@@ -221,6 +274,18 @@ tracking = 0) {
|
|
|
221
274
|
if (lineState)
|
|
222
275
|
endActualTextSpan(ctx, lineState);
|
|
223
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Paint a segment HarfBuzz shapes: a word set in several styles
|
|
279
|
+
* (`runs`), each glyph in its run's face and colour, else the segment as
|
|
280
|
+
* one run in its direction. False when HarfBuzz is not loaded: the caller
|
|
281
|
+
* paints it the fontkit way.
|
|
282
|
+
*/
|
|
283
|
+
function paintShapedSegment(ctx, seg, x, baseline, font, size, color, block, fontCache, actualText, hideTatweel) {
|
|
284
|
+
const direction = seg.rtl ? 'rtl' : 'ltr';
|
|
285
|
+
if (seg.runs && drawStyledWordPx(ctx, seg.text, x, baseline, font, size, color, wordParts(seg, font, color, ctx, (bold, italic) => ({ font: fontCache.get(pickSegmentFont(bold, italic, block)) ?? undefined, color: colorFromHex(pickSegmentColor(bold, italic, block), ctx.colorSpace) })), { direction, actualText, hideTatweel }))
|
|
286
|
+
return true;
|
|
287
|
+
return drawShapedTextPx(ctx, seg.text, x, baseline, font, size, color, { direction, actualText, hideTatweel });
|
|
288
|
+
}
|
|
224
289
|
/** Tracking: the block (column balancing; negative for a runt set short)
|
|
225
290
|
* and the line (justification tracking) were measured with extra advance
|
|
226
291
|
* after every glyph, so paint the line with the matching character
|
|
@@ -257,8 +322,15 @@ function renderLineText(ctx, line, block, columnWidth, columnX, fontCache, linkR
|
|
|
257
322
|
return;
|
|
258
323
|
const blockSize = parseFontString(block.fontString)?.sizePx ?? 0;
|
|
259
324
|
const blockColor = colorFromHex(block.color, ctx.colorSpace);
|
|
260
|
-
|
|
261
|
-
|
|
325
|
+
// A line whose block runs against its frame (a right-to-left paragraph
|
|
326
|
+
// on a left-to-right page, an English quotation in an Arabic book)
|
|
327
|
+
// carries its span (`measure`): it is justified across it and set ragged
|
|
328
|
+
// from its start side, the right, as the canvas sets it.
|
|
329
|
+
const span = line.measure;
|
|
330
|
+
const lineX = span ? span.x : line.bbox.x;
|
|
331
|
+
const align = lineTextAlign(line, block.textAlign);
|
|
332
|
+
const lineIndent = lineX - columnX;
|
|
333
|
+
const effectiveWidth = span ? span.width : columnWidth - lineIndent;
|
|
262
334
|
const segments = line.segments;
|
|
263
335
|
// Only a line of the CJK composer (or down a vertical page) has hung
|
|
264
336
|
// marks and Han–Latin spaces (see `renderSegments`).
|
|
@@ -284,18 +356,18 @@ function renderLineText(ctx, line, block, columnWidth, columnX, fontCache, linkR
|
|
|
284
356
|
}
|
|
285
357
|
if (spaceCount > 0 && ((!line.isLastLine && !line.ragged) || naturalWidth > effectiveWidth)) {
|
|
286
358
|
const justifiedSpaceWidth = (effectiveWidth - wordWidth) / spaceCount;
|
|
287
|
-
renderSegments(ctx, segments,
|
|
359
|
+
renderSegments(ctx, segments, lineX, line.baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, justifiedSpaceWidth, tracking);
|
|
288
360
|
return;
|
|
289
361
|
}
|
|
290
362
|
}
|
|
291
|
-
if ((
|
|
363
|
+
if ((align === 'center' || align === 'right') && segments) {
|
|
292
364
|
// Hung marks stay out of the alignment, as trailing tracking does.
|
|
293
365
|
let contentWidth = 0;
|
|
294
366
|
for (const seg of segments)
|
|
295
367
|
if (!(composed && seg.hangs))
|
|
296
368
|
contentWidth += seg.width;
|
|
297
369
|
const slack = Math.max(0, effectiveWidth - (contentWidth - trailing));
|
|
298
|
-
const startX =
|
|
370
|
+
const startX = lineX + (align === 'center' ? slack / 2 : slack);
|
|
299
371
|
renderSegments(ctx, segments, startX, line.baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, undefined, tracking);
|
|
300
372
|
return;
|
|
301
373
|
}
|
|
@@ -303,29 +375,35 @@ function renderLineText(ctx, line, block, columnWidth, columnX, fontCache, linkR
|
|
|
303
375
|
// blocks. Segments are needed when any of them styles differently from the
|
|
304
376
|
// block (bold/italic/math/ref/own font or colour); otherwise one text
|
|
305
377
|
// object paints the line.
|
|
306
|
-
if (segments && segments.some(composed ? composedSegmentIsStyled : segmentIsStyled)) {
|
|
307
|
-
renderSegments(ctx, segments,
|
|
378
|
+
if (segments && (isDirected(line) || segments.some(composed ? composedSegmentIsStyled : segmentIsStyled))) {
|
|
379
|
+
renderSegments(ctx, segments, lineX, line.baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, undefined, tracking);
|
|
308
380
|
return;
|
|
309
381
|
}
|
|
310
382
|
tagContent(ctx, elem);
|
|
311
383
|
const plainSlack = Math.max(0, effectiveWidth - (line.bbox.width - trailing));
|
|
312
|
-
const plainX =
|
|
384
|
+
const plainX = lineX + (align === 'right' ? plainSlack : align === 'center' ? plainSlack / 2 : 0);
|
|
313
385
|
// Each word where the layout measured it (EF-137): the embedded face's
|
|
314
386
|
// own widths could differ, most of all for a character it has no glyph
|
|
315
|
-
// for, and would carry the rest of the line along.
|
|
316
|
-
// right-to-left letters stays one run, which the shaper turns around.
|
|
387
|
+
// for, and would carry the rest of the line along.
|
|
317
388
|
// The hyphen repeated from the line before is painted but not read.
|
|
318
389
|
const actualText = line.repeatedHyphen && line.text.startsWith('-') ? line.text.slice(1) : undefined;
|
|
319
|
-
|
|
390
|
+
// A line with right-to-left or joining letters and no directions (a VDT
|
|
391
|
+
// from before the engine resolved bidi levels) is set as one text, cut
|
|
392
|
+
// into bidi runs and shaped by HarfBuzz; with fontkit when HarfBuzz is
|
|
393
|
+
// not loaded, which turns the whole line around.
|
|
394
|
+
const complex = needsComplexShaping(line.text);
|
|
395
|
+
if (segments && segments.length > 0 && !complex
|
|
320
396
|
&& drawMeasuredTextPx(ctx, withLineEndSpace(segments, line.text), plainX, line.baseline, blockFont, blockSize, blockColor, tracking, actualText))
|
|
321
397
|
return;
|
|
398
|
+
if (complex && drawShapedTextPx(ctx, line.text, plainX, line.baseline, blockFont, blockSize, blockColor, { base: block.direction, actualText }))
|
|
399
|
+
return;
|
|
322
400
|
drawTextPx(ctx, line.text, plainX, line.baseline, blockFont, blockSize, blockColor, undefined, actualText);
|
|
323
401
|
}
|
|
324
402
|
/** Whether a segment of a line set word by word paints differently from
|
|
325
403
|
* the block's plain text, or is linked; an orientation mark (`:tcy`,
|
|
326
404
|
* `:upright`, `:sideways`) keeps its segment apart. */
|
|
327
405
|
function segmentIsStyled(s) {
|
|
328
|
-
return s.bold || s.italic || s.kind === 'math' || s.kind === 'swatch' || s.kind === 'chip' || s.refResourceId !== undefined || s.href !== undefined || s.pageLink !== undefined || s.fontString !== undefined || s.color !== undefined || s.baselineShift !== undefined
|
|
406
|
+
return s.bold || s.italic || s.runs !== undefined || s.kind === 'math' || s.kind === 'swatch' || s.kind === 'chip' || s.refResourceId !== undefined || s.href !== undefined || s.pageLink !== undefined || s.fontString !== undefined || s.color !== undefined || s.baselineShift !== undefined
|
|
329
407
|
|| s.tcy !== undefined || s.orientation !== undefined || s.labelTab !== undefined;
|
|
330
408
|
}
|
|
331
409
|
/** {@link segmentIsStyled} for a line of the CJK composer or one down a
|
|
@@ -359,25 +437,11 @@ function withLineEndSpace(segments, text) {
|
|
|
359
437
|
const rest = text.slice(shown.length);
|
|
360
438
|
return /^\s+$/.test(rest) ? [...segments, { text: rest, width: 0 }] : segments;
|
|
361
439
|
}
|
|
362
|
-
/** Whether
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
for (let i = 0; i < text.length; i++) {
|
|
368
|
-
const c = text.charCodeAt(i);
|
|
369
|
-
if (c < 0x0590)
|
|
370
|
-
continue;
|
|
371
|
-
if (c <= 0x08ff || (c >= 0xfb1d && c <= 0xfdff) || (c >= 0xfe70 && c <= 0xfefe))
|
|
372
|
-
return true;
|
|
373
|
-
if (c >= 0xd800 && c <= 0xdbff) {
|
|
374
|
-
const cp = text.codePointAt(i);
|
|
375
|
-
if ((cp >= 0x10800 && cp <= 0x10fff) || (cp >= 0x1e800 && cp <= 0x1efff))
|
|
376
|
-
return true;
|
|
377
|
-
i++;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
return false;
|
|
440
|
+
/** Whether a line carries the engine's directions: an order to paint its
|
|
441
|
+
* segments in, or a right-to-left segment. Absent on every left-to-right
|
|
442
|
+
* line, which is painted as it always was. */
|
|
443
|
+
function isDirected(line) {
|
|
444
|
+
return line.order !== undefined || (line.segments?.some((s) => s.rtl) ?? false);
|
|
381
445
|
}
|
|
382
446
|
function renderBullet(ctx, block, fontCache, elem) {
|
|
383
447
|
if (!block.bulletText ||
|
|
@@ -503,4 +567,13 @@ export function renderBlock(ctx, block, columnWidth, columnX, fontCache, resourc
|
|
|
503
567
|
renderStrikethrough(ctx, block);
|
|
504
568
|
}
|
|
505
569
|
}
|
|
570
|
+
/** The tatweels of a segment its text read leaves out: the ones kashida
|
|
571
|
+
* justification inserted (`VDTLineSegment.kashida`), so one the author
|
|
572
|
+
* typed stays; every one on a line of a VDT that only counts them
|
|
573
|
+
* (`VDTLine.kashida`, before the per-segment offsets). */
|
|
574
|
+
function kashidaOf(seg, line) {
|
|
575
|
+
if (seg.kashida)
|
|
576
|
+
return seg.kashida.length;
|
|
577
|
+
return line.kashida !== undefined && !line.segments?.some((s) => s.kashida);
|
|
578
|
+
}
|
|
506
579
|
//# sourceMappingURL=blockRender.js.map
|