postext-pdf 1.28.0 → 1.28.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__/sharedGlyphReadback.test.d.ts +2 -0
- package/dist/__tests__/sharedGlyphReadback.test.d.ts.map +1 -0
- package/dist/__tests__/sharedGlyphReadback.test.js +331 -0
- package/dist/__tests__/sharedGlyphReadback.test.js.map +1 -0
- package/dist/fontCache.d.ts +10 -0
- package/dist/fontCache.d.ts.map +1 -1
- package/dist/fontCache.js +15 -0
- package/dist/fontCache.js.map +1 -1
- package/dist/pdf-backend/fallbackSpaces.d.ts +3 -0
- package/dist/pdf-backend/fallbackSpaces.d.ts.map +1 -1
- package/dist/pdf-backend/fallbackSpaces.js +5 -0
- package/dist/pdf-backend/fallbackSpaces.js.map +1 -1
- package/dist/pdf-backend/primitives.d.ts +18 -4
- package/dist/pdf-backend/primitives.d.ts.map +1 -1
- package/dist/pdf-backend/primitives.js +194 -55
- package/dist/pdf-backend/primitives.js.map +1 -1
- package/dist/pdf-backend/shapedText.d.ts +5 -0
- package/dist/pdf-backend/shapedText.d.ts.map +1 -1
- package/dist/pdf-backend/shapedText.js +10 -4
- package/dist/pdf-backend/shapedText.js.map +1 -1
- package/dist/pdf-backend/svgVector.js +1 -1
- package/dist/pdf-backend/svgVector.js.map +1 -1
- package/package.json +3 -3
|
@@ -33,6 +33,11 @@ export interface PageCtx {
|
|
|
33
33
|
* vertical painter reads it, since it sets its own spacing inside its
|
|
34
34
|
* text objects. */
|
|
35
35
|
trackingPx?: number;
|
|
36
|
+
/** How many spans opened with {@link beginActualTextSpan} are open:
|
|
37
|
+
* what is painted inside one is read as the span's text, and no glyph
|
|
38
|
+
* takes a span of its own there (#755; a reader that meets an
|
|
39
|
+
* `/ActualText` inside another, Poppler, drops the outer one). */
|
|
40
|
+
readSpans?: number;
|
|
36
41
|
/** Set while a right-to-left page's flow paints through its mirror
|
|
37
42
|
* (`VDTMirroredFlowFrame`, {@link mirrorMatrix}): every text object
|
|
38
43
|
* and picture is turned back about its own box, so it reads as written
|
|
@@ -167,8 +172,12 @@ export interface TextShow {
|
|
|
167
172
|
}
|
|
168
173
|
/** The show-text operators of `text` in `font`'s face: one
|
|
169
174
|
* ({@link showTextShaped}) for a face of one file, else one per run of
|
|
170
|
-
* characters set in the same file (see `faceFiles.ts`).
|
|
171
|
-
|
|
175
|
+
* characters set in the same file (see `faceFiles.ts`). A glyph the
|
|
176
|
+
* font's `/ToUnicode` map reads as other text is shown in a span of its
|
|
177
|
+
* own ({@link glyphReads}), unless `read` is false: the caller reads the
|
|
178
|
+
* text some other way (an `/ActualText` over all of it, a figure's
|
|
179
|
+
* alternate text). */
|
|
180
|
+
export declare function textShows(font: PDFFont, text: string, read?: boolean): TextShow[];
|
|
172
181
|
/** How far `text` moves the pen in `font`'s face at `sizePx`, px, with
|
|
173
182
|
* `trackingPx` after every glyph (as {@link showTextShaped} paints it,
|
|
174
183
|
* each run in the file of the face that has it); and how many glyphs it
|
|
@@ -196,12 +205,17 @@ export declare function measuredTextOperator(font: PDFFont, pieces: readonly {
|
|
|
196
205
|
* {@link measuredTextOperator} for a face of any number of files: the
|
|
197
206
|
* pieces cut into runs by file (see `faceFiles.ts`), one show-text
|
|
198
207
|
* operator per stretch set in the same file. The pen carries across the
|
|
199
|
-
* font switches, so every piece still starts where the layout put it.
|
|
208
|
+
* font switches, so every piece still starts where the layout put it. A
|
|
209
|
+
* glyph the font's `/ToUnicode` map reads as other text is shown in a span
|
|
210
|
+
* of its own between two of them ({@link glyphReads}).
|
|
200
211
|
*/
|
|
201
212
|
export declare function measuredTextShows(font: PDFFont, pieces: readonly {
|
|
202
213
|
text: string;
|
|
203
214
|
width: number;
|
|
204
|
-
}[], sizePx: number, trackingPx?: number
|
|
215
|
+
}[], sizePx: number, trackingPx?: number,
|
|
216
|
+
/** False when the caller reads the text some other way: no glyph takes
|
|
217
|
+
* a span of its own (see {@link textShows}). */
|
|
218
|
+
read?: boolean): TextShow[] | undefined;
|
|
205
219
|
export declare function fontKeyOn(page: PDFPage, font: PDFFont): PDFName;
|
|
206
220
|
/** Outline of the glyphs a text is drawn with (a design text's `stroke`):
|
|
207
221
|
* stroked over the fill, or alone for hollow letters. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/primitives.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,SAAS,EAOT,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,KAAK,EAGV,OAAO,EAEP,WAAW,EAoBZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAwC,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAC9J,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/primitives.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,9 @@ import { rgb, cmyk, grayscale, pushGraphicsState, popGraphicsState, rectangle, c
|
|
|
2
2
|
import { colorAlpha, hexToRgb, rgbToCmyk, rgbToGrayscale } from '../colors';
|
|
3
3
|
import { isPrintMode, modeKey, overPaper } from '../print/colorMode';
|
|
4
4
|
import { joinsLetters, scriptContextUntracked } from 'postext';
|
|
5
|
-
import { fallbackPieces } from './fallbackSpaces';
|
|
5
|
+
import { fallbackPieces, isDefaultIgnorable, isSpaceCharacter } from './fallbackSpaces';
|
|
6
6
|
import { fileRuns, noteMissingGlyphs } from '../faceFiles';
|
|
7
|
+
import { needsComplexShaping } from '../complexShaping';
|
|
7
8
|
import { shapingKey, withShapingScript } from '../shapingLanguage';
|
|
8
9
|
/** Set the character spacing (`Tc`) text is painted with, px, and record
|
|
9
10
|
* it on the context. */
|
|
@@ -350,8 +351,15 @@ export function showTextShaped(font, text) {
|
|
|
350
351
|
const hit = cache.get(key);
|
|
351
352
|
if (hit)
|
|
352
353
|
return hit;
|
|
353
|
-
|
|
354
|
-
|
|
354
|
+
const run = shownRun(font, text);
|
|
355
|
+
let op;
|
|
356
|
+
if (run)
|
|
357
|
+
op = partsOperator(font, plainParts(run.parts));
|
|
358
|
+
else {
|
|
359
|
+
// A standard font: no shaper, pdf-lib's own encoding.
|
|
360
|
+
noteMissingGlyphs(font, text);
|
|
361
|
+
op = showText(font.encodeText(text));
|
|
362
|
+
}
|
|
355
363
|
if (cache.size >= ENCODE_CACHE_SLOTS)
|
|
356
364
|
cache.clear();
|
|
357
365
|
cache.set(key, op);
|
|
@@ -359,9 +367,16 @@ export function showTextShaped(font, text) {
|
|
|
359
367
|
}
|
|
360
368
|
/** The show-text operators of `text` in `font`'s face: one
|
|
361
369
|
* ({@link showTextShaped}) for a face of one file, else one per run of
|
|
362
|
-
* characters set in the same file (see `faceFiles.ts`).
|
|
363
|
-
|
|
364
|
-
|
|
370
|
+
* characters set in the same file (see `faceFiles.ts`). A glyph the
|
|
371
|
+
* font's `/ToUnicode` map reads as other text is shown in a span of its
|
|
372
|
+
* own ({@link glyphReads}), unless `read` is false: the caller reads the
|
|
373
|
+
* text some other way (an `/ActualText` over all of it, a figure's
|
|
374
|
+
* alternate text). */
|
|
375
|
+
export function textShows(font, text, read = true) {
|
|
376
|
+
return fileRuns(font, text).flatMap((run) => {
|
|
377
|
+
const shown = read ? shownRun(run.font, run.text) : undefined;
|
|
378
|
+
return shown?.reads ? partsShows(run.font, shown.parts) : [{ font: run.font, op: showTextShaped(run.font, run.text) }];
|
|
379
|
+
});
|
|
365
380
|
}
|
|
366
381
|
function shapingFace(font) {
|
|
367
382
|
const embedder = font.embedder;
|
|
@@ -370,22 +385,96 @@ function shapingFace(font) {
|
|
|
370
385
|
return undefined;
|
|
371
386
|
return { face, features: embedder.fontFeatures };
|
|
372
387
|
}
|
|
373
|
-
/**
|
|
374
|
-
*
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
*
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
*
|
|
388
|
+
/**
|
|
389
|
+
* What the glyphs fontkit laid `text` out with are read as, where the
|
|
390
|
+
* font's `/ToUnicode` map reads them as other text (#755); undefined when
|
|
391
|
+
* the map reads every one as written, which is nearly always.
|
|
392
|
+
*
|
|
393
|
+
* The map is one per font, and a glyph keeps the characters it was first
|
|
394
|
+
* given (fontkit makes a glyph once, with the characters of the text that
|
|
395
|
+
* first showed it; `shapedText.ts` does the same for the glyphs HarfBuzz
|
|
396
|
+
* shows). A glyph two characters share therefore reads as the first of
|
|
397
|
+
* them the document set: the bracket a right-to-left run mirrors is the
|
|
398
|
+
* glyph of the other bracket, so after `(١)` in an Arabic note the glyph
|
|
399
|
+
* of `)` stands for `(`, and a later `(Brill, 2017)` in the same font read
|
|
400
|
+
* back `(Brill, 2017(`. A form the shaper puts in a character's place
|
|
401
|
+
* takes the characters of that character's own glyph, the wrong ones
|
|
402
|
+
* with them. The same goes for any two characters the face's cmap draws
|
|
403
|
+
* with one glyph: the hyphen-minus and the hyphen, the space and the
|
|
404
|
+
* no-break space. Such a glyph is shown in a span whose `/ActualText` is
|
|
405
|
+
* its character here, as `shapedText.ts` does for a cluster HarfBuzz
|
|
406
|
+
* shaped: the first use of a glyph costs nothing, each use for another
|
|
407
|
+
* character one span.
|
|
408
|
+
*
|
|
409
|
+
* The glyphs are walked against the text. A glyph whose own characters
|
|
410
|
+
* are the next ones of the text reads right; one with no characters (the
|
|
411
|
+
* second glyph of a decomposed letter) reads as nothing; one that holds
|
|
412
|
+
* one character, and not the next of the text, is read as that next
|
|
413
|
+
* character. Three glyphs are left as they read: `.notdef`, which stands
|
|
414
|
+
* for every character the face lacks; the space glyph fontkit hides an
|
|
415
|
+
* invisible character behind; and the space glyph, read as a space, under
|
|
416
|
+
* a no-break space or any other space the face draws with it (a space the
|
|
417
|
+
* face lacks reads as a space too, see `fallbackSpaces.ts`). The reads
|
|
418
|
+
* hold only when the walk ends where the text does (every glyph accounted
|
|
419
|
+
* for, one way or another); when it does not — a glyph for several
|
|
420
|
+
* characters that holds others, a variation selector — the run is left as
|
|
421
|
+
* it reads.
|
|
422
|
+
*/
|
|
423
|
+
function glyphReads(face, glyphs, text) {
|
|
424
|
+
// fontkit hands a right-to-left run's glyphs over in visual order: such
|
|
425
|
+
// text is HarfBuzz's whenever it is loaded, and is not walked here.
|
|
426
|
+
if (needsComplexShaping(text))
|
|
427
|
+
return undefined;
|
|
428
|
+
let reads;
|
|
429
|
+
let space;
|
|
430
|
+
// UTF-16 offset in `text` of the next character to read.
|
|
431
|
+
let at = 0;
|
|
432
|
+
for (let i = 0; i < glyphs.length; i++) {
|
|
433
|
+
const glyph = glyphs[i];
|
|
434
|
+
const own = glyph.codePoints;
|
|
435
|
+
if (glyph.id !== 0 && (!own || own.length === 0))
|
|
436
|
+
continue;
|
|
437
|
+
let end = at;
|
|
438
|
+
for (const cp of own ?? []) {
|
|
439
|
+
if (text.codePointAt(end) !== cp) {
|
|
440
|
+
end = -1;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
end += cp > 0xffff ? 2 : 1;
|
|
444
|
+
}
|
|
445
|
+
if (end > at) {
|
|
446
|
+
at = end;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
const cp = text.codePointAt(at);
|
|
450
|
+
if (cp === undefined)
|
|
451
|
+
return undefined;
|
|
452
|
+
at += cp > 0xffff ? 2 : 1;
|
|
453
|
+
if (glyph.id === 0)
|
|
454
|
+
continue;
|
|
455
|
+
if (isDefaultIgnorable(cp) && glyph.id === (space ??= cmapGlyphId(face, 0x20)))
|
|
456
|
+
continue;
|
|
457
|
+
if (own.length !== 1)
|
|
458
|
+
return undefined;
|
|
459
|
+
if (own[0] === 0x20 && isSpaceCharacter(cp))
|
|
460
|
+
continue;
|
|
461
|
+
reads ??= new Array(glyphs.length);
|
|
462
|
+
reads[i] = String.fromCodePoint(cp);
|
|
463
|
+
}
|
|
464
|
+
return at === text.length ? reads : undefined;
|
|
465
|
+
}
|
|
466
|
+
/** The id of the glyph the face's cmap gives `cp` (0: none), read from the
|
|
467
|
+
* cmap itself: `glyphForCodePoint` would make the glyph, with `cp` as the
|
|
468
|
+
* characters it then keeps in the font's map. */
|
|
469
|
+
function cmapGlyphId(face, cp) {
|
|
470
|
+
const cmap = face._cmapProcessor;
|
|
471
|
+
return typeof cmap?.lookup === 'function' ? cmap.lookup(cp) || 0 : 0;
|
|
472
|
+
}
|
|
473
|
+
/** The `TJ` array (hex glyph runs and adjustments) of a shaped run, with
|
|
474
|
+
* the sum of the glyphs' own widths (their `W` entries), in thousandths
|
|
475
|
+
* of the font size; undefined when the shaper's positions cannot be
|
|
476
|
+
* matched to its glyphs. A glyph the font's map reads as other text is a
|
|
477
|
+
* part of its own ({@link glyphReads}). */
|
|
389
478
|
function shapedRun(font, text, encoded) {
|
|
390
479
|
const shaping = shapingFace(font);
|
|
391
480
|
if (!shaping)
|
|
@@ -396,6 +485,7 @@ function shapedRun(font, text, encoded) {
|
|
|
396
485
|
const count = run.glyphs.length;
|
|
397
486
|
if (count === 0 || hex.length !== count * 4 || run.positions.length !== count)
|
|
398
487
|
return undefined;
|
|
488
|
+
const reads = glyphReads(face, run.glyphs, text);
|
|
399
489
|
// TJ numbers are thousandths of text space, subtracted from the pen: a
|
|
400
490
|
// glyph drawn at `pen + xOffset` then advancing by `xAdvance` (not its
|
|
401
491
|
// W width `advanceWidth`) is `-xOffset, glyph, -(xAdvance - w - xOffset)`.
|
|
@@ -418,7 +508,13 @@ function shapedRun(font, text, encoded) {
|
|
|
418
508
|
parts.push(lead);
|
|
419
509
|
}
|
|
420
510
|
const cid = hex.slice(i * 4, i * 4 + 4);
|
|
421
|
-
|
|
511
|
+
const read = reads?.[i];
|
|
512
|
+
if (read !== undefined) {
|
|
513
|
+
flushHex();
|
|
514
|
+
parts.push({ hex: cid, text: read });
|
|
515
|
+
}
|
|
516
|
+
else
|
|
517
|
+
pendingHex += cid;
|
|
422
518
|
pendingAdjust = -(pos.xAdvance - run.glyphs[i].advanceWidth - pos.xOffset) * toText;
|
|
423
519
|
widths += cid === '0000' && subsetFont ? MISSING_WIDTH : run.glyphs[i].advanceWidth * toText;
|
|
424
520
|
}
|
|
@@ -446,10 +542,13 @@ function partsOperator(font, parts) {
|
|
|
446
542
|
return parts.length === 1 && typeof parts[0] === 'string' ? showText(PDFHexString.of(parts[0])) : adjustedOperator(font, parts);
|
|
447
543
|
}
|
|
448
544
|
/** Append a part to a `TJ` array, merging it into a neighbouring glyph run
|
|
449
|
-
* or number; a zero adjustment is dropped.
|
|
545
|
+
* or number; a zero adjustment is dropped. A glyph read through a span
|
|
546
|
+
* stays a part of its own. */
|
|
450
547
|
function pushPart(parts, part) {
|
|
451
548
|
const last = parts[parts.length - 1];
|
|
452
|
-
if (typeof part === '
|
|
549
|
+
if (typeof part === 'object')
|
|
550
|
+
parts.push(part);
|
|
551
|
+
else if (typeof part === 'number') {
|
|
453
552
|
if (part === 0)
|
|
454
553
|
return;
|
|
455
554
|
if (typeof last === 'number')
|
|
@@ -467,16 +566,63 @@ function pushPart(parts, part) {
|
|
|
467
566
|
function shownRunOf(parts, widths) {
|
|
468
567
|
let advance = widths;
|
|
469
568
|
let glyphs = 0;
|
|
569
|
+
let reads = false;
|
|
470
570
|
for (const part of parts) {
|
|
471
571
|
if (typeof part === 'number')
|
|
472
572
|
advance -= part;
|
|
473
|
-
else
|
|
573
|
+
else if (typeof part === 'string')
|
|
474
574
|
glyphs += part.length / 4;
|
|
575
|
+
else {
|
|
576
|
+
glyphs += part.hex.length / 4;
|
|
577
|
+
reads = true;
|
|
578
|
+
}
|
|
475
579
|
}
|
|
476
|
-
return { parts, advance, glyphs };
|
|
580
|
+
return { parts, advance, glyphs, reads };
|
|
581
|
+
}
|
|
582
|
+
/** `parts` with every glyph read through the font's map: one show-text
|
|
583
|
+
* array, as before any glyph took a span. */
|
|
584
|
+
function plainParts(parts) {
|
|
585
|
+
const out = [];
|
|
586
|
+
for (const part of parts)
|
|
587
|
+
pushPart(out, typeof part === 'object' ? part.hex : part);
|
|
588
|
+
return out;
|
|
477
589
|
}
|
|
478
|
-
/**
|
|
479
|
-
*
|
|
590
|
+
/**
|
|
591
|
+
* The show-text operators of `parts` in `font`: one, or, around each glyph
|
|
592
|
+
* read through a span ({@link ReadGlyph}), the span's `BDC`, the glyph and
|
|
593
|
+
* its `EMC`. The glyphs and the pen adjustments are the same ones in the
|
|
594
|
+
* same order, cut into several arrays: nothing moves on the page.
|
|
595
|
+
*/
|
|
596
|
+
function partsShows(font, parts) {
|
|
597
|
+
const shows = [];
|
|
598
|
+
let plain = [];
|
|
599
|
+
const flush = () => {
|
|
600
|
+
if (plain.length > 0)
|
|
601
|
+
shows.push({ font, op: partsOperator(font, plain) });
|
|
602
|
+
plain = [];
|
|
603
|
+
};
|
|
604
|
+
for (const part of parts) {
|
|
605
|
+
if (typeof part !== 'object') {
|
|
606
|
+
pushPart(plain, part);
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
flush();
|
|
610
|
+
const props = font.doc.context.obj({ ActualText: PDFHexString.fromText(part.text) });
|
|
611
|
+
shows.push({ font, op: PDFOperator.of(PDFOperatorNames.BeginMarkedContentSequence, [PDFName.of('Span'), props]) }, { font, op: showText(PDFHexString.of(part.hex)) }, { font, op: PDFOperator.of(PDFOperatorNames.EndMarkedContent) });
|
|
612
|
+
}
|
|
613
|
+
flush();
|
|
614
|
+
if (shows.length === 0)
|
|
615
|
+
shows.push({ font, op: partsOperator(font, []) });
|
|
616
|
+
return shows;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* The parts of a text holding a space the face has no glyph for (a narrow
|
|
620
|
+
* no-break space, a figure space…) or an invisible character (a word
|
|
621
|
+
* joiner): painted as the canvas measured it, not as `.notdef` boxes (see
|
|
622
|
+
* `fallbackSpaces.ts`). A missing space is the face's space glyph — text
|
|
623
|
+
* extraction still finds a space there — moved to the browser's advance
|
|
624
|
+
* for it; an invisible character is not drawn.
|
|
625
|
+
*/
|
|
480
626
|
function fallbackRun(font, face, pieces) {
|
|
481
627
|
const toText = 1000 / face.unitsPerEm;
|
|
482
628
|
const spaceGlyph = face.hasGlyphForCodePoint(0x20) ? face.glyphForCodePoint(0x20) : undefined;
|
|
@@ -485,7 +631,11 @@ function fallbackRun(font, face, pieces) {
|
|
|
485
631
|
for (const piece of pieces) {
|
|
486
632
|
if ('space' in piece) {
|
|
487
633
|
if (spaceGlyph) {
|
|
488
|
-
|
|
634
|
+
// The face's space glyph, read as a space whatever the font's map
|
|
635
|
+
// gives it (a no-break space set before any space, #755).
|
|
636
|
+
const space = font.encodeText(' ');
|
|
637
|
+
for (const part of shapedRun(font, ' ', space)?.parts ?? [space.asString()])
|
|
638
|
+
pushPart(parts, part);
|
|
489
639
|
pushPart(parts, tjNumber((spaceGlyph.advanceWidth - piece.space) * toText));
|
|
490
640
|
widths += spaceGlyph.advanceWidth * toText;
|
|
491
641
|
}
|
|
@@ -502,24 +652,6 @@ function fallbackRun(font, face, pieces) {
|
|
|
502
652
|
}
|
|
503
653
|
return shownRunOf(parts, widths);
|
|
504
654
|
}
|
|
505
|
-
/**
|
|
506
|
-
* The show-text operator of a text holding a space the face has no glyph
|
|
507
|
-
* for (a narrow no-break space, a figure space…) or an invisible character
|
|
508
|
-
* (a word joiner): painted as the canvas measured it, not as `.notdef`
|
|
509
|
-
* boxes (see `fallbackSpaces.ts`). A missing space is the face's space
|
|
510
|
-
* glyph — text extraction still finds a space there — moved to the
|
|
511
|
-
* browser's advance for it; an invisible character is not drawn. Undefined
|
|
512
|
-
* for text that needs none of this.
|
|
513
|
-
*/
|
|
514
|
-
function fallbackOperator(font, text) {
|
|
515
|
-
const shaping = shapingFace(font);
|
|
516
|
-
if (!shaping)
|
|
517
|
-
return undefined;
|
|
518
|
-
const pieces = fallbackPieces(shaping.face, text);
|
|
519
|
-
if (!pieces)
|
|
520
|
-
return undefined;
|
|
521
|
-
return partsOperator(font, fallbackRun(font, shaping.face, pieces).parts);
|
|
522
|
-
}
|
|
523
655
|
const runsByFont = new WeakMap();
|
|
524
656
|
/** `text` as {@link showTextShaped} paints it, with the advance and glyph
|
|
525
657
|
* count it leaves (cached per font). Undefined when the font carries no
|
|
@@ -590,16 +722,21 @@ const MEASURED_TOLERANCE = 0.5;
|
|
|
590
722
|
* added after every glyph. Undefined when the font carries no shaper.
|
|
591
723
|
*/
|
|
592
724
|
export function measuredTextOperator(font, pieces, sizePx, trackingPx = 0) {
|
|
593
|
-
const shows = measuredTextShows(font, pieces, sizePx, trackingPx);
|
|
725
|
+
const shows = measuredTextShows(font, pieces, sizePx, trackingPx, false);
|
|
594
726
|
return shows && shows.length === 1 ? shows[0].op : undefined;
|
|
595
727
|
}
|
|
596
728
|
/**
|
|
597
729
|
* {@link measuredTextOperator} for a face of any number of files: the
|
|
598
730
|
* pieces cut into runs by file (see `faceFiles.ts`), one show-text
|
|
599
731
|
* operator per stretch set in the same file. The pen carries across the
|
|
600
|
-
* font switches, so every piece still starts where the layout put it.
|
|
732
|
+
* font switches, so every piece still starts where the layout put it. A
|
|
733
|
+
* glyph the font's `/ToUnicode` map reads as other text is shown in a span
|
|
734
|
+
* of its own between two of them ({@link glyphReads}).
|
|
601
735
|
*/
|
|
602
|
-
export function measuredTextShows(font, pieces, sizePx, trackingPx = 0
|
|
736
|
+
export function measuredTextShows(font, pieces, sizePx, trackingPx = 0,
|
|
737
|
+
/** False when the caller reads the text some other way: no glyph takes
|
|
738
|
+
* a span of its own (see {@link textShows}). */
|
|
739
|
+
read = true) {
|
|
603
740
|
if (!(sizePx > 0))
|
|
604
741
|
return undefined;
|
|
605
742
|
const groups = [];
|
|
@@ -619,7 +756,7 @@ export function measuredTextShows(font, pieces, sizePx, trackingPx = 0) {
|
|
|
619
756
|
groups.push(group);
|
|
620
757
|
}
|
|
621
758
|
for (const part of run.parts)
|
|
622
|
-
pushPart(group.parts, part);
|
|
759
|
+
pushPart(group.parts, read || typeof part !== 'object' ? part : part.hex);
|
|
623
760
|
advance += run.advance + run.glyphs * tracking;
|
|
624
761
|
}
|
|
625
762
|
ahead += advance - (piece.width / sizePx) * 1000;
|
|
@@ -635,7 +772,7 @@ export function measuredTextShows(font, pieces, sizePx, trackingPx = 0) {
|
|
|
635
772
|
}
|
|
636
773
|
if (groups.length === 0)
|
|
637
774
|
groups.push({ font, parts: [] });
|
|
638
|
-
return groups.
|
|
775
|
+
return groups.flatMap((g) => partsShows(g.font, g.parts));
|
|
639
776
|
}
|
|
640
777
|
const fontKeysByPage = new WeakMap();
|
|
641
778
|
export function fontKeyOn(page, font) {
|
|
@@ -677,7 +814,7 @@ direction) {
|
|
|
677
814
|
// document loaded it (`shapedText.ts`).
|
|
678
815
|
if (complexPainter?.(ctx, text, xPx, baselinePx, font, sizePx, color, outline, actualText, direction))
|
|
679
816
|
return;
|
|
680
|
-
pushTextObject(ctx, textShows(font, text), xPx, baselinePx, font, sizePx, color, outline, actualText);
|
|
817
|
+
pushTextObject(ctx, textShows(font, text, actualText === undefined && !ctx.readSpans), xPx, baselinePx, font, sizePx, color, outline, actualText);
|
|
681
818
|
}
|
|
682
819
|
finally {
|
|
683
820
|
ctx.runAdvancePx = outer;
|
|
@@ -722,7 +859,7 @@ export function drawMeasuredTextPx(ctx, pieces, xPx, baselinePx, font, sizePx, c
|
|
|
722
859
|
endActualTextSpan(ctx, { font, text: pieces[0]?.text ?? '', sizePx, xPx, baselinePx });
|
|
723
860
|
return true;
|
|
724
861
|
}
|
|
725
|
-
const shows = measuredTextShows(font, pieces, sizePx, trackingPx);
|
|
862
|
+
const shows = measuredTextShows(font, pieces, sizePx, trackingPx, actualText === undefined && !ctx.readSpans);
|
|
726
863
|
if (!shows)
|
|
727
864
|
return false;
|
|
728
865
|
// Every piece starts where the layout put it: the run is as wide as the
|
|
@@ -800,6 +937,7 @@ export function withActualText(ctx, text, shows) {
|
|
|
800
937
|
*/
|
|
801
938
|
export function beginActualTextSpan(ctx, text, state) {
|
|
802
939
|
ctx.tags?.close();
|
|
940
|
+
ctx.readSpans = (ctx.readSpans ?? 0) + 1;
|
|
803
941
|
const props = ctx.page.doc.context.obj({ ActualText: PDFHexString.fromText(text) });
|
|
804
942
|
ctx.page.pushOperators(...lineTextState(ctx, state), PDFOperator.of(PDFOperatorNames.BeginMarkedContentSequence, [PDFName.of('Span'), props]));
|
|
805
943
|
}
|
|
@@ -870,6 +1008,7 @@ export function compressedMarkSpacingPx(font, seg, sizePx) {
|
|
|
870
1008
|
* state in force (see `lineTextState`). */
|
|
871
1009
|
export function endActualTextSpan(ctx, state) {
|
|
872
1010
|
ctx.tags?.close();
|
|
1011
|
+
ctx.readSpans = Math.max(0, (ctx.readSpans ?? 0) - 1);
|
|
873
1012
|
ctx.page.pushOperators(...lineTextState(ctx, state), PDFOperator.of(PDFOperatorNames.EndMarkedContent));
|
|
874
1013
|
}
|
|
875
1014
|
export function pushClipRect(ctx, xPx, yPx, wPx, hPx) {
|