postext-pdf 1.29.0 → 1.29.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/dist/__tests__/scriptContextHan.test.js +3 -1
- package/dist/__tests__/scriptContextHan.test.js.map +1 -1
- package/dist/__tests__/shapingLanguageDocument.test.js +1 -1
- package/dist/__tests__/shapingLanguageDocument.test.js.map +1 -1
- package/dist/__tests__/shapingLanguageRuns.test.d.ts +2 -0
- package/dist/__tests__/shapingLanguageRuns.test.d.ts.map +1 -0
- package/dist/__tests__/shapingLanguageRuns.test.js +250 -0
- package/dist/__tests__/shapingLanguageRuns.test.js.map +1 -0
- package/dist/__tests__/shapingLanguageRunsDocument.test.d.ts +2 -0
- package/dist/__tests__/shapingLanguageRunsDocument.test.d.ts.map +1 -0
- package/dist/__tests__/shapingLanguageRunsDocument.test.js +327 -0
- package/dist/__tests__/shapingLanguageRunsDocument.test.js.map +1 -0
- package/dist/faceFiles.d.ts +9 -0
- package/dist/faceFiles.d.ts.map +1 -1
- package/dist/faceFiles.js +16 -1
- package/dist/faceFiles.js.map +1 -1
- package/dist/pdf-backend/blockRender.d.ts.map +1 -1
- package/dist/pdf-backend/blockRender.js +11 -1
- package/dist/pdf-backend/blockRender.js.map +1 -1
- package/dist/pdf-backend/primitives.js +7 -7
- 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 +8 -2
- package/dist/pdf-backend/renderResourceBlock.js.map +1 -1
- package/dist/pdf-backend/shapedText.d.ts.map +1 -1
- package/dist/pdf-backend/shapedText.js +16 -6
- package/dist/pdf-backend/shapedText.js.map +1 -1
- package/dist/pdf-backend/wordPieces.d.ts +48 -0
- package/dist/pdf-backend/wordPieces.d.ts.map +1 -0
- package/dist/pdf-backend/wordPieces.js +72 -0
- package/dist/pdf-backend/wordPieces.js.map +1 -0
- package/dist/shapingLanguage.d.ts +40 -3
- package/dist/shapingLanguage.d.ts.map +1 -1
- package/dist/shapingLanguage.js +168 -5
- package/dist/shapingLanguage.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { execFileSync } from 'node:child_process';
|
|
6
|
+
import { buildDocument, lineRuns, resolveParagraph } from 'postext';
|
|
7
|
+
import { renderToPdf } from '../pdf-backend';
|
|
8
|
+
import { parseFontString } from '../fontString';
|
|
9
|
+
import { loadComplexShaper, shapeRun } from '../complexShaping';
|
|
10
|
+
// #764, end to end, in the faces the page review found off: an Arabic
|
|
11
|
+
// paragraph with quotations in guillemets, brackets and full stops in
|
|
12
|
+
// Markazi Text and in Amiri, and a justified Catalan paragraph with `l·l`
|
|
13
|
+
// words in Crimson Pro. The document is laid out by a measurer that
|
|
14
|
+
// shapes as Chrome 154's canvas does (see `shapingLanguageRuns.test.ts`,
|
|
15
|
+
// which holds Chrome's own widths of these files), in the language and
|
|
16
|
+
// the direction the engine sets on it, and its PDF prints every word
|
|
17
|
+
// where the layout put it.
|
|
18
|
+
const fixture = (name) => new Uint8Array(fs.readFileSync(new URL(`./fixtures/fontsource/${name}`, import.meta.url)));
|
|
19
|
+
/** The files of each family, as Fontsource cuts it: `latin`, then
|
|
20
|
+
* `arabic`. */
|
|
21
|
+
const FACES = {
|
|
22
|
+
'Markazi Text': [fixture('markazi-text-latin.ttf'), fixture('markazi-text-arabic.ttf')],
|
|
23
|
+
Amiri: [fixture('amiri-latin.ttf'), fixture('amiri-arabic.ttf')],
|
|
24
|
+
'Crimson Pro': [fixture('crimson-pro-latin.ttf')],
|
|
25
|
+
};
|
|
26
|
+
const fontProvider = async (family) => FACES[family] ?? FACES.Amiri;
|
|
27
|
+
/** The file the browser takes a character from: the `arabic` one for the
|
|
28
|
+
* Arabic blocks (its `unicode-range`), the `latin` one for the rest. */
|
|
29
|
+
const fileOf = (files, cp) => (files.length > 1 && cp >= 0x0600 && cp <= 0x08FF ? files[1] : files[0]);
|
|
30
|
+
const SCRIPTS = [['Arab', /\p{Script=Arabic}/u], ['Latn', /\p{Script=Latin}/u], ['Grek', /\p{Script=Greek}/u], ['Cyrl', /\p{Script=Cyrillic}/u]];
|
|
31
|
+
const scriptOfLetter = (ch) => SCRIPTS.find(([, re]) => re.test(ch))?.[0];
|
|
32
|
+
/** The advance (em) of one word of a run, as Chrome shapes it: each
|
|
33
|
+
* character in the script of the letter before it in the word, else of
|
|
34
|
+
* the first after it (none for a word with no letter; `latin`: the whole
|
|
35
|
+
* string had no character above U+00FF, and is Latin text), then cut by
|
|
36
|
+
* the file that draws it. */
|
|
37
|
+
function wordAdvance(files, word, rtl, language, latin) {
|
|
38
|
+
const chars = [...word];
|
|
39
|
+
const own = chars.map((ch) => (latin ? 'Latn' : scriptOfLetter(ch)));
|
|
40
|
+
const first = own.find((s) => s !== undefined);
|
|
41
|
+
let before;
|
|
42
|
+
const scripts = own.map((s) => (before = s ?? before) ?? first);
|
|
43
|
+
let advance = 0;
|
|
44
|
+
for (let a = 0; a < chars.length;) {
|
|
45
|
+
const file = fileOf(files, chars[a].codePointAt(0));
|
|
46
|
+
let b = a + 1;
|
|
47
|
+
while (b < chars.length && scripts[b] === scripts[a] && fileOf(files, chars[b].codePointAt(0)) === file)
|
|
48
|
+
b++;
|
|
49
|
+
const script = scripts[a];
|
|
50
|
+
const run = shapeRun(file, chars.slice(a, b).join(''), { direction: rtl ? 'rtl' : 'ltr', ...(script ? { script } : {}), ...(language ? { language } : {}) });
|
|
51
|
+
advance += run ? run.glyphs.reduce((sum, g) => sum + g.xAdvance, 0) / run.upem : (b - a) * 0.5;
|
|
52
|
+
a = b;
|
|
53
|
+
}
|
|
54
|
+
return advance;
|
|
55
|
+
}
|
|
56
|
+
/** The strings the engine measured, each with the context's direction. */
|
|
57
|
+
const measured = new Set();
|
|
58
|
+
/**
|
|
59
|
+
* Measures as Chrome 154's canvas does, with HarfBuzz: the string cut
|
|
60
|
+
* into runs of one direction (UAX #9, in the context's `direction`), each
|
|
61
|
+
* run into words at its spaces, each word shaped in the script of its
|
|
62
|
+
* letters and the context's language.
|
|
63
|
+
*/
|
|
64
|
+
class CanvasCtx {
|
|
65
|
+
direction = 'ltr';
|
|
66
|
+
letterSpacing = '0px';
|
|
67
|
+
fontString = '';
|
|
68
|
+
language = 'inherit';
|
|
69
|
+
get font() {
|
|
70
|
+
return this.fontString;
|
|
71
|
+
}
|
|
72
|
+
set font(value) {
|
|
73
|
+
this.fontString = value;
|
|
74
|
+
}
|
|
75
|
+
get lang() {
|
|
76
|
+
return this.language;
|
|
77
|
+
}
|
|
78
|
+
set lang(value) {
|
|
79
|
+
this.language = value;
|
|
80
|
+
}
|
|
81
|
+
measureText(s) {
|
|
82
|
+
const parsed = parseFontString(this.fontString);
|
|
83
|
+
const files = FACES[parsed?.family ?? ''] ?? FACES.Amiri;
|
|
84
|
+
const language = this.language === 'inherit' || this.language === '' ? undefined : this.language;
|
|
85
|
+
const latin = /^[\u0000-\u00FF]*$/.test(s);
|
|
86
|
+
measured.add(`${this.direction} ${s}`);
|
|
87
|
+
let advance = 0;
|
|
88
|
+
for (const run of lineRuns(resolveParagraph(s, this.direction === 'rtl' ? 'rtl' : 'ltr'))) {
|
|
89
|
+
for (const word of s.slice(run.start, run.end).split(/( )/)) {
|
|
90
|
+
if (word !== '')
|
|
91
|
+
advance += wordAdvance(files, word, (run.level & 1) === 1, language, latin);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { width: advance * (parsed?.sizePx ?? 16) };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const host = globalThis;
|
|
98
|
+
host.OffscreenCanvasRenderingContext2D = CanvasCtx;
|
|
99
|
+
host.OffscreenCanvas = class {
|
|
100
|
+
getContext() {
|
|
101
|
+
return new CanvasCtx();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const pt = (value) => ({ value, unit: 'pt' });
|
|
105
|
+
const SIZE = 20;
|
|
106
|
+
const EM = SIZE / 1000;
|
|
107
|
+
const PAGE = 420;
|
|
108
|
+
const MARGIN = 20;
|
|
109
|
+
function config(locale, fontFamily, bodyText = {}) {
|
|
110
|
+
return {
|
|
111
|
+
page: { width: pt(PAGE), height: pt(400), dpi: 72, margins: { top: pt(MARGIN), bottom: pt(MARGIN), left: pt(MARGIN), right: pt(MARGIN) } },
|
|
112
|
+
locale,
|
|
113
|
+
layout: { layoutType: 'single' },
|
|
114
|
+
header: { elements: [] },
|
|
115
|
+
footer: { elements: [] },
|
|
116
|
+
bodyText: { fontFamily, fontSize: pt(SIZE), lineHeight: pt(36), firstLineIndent: pt(0), textAlign: 'justify', hyphenation: { enabled: false }, shapingLanguage: 'document', ...bodyText },
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const hasPdftotext = (() => {
|
|
120
|
+
try {
|
|
121
|
+
execFileSync('pdftotext', ['-v'], { stdio: 'ignore' });
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
})();
|
|
128
|
+
/** What pdftotext reads as words on each line of the PDF's first page,
|
|
129
|
+
* px at 72 dpi. It cuts a word where its font changes, and at a letter
|
|
130
|
+
* that leaves air before the next: a word may come in several boxes. */
|
|
131
|
+
function wordBoxes(bytes) {
|
|
132
|
+
const file = path.join(os.tmpdir(), `postext-language-runs-${process.pid}-${Math.random().toString(36).slice(2)}.pdf`);
|
|
133
|
+
fs.writeFileSync(file, bytes);
|
|
134
|
+
const xml = execFileSync('pdftotext', ['-bbox', '-l', '1', file, '-'], { encoding: 'utf8' });
|
|
135
|
+
fs.unlinkSync(file);
|
|
136
|
+
const lines = new Map();
|
|
137
|
+
for (const m of xml.matchAll(/<word xMin="([\d.]+)" yMin="([\d.]+)" xMax="([\d.]+)" yMax="[\d.]+">/g)) {
|
|
138
|
+
const y = Math.round(Number(m[2]));
|
|
139
|
+
const key = [...lines.keys()].find((k) => Math.abs(k - y) < 8) ?? y;
|
|
140
|
+
if (!lines.has(key))
|
|
141
|
+
lines.set(key, []);
|
|
142
|
+
lines.get(key).push({ left: Number(m[1]), right: Number(m[3]) });
|
|
143
|
+
}
|
|
144
|
+
return [...lines.entries()].sort((a, b) => a[0] - b[0]).map(([, boxes]) => boxes);
|
|
145
|
+
}
|
|
146
|
+
const firstBlock = (doc) => doc.pages[0].columns[0].blocks[0];
|
|
147
|
+
/**
|
|
148
|
+
* The words of a line as the layout placed them, on the sheet: its
|
|
149
|
+
* segments in the order the line gives (flow order), from the line's
|
|
150
|
+
* start, the spaces of a justified line that is not its paragraph's last
|
|
151
|
+
* stretched to fill the measure; what stands between two spaces is one
|
|
152
|
+
* word. A right-to-left page is the mirror of its flow.
|
|
153
|
+
*/
|
|
154
|
+
function wordPlaces(page, block, line) {
|
|
155
|
+
const segments = line.segments;
|
|
156
|
+
const measure = PAGE - 2 * MARGIN - (line.bbox.x - MARGIN);
|
|
157
|
+
const spaces = segments.filter((s) => s.kind === 'space').length;
|
|
158
|
+
const words = segments.reduce((sum, s) => sum + (s.kind === 'space' ? 0 : s.width), 0);
|
|
159
|
+
const space = block.textAlign === 'justify' && !line.isLastLine && spaces > 0 ? (measure - words) / spaces : undefined;
|
|
160
|
+
const places = [];
|
|
161
|
+
let x = line.bbox.x;
|
|
162
|
+
let open;
|
|
163
|
+
for (const i of line.order ?? segments.map((_, k) => k)) {
|
|
164
|
+
const seg = segments[i];
|
|
165
|
+
const width = seg.kind === 'space' ? space ?? seg.width : seg.width;
|
|
166
|
+
if (seg.kind === 'space')
|
|
167
|
+
open = undefined;
|
|
168
|
+
else if (open)
|
|
169
|
+
open.right = x + width;
|
|
170
|
+
else {
|
|
171
|
+
open = { left: x, right: x + width };
|
|
172
|
+
places.push(open);
|
|
173
|
+
}
|
|
174
|
+
x += width;
|
|
175
|
+
}
|
|
176
|
+
const flow = page.flow;
|
|
177
|
+
const originX = flow && flow.writingMode === 'horizontal-tb' && flow.direction === 'rtl' ? flow.mirror.originX : undefined;
|
|
178
|
+
return originX === undefined ? places : places.map((p) => ({ left: originX - p.right, right: originX - p.left }));
|
|
179
|
+
}
|
|
180
|
+
/** Every word of the PDF against its place: the boxes pdftotext read
|
|
181
|
+
* inside a place start where it starts and end where it ends, to a
|
|
182
|
+
* twentieth of a pixel, and no box lies outside every place. With
|
|
183
|
+
* `whole`, a place holds one box: pdftotext cuts no Latin word that has
|
|
184
|
+
* no hole in it. */
|
|
185
|
+
async function expectInPlace(doc, what, whole = false) {
|
|
186
|
+
const boxes = wordBoxes(await renderToPdf(doc, { fontProvider, accessible: false }));
|
|
187
|
+
const block = firstBlock(doc);
|
|
188
|
+
expect(boxes.length, what).toBe(block.lines.length);
|
|
189
|
+
block.lines.forEach((line, n) => {
|
|
190
|
+
const places = wordPlaces(doc.pages[0], block, line);
|
|
191
|
+
const inside = places.map((place) => boxes[n].filter((box) => (box.left + box.right) / 2 > place.left && (box.left + box.right) / 2 < place.right));
|
|
192
|
+
expect(inside.reduce((sum, list) => sum + list.length, 0), `${what} line ${n + 1}: ${line.text}`).toBe(boxes[n].length);
|
|
193
|
+
places.forEach((place, i) => {
|
|
194
|
+
expect(inside[i].length, `${what} line ${n + 1} word ${i + 1}`).toBeGreaterThan(0);
|
|
195
|
+
if (whole)
|
|
196
|
+
expect(inside[i].length, `${what} line ${n + 1} word ${i + 1} in one piece`).toBe(1);
|
|
197
|
+
expect(Math.min(...inside[i].map((box) => box.left)), `${what} line ${n + 1} word ${i + 1} left`).toBeCloseTo(place.left, 1);
|
|
198
|
+
expect(Math.max(...inside[i].map((box) => box.right)), `${what} line ${n + 1} word ${i + 1} right`).toBeCloseTo(place.right, 1);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/** The width the layout gave each text, thousandths of the em. */
|
|
203
|
+
const widthsOf = (doc) => Object.fromEntries(firstBlock(doc).lines.flatMap((line) => line.segments.filter((s) => s.kind !== 'space').map((s) => [s.text, Math.round((s.width / EM) * 10) / 10])));
|
|
204
|
+
beforeAll(async () => {
|
|
205
|
+
await loadComplexShaper();
|
|
206
|
+
});
|
|
207
|
+
// An Arabic paragraph: «…» quotations, a bracketed aside, full stops, a
|
|
208
|
+
// question mark inside a quotation.
|
|
209
|
+
const ARABIC = '\u0642\u0644\u062A: \u00AB\u0623\u0646\u0627 \u064A\u0627 \u062E\u0627\u0644\u0629.\u00BB \u062B\u0645 \u0645\u0634\u064A\u062A (\u0648\u064A\u0642\u0627\u0644 \u0633\u0627\u0641\u0631\u062A) \u0625\u0644\u0649 \u0627\u0644\u0628\u064A\u0648\u062A. \u00AB\u064A\u0648\u0633\u0641\u061F\u00BB \u0643\u062A\u0627\u0628.';
|
|
210
|
+
// Set from its start side: a justified Arabic line takes kashidas.
|
|
211
|
+
const fromStart = { textAlign: 'left' };
|
|
212
|
+
describe('an Arabic paragraph with quotations, brackets and full stops (#764)', () => {
|
|
213
|
+
it('Markazi Text: the layout measures the guillemets and the stops of Arabic text in Arabic', () => {
|
|
214
|
+
measured.clear();
|
|
215
|
+
const widths = widthsOf(buildDocument({ markdown: ARABIC }, config('ar', 'Markazi Text', fromStart)));
|
|
216
|
+
// Each word as a right-to-left run, as it is painted.
|
|
217
|
+
expect([...measured]).toContain('rtl \u00AB\u0623\u0646\u0627');
|
|
218
|
+
// Chrome's widths of these words in Arabic.
|
|
219
|
+
expect(widths).toMatchObject({ '\u00AB\u0623\u0646\u0627': 939.5, '\u062E\u0627\u0644\u0629.\u00BB': 1892.1, '\u0643\u062A\u0627\u0628.': 1708 });
|
|
220
|
+
// In Persian the face has no forms of its own and draws its marks
|
|
221
|
+
// the same under every script, so the engine measures the word as any
|
|
222
|
+
// text, in a left-to-right context: the stop and the guillemet are a
|
|
223
|
+
// run of their own there, set in the order they are written (0.587 em;
|
|
224
|
+
// 0.582 in the right-to-left run every output paints them in).
|
|
225
|
+
const persian = widthsOf(buildDocument({ markdown: ARABIC }, config('fa', 'Markazi Text', fromStart)));
|
|
226
|
+
expect([...measured]).toContain('ltr \u00AB\u0623\u0646\u0627');
|
|
227
|
+
expect(persian).toMatchObject({ '\u00AB\u0623\u0646\u0627': 1043.5, '\u062E\u0627\u0644\u0629.\u00BB': 1993.2, '\u0643\u062A\u0627\u0628.': 1714.8 });
|
|
228
|
+
});
|
|
229
|
+
it('Amiri: the stop, the brackets and the guillemets of an Arabic word are the Arabic ones', () => {
|
|
230
|
+
const widths = widthsOf(buildDocument({ markdown: ARABIC }, config('ar', 'Amiri', fromStart)));
|
|
231
|
+
expect(widths).toMatchObject({ '\u00AB\u0623\u0646\u0627': 1068, '\u062E\u0627\u0644\u0629.\u00BB': 2112, '(\u0648\u064A\u0642\u0627\u0644': 2380, '\u0643\u062A\u0627\u0628.': 2040 });
|
|
232
|
+
});
|
|
233
|
+
it.skipIf(!hasPdftotext)('the PDF prints every word where the layout put it, in both faces', async () => {
|
|
234
|
+
for (const family of ['Markazi Text', 'Amiri']) {
|
|
235
|
+
// Not Markazi Text in Persian: its words were measured left to
|
|
236
|
+
// right (see above), five thousandths of the em wider than any
|
|
237
|
+
// output sets `.»`.
|
|
238
|
+
for (const locale of family === 'Amiri' ? ['ar', 'ar-EG', 'fa'] : ['ar', 'ar-EG']) {
|
|
239
|
+
const doc = buildDocument({ markdown: ARABIC }, config(locale, family, fromStart));
|
|
240
|
+
expect(firstBlock(doc).lines.length, `${family} ${locale}`).toBeGreaterThan(1);
|
|
241
|
+
await expectInPlace(doc, `${family} ${locale}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}, 120_000);
|
|
245
|
+
it.skipIf(!hasPdftotext)('and in a document that keeps the host\u2019s language, measured in none', async () => {
|
|
246
|
+
const doc = buildDocument({ markdown: ARABIC }, config('ar', 'Amiri', { ...fromStart, shapingLanguage: 'host' }));
|
|
247
|
+
expect(widthsOf(doc)).toMatchObject({ '\u00AB\u0623\u0646\u0627': 1068, '\u062E\u0627\u0644\u0629.\u00BB': 2112, '\u0643\u062A\u0627\u0628.': 2040 });
|
|
248
|
+
await expectInPlace(doc, 'Amiri host');
|
|
249
|
+
// Markazi Text has no forms of its own in no language.
|
|
250
|
+
expect(widthsOf(buildDocument({ markdown: ARABIC }, config('ar', 'Markazi Text', { ...fromStart, shapingLanguage: 'host' })))['\u00AB\u0623\u0646\u0627']).toBe(1043.5);
|
|
251
|
+
}, 120_000);
|
|
252
|
+
});
|
|
253
|
+
describe('a justified Catalan paragraph in Crimson Pro (#764)', () => {
|
|
254
|
+
// A paragraph with a word in italics is cut word by word: the pieces of
|
|
255
|
+
// a word are as wide as the word grew by each. A plain one goes to the
|
|
256
|
+
// text library, which measures each piece alone.
|
|
257
|
+
const STYLED = 'La instal\u00B7laci\u00F3 de la il\u00B7luminaci\u00F3 col\u00B7lectiva *fou* una il\u00B7lusi\u00F3 paral\u00B7lela del col\u00B7legi.';
|
|
258
|
+
const PLAIN = STYLED.replace(/\*/g, '');
|
|
259
|
+
const hyphenated = (locale) => ({ hyphenation: { enabled: true, locale } });
|
|
260
|
+
/** The words of a paragraph: the pieces of each joined, with the width
|
|
261
|
+
* the layout gave them together. */
|
|
262
|
+
const wordWidths = (doc) => {
|
|
263
|
+
const words = {};
|
|
264
|
+
for (const line of firstBlock(doc).lines) {
|
|
265
|
+
let text = '';
|
|
266
|
+
let width = 0;
|
|
267
|
+
for (const seg of [...line.segments, { kind: 'space', text: ' ', width: 0 }]) {
|
|
268
|
+
if (seg.kind !== 'space') {
|
|
269
|
+
text += seg.text;
|
|
270
|
+
width += seg.width;
|
|
271
|
+
}
|
|
272
|
+
else if (text !== '') {
|
|
273
|
+
words[text] = Math.round((width / EM) * 10) / 10;
|
|
274
|
+
text = '';
|
|
275
|
+
width = 0;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return words;
|
|
280
|
+
};
|
|
281
|
+
/** Each line ends between two words: the piece that opens a line after
|
|
282
|
+
* a break inside a word keeps the width the word had beyond the break,
|
|
283
|
+
* whatever stood before it. */
|
|
284
|
+
const expectNoWordBroken = (doc) => {
|
|
285
|
+
for (const line of firstBlock(doc).lines)
|
|
286
|
+
expect(line.text).not.toMatch(/-$/);
|
|
287
|
+
};
|
|
288
|
+
it('a word cut at its syllables is measured whole in a styled paragraph: the Catalan dot is in the piece after it', () => {
|
|
289
|
+
const doc = buildDocument({ markdown: STYLED }, config('ca', 'Crimson Pro', hyphenated('ca')));
|
|
290
|
+
expectNoWordBroken(doc);
|
|
291
|
+
// Chrome's widths in Catalan (4381.8, 2708 and 2856.4 in any other
|
|
292
|
+
// language).
|
|
293
|
+
expect(wordWidths(doc)).toMatchObject({ 'instal\u00B7laci\u00F3': 4727.5, 'il\u00B7lusi\u00F3': 3053.7, 'col\u00B7legi.': 3430.7 });
|
|
294
|
+
// `tal·` alone has the narrow dot (1292); the 354 units of 1024 the
|
|
295
|
+
// Catalan one adds went to the piece after it, 725.6 wide alone.
|
|
296
|
+
const pieces = firstBlock(doc).lines[0].segments.filter((s) => s.kind !== 'space').map((s) => [s.text, Math.round((s.width / EM) * 10) / 10]);
|
|
297
|
+
expect(pieces.slice(1, 5)).toEqual([['ins', 1191.4], ['tal\u00B7', 1292], ['la', 1071.3], ['ci\u00F3', 1172.9]]);
|
|
298
|
+
const spanish = buildDocument({ markdown: STYLED }, config('es', 'Crimson Pro', hyphenated('es')));
|
|
299
|
+
expect(wordWidths(spanish)).toMatchObject({ 'instal\u00B7laci\u00F3': 4381.8, 'il\u00B7lusi\u00F3': 2708, 'col\u00B7legi.': 3085 });
|
|
300
|
+
});
|
|
301
|
+
it('and piece by piece in a plain paragraph: each as wide as it is alone', () => {
|
|
302
|
+
const doc = buildDocument({ markdown: PLAIN }, config('ca', 'Crimson Pro', hyphenated('ca')));
|
|
303
|
+
expectNoWordBroken(doc);
|
|
304
|
+
const pieces = firstBlock(doc).lines[0].segments.filter((s) => s.kind !== 'space').map((s) => [s.text, Math.round((s.width / EM) * 10) / 10]);
|
|
305
|
+
expect(pieces.slice(1, 5)).toEqual([['ins', 1191.4], ['tal\u00B7', 1292], ['la', 725.6], ['ci\u00F3', 1172.9]]);
|
|
306
|
+
});
|
|
307
|
+
it.skipIf(!hasPdftotext)('the PDF prints each word where the layout put it, as wide as measured: no hole after the dot', async () => {
|
|
308
|
+
for (const markdown of [STYLED, PLAIN]) {
|
|
309
|
+
for (const locale of ['ca', 'es']) {
|
|
310
|
+
const doc = buildDocument({ markdown }, config(locale, 'Crimson Pro', hyphenated(locale)));
|
|
311
|
+
expect(firstBlock(doc).lines.length, locale).toBeGreaterThan(1);
|
|
312
|
+
expectNoWordBroken(doc);
|
|
313
|
+
await expectInPlace(doc, `justified ${locale} ${markdown === STYLED ? 'styled' : 'plain'}`, true);
|
|
314
|
+
}
|
|
315
|
+
// Set ragged, and with no syllables: the words come whole.
|
|
316
|
+
await expectInPlace(buildDocument({ markdown }, config('ca', 'Crimson Pro', { textAlign: 'left' })), 'ragged ca', true);
|
|
317
|
+
await expectInPlace(buildDocument({ markdown }, config('ca', 'Crimson Pro')), 'whole words ca', true);
|
|
318
|
+
}
|
|
319
|
+
}, 120_000);
|
|
320
|
+
it.skipIf(!hasPdftotext)('a document that keeps the host\u2019s language is measured with the plain dot and printed piece by piece', async () => {
|
|
321
|
+
const doc = buildDocument({ markdown: STYLED }, config('ca', 'Crimson Pro', { ...hyphenated('ca'), shapingLanguage: 'host' }));
|
|
322
|
+
expectNoWordBroken(doc);
|
|
323
|
+
expect(wordWidths(doc)).toMatchObject({ 'instal\u00B7laci\u00F3': 4381.8, 'il\u00B7lusi\u00F3': 2708 });
|
|
324
|
+
await expectInPlace(doc, 'host ca', true);
|
|
325
|
+
}, 120_000);
|
|
326
|
+
});
|
|
327
|
+
//# sourceMappingURL=shapingLanguageRunsDocument.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapingLanguageRunsDocument.test.js","sourceRoot":"","sources":["../../src/__tests__/shapingLanguageRunsDocument.test.ts"],"names":[],"mappings":"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"}
|
package/dist/faceFiles.d.ts
CHANGED
|
@@ -42,6 +42,10 @@ export declare function faceFilesOf(font: PDFFont): FaceFiles | undefined;
|
|
|
42
42
|
export interface FileRun {
|
|
43
43
|
font: PDFFont;
|
|
44
44
|
text: string;
|
|
45
|
+
/** A letter of the script the run is shaped in, when it holds no letter
|
|
46
|
+
* and the text it was cut out of does (`besideLetterOf`, #764): the
|
|
47
|
+
* caller shapes the run inside `withBesideLetter`. */
|
|
48
|
+
beside?: number;
|
|
45
49
|
}
|
|
46
50
|
/**
|
|
47
51
|
* `text` cut into runs by the file of `font`'s face that has a glyph for
|
|
@@ -76,6 +80,11 @@ export interface FileRun {
|
|
|
76
80
|
* Latin form for it. A word the file cannot set whole (the `(` of an
|
|
77
81
|
* Arabic sentence, whose mirror only the `latin` file holds) is cut as
|
|
78
82
|
* any other text.
|
|
83
|
+
*
|
|
84
|
+
* A run with no letter, cut out of text that has one (the `.»` of
|
|
85
|
+
* `خالة.»`, which the `latin` file draws), says the letter whose script
|
|
86
|
+
* the browser shaped it in (`beside`, #764), in a document shaped in its
|
|
87
|
+
* own language.
|
|
79
88
|
*/
|
|
80
89
|
export declare function fileRuns(font: PDFFont, text: string, rtl?: boolean): FileRun[];
|
|
81
90
|
/** `text`'s width at `size` (points), each run measured in its file. */
|
package/dist/faceFiles.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faceFiles.d.ts","sourceRoot":"","sources":["../src/faceFiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAsBvC,sEAAsE;AACtE,qBAAa,SAAS;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgD;IACtE,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;gBAE/C,KAAK,EAAE,SAAS,OAAO,EAAE;IAKrC;uBACmB;IACnB,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAQxB,2CAA2C;IAC3C,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAI1C,uEAAuE;IACvE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;CAapC;AAID;;;oDAGoD;AACpD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CASxF;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAGhE;AAED,+CAA+C;AAC/C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"faceFiles.d.ts","sourceRoot":"","sources":["../src/faceFiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAsBvC,sEAAsE;AACtE,qBAAa,SAAS;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgD;IACtE,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;gBAE/C,KAAK,EAAE,SAAS,OAAO,EAAE;IAKrC;uBACmB;IACnB,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAQxB,2CAA2C;IAC3C,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAI1C,uEAAuE;IACvE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;CAapC;AAID;;;oDAGoD;AACpD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CASxF;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAGhE;AAED,+CAA+C;AAC/C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb;;2DAEuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,UAAQ,GAAG,OAAO,EAAE,CAmE5E;AAgCD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMnF;AAQD;;;6EAG6E;AAC7E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAanE;AAED;yEACyE;AACzE,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAEtF;AAED;4BAC4B;AAC5B,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9C"}
|
package/dist/faceFiles.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mirroredCodePoint } from 'postext';
|
|
2
2
|
import { isDefaultIgnorable, isFallbackHandled, substituteGlyph } from './pdf-backend/fallbackSpaces';
|
|
3
|
-
import { shapingScriptLetter } from './shapingLanguage';
|
|
3
|
+
import { besideLetterOf, shapingScriptLetter } from './shapingLanguage';
|
|
4
4
|
function coverageFace(font) {
|
|
5
5
|
const face = font.embedder?.font;
|
|
6
6
|
return face && typeof face.hasGlyphForCodePoint === 'function' ? face : undefined;
|
|
@@ -108,6 +108,11 @@ export function faceFilesOf(font) {
|
|
|
108
108
|
* Latin form for it. A word the file cannot set whole (the `(` of an
|
|
109
109
|
* Arabic sentence, whose mirror only the `latin` file holds) is cut as
|
|
110
110
|
* any other text.
|
|
111
|
+
*
|
|
112
|
+
* A run with no letter, cut out of text that has one (the `.»` of
|
|
113
|
+
* `خالة.»`, which the `latin` file draws), says the letter whose script
|
|
114
|
+
* the browser shaped it in (`beside`, #764), in a document shaped in its
|
|
115
|
+
* own language.
|
|
111
116
|
*/
|
|
112
117
|
export function fileRuns(font, text, rtl = false) {
|
|
113
118
|
const list = faceFilesOf(font);
|
|
@@ -172,6 +177,16 @@ export function fileRuns(font, text, rtl = false) {
|
|
|
172
177
|
else
|
|
173
178
|
runs.push({ font, text: pending });
|
|
174
179
|
}
|
|
180
|
+
if (runs.length > 1) {
|
|
181
|
+
// The runs follow each other through the text.
|
|
182
|
+
let at = 0;
|
|
183
|
+
for (const run of runs) {
|
|
184
|
+
const beside = besideLetterOf(text, at, at + run.text.length);
|
|
185
|
+
if (beside !== undefined)
|
|
186
|
+
run.beside = beside;
|
|
187
|
+
at += run.text.length;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
175
190
|
return runs.length > 0 ? runs : [{ font, text }];
|
|
176
191
|
}
|
|
177
192
|
/** Opening brackets and initial quotation marks (`Ps`, `Pi`). */
|
package/dist/faceFiles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faceFiles.js","sourceRoot":"","sources":["../src/faceFiles.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"faceFiles.js","sourceRoot":"","sources":["../src/faceFiles.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blockRender.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/blockRender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAW,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAuB,cAAc,EAAc,MAAM,SAAS,CAAC;AAEzF,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,KAAK,OAAO,EAAqR,MAAM,cAAc,CAAC;AAM/T,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AACnE,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"blockRender.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/blockRender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAW,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAuB,cAAc,EAAc,MAAM,SAAS,CAAC;AAEzF,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,KAAK,OAAO,EAAqR,MAAM,cAAc,CAAC;AAM/T,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAA8B,MAAM,SAAS,CAAC;AACnE,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AASrD,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AA0CD;+CAC+C;AAC/C,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,KAAK,GACnB,IAAI,CAGN;AAyqBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,IAAI,CAgBN;AAED,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,CAyEN"}
|
|
@@ -16,6 +16,7 @@ import { drawShapedTextPx, drawStyledWordPx } from './shapedText';
|
|
|
16
16
|
import { segmentLanguages, segmentOffsets, wordParts } from './directedLine';
|
|
17
17
|
import { needsComplexShaping } from '../complexShaping';
|
|
18
18
|
import { shapesSegmentLanguages, withSegmentLanguage } from '../shapingLanguage';
|
|
19
|
+
import { wordSegments } from './wordPieces';
|
|
19
20
|
/** The link destination of a footnote of the document being drawn
|
|
20
21
|
* (`LinkRegistry.documentIndex`: note ids repeat from chapter to chapter).
|
|
21
22
|
* A key no resource id takes: it opens with a NUL. */
|
|
@@ -145,6 +146,10 @@ textElem) {
|
|
|
145
146
|
* A word set in several styles (`VDTLineSegment.runs`, a bold letter in an
|
|
146
147
|
* Arabic word) is shaped whole and each glyph painted in its run's style
|
|
147
148
|
* (`drawStyledWordPx`).
|
|
149
|
+
*
|
|
150
|
+
* `segments` are the line's own, or, in a document shaped in its own
|
|
151
|
+
* language, those with the pieces of a word measured whole joined
|
|
152
|
+
* (`wordPieces.ts`).
|
|
148
153
|
*/
|
|
149
154
|
function renderSegments(ctx, segments, startX, baseline, line, block, blockFont, blockSize, blockColor, fontCache, linkRegistry, elem, justifiedSpaceWidth,
|
|
150
155
|
/** The character spacing the line is painted with (block + line, px);
|
|
@@ -414,10 +419,15 @@ function renderLineText(ctx, line, block, columnWidth, columnX, fontCache, linkR
|
|
|
414
419
|
const align = lineTextAlign(line, block.textAlign);
|
|
415
420
|
const lineIndent = lineX - columnX;
|
|
416
421
|
const effectiveWidth = span ? span.width : columnWidth - lineIndent;
|
|
417
|
-
const segments = line.segments;
|
|
418
422
|
// Only a line of the CJK composer (or down a vertical page) has hung
|
|
419
423
|
// marks and Han–Latin spaces (see `renderSegments`).
|
|
420
424
|
const composed = line.cjkComposed === true || ctx.vertical !== undefined;
|
|
425
|
+
// The pieces of a word the layout measured whole are painted as that
|
|
426
|
+
// word, in a document shaped in its own language (#764).
|
|
427
|
+
const segments = wordSegments(line, composed, (seg, text) => {
|
|
428
|
+
const fontStr = seg.fontString ?? pickSegmentFont(!!seg.bold, !!seg.italic, block);
|
|
429
|
+
return withSegmentLanguage(seg.lang, () => textAdvancePx(fontCache.get(fontStr) ?? blockFont, text, parseFontString(fontStr)?.sizePx ?? blockSize, tracking).advance);
|
|
430
|
+
});
|
|
421
431
|
// Last lines render ragged at natural width — except when overfull:
|
|
422
432
|
// Knuth-Plass may accept a final line wider than the measure on the
|
|
423
433
|
// assumption that its inter-word glue shrinks (TeX glue-setting semantics),
|