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.
Files changed (100) hide show
  1. package/README.md +13 -1
  2. package/dist/__bench__/arabicShaping.bench.test.d.ts +2 -0
  3. package/dist/__bench__/arabicShaping.bench.test.d.ts.map +1 -0
  4. package/dist/__bench__/arabicShaping.bench.test.js +53 -0
  5. package/dist/__bench__/arabicShaping.bench.test.js.map +1 -0
  6. package/dist/__tests__/arabicShaping.test.d.ts +2 -0
  7. package/dist/__tests__/arabicShaping.test.d.ts.map +1 -0
  8. package/dist/__tests__/arabicShaping.test.js +261 -0
  9. package/dist/__tests__/arabicShaping.test.js.map +1 -0
  10. package/dist/__tests__/complexShaping.test.d.ts +2 -0
  11. package/dist/__tests__/complexShaping.test.d.ts.map +1 -0
  12. package/dist/__tests__/complexShaping.test.js +145 -0
  13. package/dist/__tests__/complexShaping.test.js.map +1 -0
  14. package/dist/__tests__/designTextRtl.test.d.ts +2 -0
  15. package/dist/__tests__/designTextRtl.test.d.ts.map +1 -0
  16. package/dist/__tests__/designTextRtl.test.js +136 -0
  17. package/dist/__tests__/designTextRtl.test.js.map +1 -0
  18. package/dist/__tests__/harfbuzz.test.d.ts +2 -0
  19. package/dist/__tests__/harfbuzz.test.d.ts.map +1 -0
  20. package/dist/__tests__/harfbuzz.test.js +103 -0
  21. package/dist/__tests__/harfbuzz.test.js.map +1 -0
  22. package/dist/__tests__/measuredLines.test.js +13 -5
  23. package/dist/__tests__/measuredLines.test.js.map +1 -1
  24. package/dist/__tests__/mirroredPdf.test.d.ts +2 -0
  25. package/dist/__tests__/mirroredPdf.test.d.ts.map +1 -0
  26. package/dist/__tests__/mirroredPdf.test.js +104 -0
  27. package/dist/__tests__/mirroredPdf.test.js.map +1 -0
  28. package/dist/__tests__/rtlPdf.test.d.ts +2 -0
  29. package/dist/__tests__/rtlPdf.test.d.ts.map +1 -0
  30. package/dist/__tests__/rtlPdf.test.js +312 -0
  31. package/dist/__tests__/rtlPdf.test.js.map +1 -0
  32. package/dist/__tests__/verticalText.test.js +4 -4
  33. package/dist/__tests__/verticalText.test.js.map +1 -1
  34. package/dist/complexShaping.d.ts +113 -0
  35. package/dist/complexShaping.d.ts.map +1 -0
  36. package/dist/complexShaping.js +188 -0
  37. package/dist/complexShaping.js.map +1 -0
  38. package/dist/faceFiles.d.ts +9 -1
  39. package/dist/faceFiles.d.ts.map +1 -1
  40. package/dist/faceFiles.js +47 -5
  41. package/dist/faceFiles.js.map +1 -1
  42. package/dist/harfbuzz.d.ts +119 -0
  43. package/dist/harfbuzz.d.ts.map +1 -0
  44. package/dist/harfbuzz.js +280 -0
  45. package/dist/harfbuzz.js.map +1 -0
  46. package/dist/harfbuzz.wasm +0 -0
  47. package/dist/index.d.ts +2 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/pdf-backend/blockRender.d.ts.map +1 -1
  51. package/dist/pdf-backend/blockRender.js +113 -40
  52. package/dist/pdf-backend/blockRender.js.map +1 -1
  53. package/dist/pdf-backend/chip.d.ts.map +1 -1
  54. package/dist/pdf-backend/chip.js +11 -2
  55. package/dist/pdf-backend/chip.js.map +1 -1
  56. package/dist/pdf-backend/directedLine.d.ts +38 -0
  57. package/dist/pdf-backend/directedLine.d.ts.map +1 -0
  58. package/dist/pdf-backend/directedLine.js +103 -0
  59. package/dist/pdf-backend/directedLine.js.map +1 -0
  60. package/dist/pdf-backend/fontHelpers.d.ts.map +1 -1
  61. package/dist/pdf-backend/fontHelpers.js +6 -0
  62. package/dist/pdf-backend/fontHelpers.js.map +1 -1
  63. package/dist/pdf-backend/headerFooter.d.ts.map +1 -1
  64. package/dist/pdf-backend/headerFooter.js +11 -3
  65. package/dist/pdf-backend/headerFooter.js.map +1 -1
  66. package/dist/pdf-backend/index.d.ts +32 -3
  67. package/dist/pdf-backend/index.d.ts.map +1 -1
  68. package/dist/pdf-backend/index.js +40 -6
  69. package/dist/pdf-backend/index.js.map +1 -1
  70. package/dist/pdf-backend/links.d.ts +7 -2
  71. package/dist/pdf-backend/links.d.ts.map +1 -1
  72. package/dist/pdf-backend/links.js +9 -3
  73. package/dist/pdf-backend/links.js.map +1 -1
  74. package/dist/pdf-backend/outlines.js +2 -2
  75. package/dist/pdf-backend/outlines.js.map +1 -1
  76. package/dist/pdf-backend/primitives.d.ts +46 -2
  77. package/dist/pdf-backend/primitives.d.ts.map +1 -1
  78. package/dist/pdf-backend/primitives.js +67 -5
  79. package/dist/pdf-backend/primitives.js.map +1 -1
  80. package/dist/pdf-backend/renderResourceBlock.d.ts.map +1 -1
  81. package/dist/pdf-backend/renderResourceBlock.js +48 -14
  82. package/dist/pdf-backend/renderResourceBlock.js.map +1 -1
  83. package/dist/pdf-backend/rtlRun.d.ts +12 -0
  84. package/dist/pdf-backend/rtlRun.d.ts.map +1 -0
  85. package/dist/pdf-backend/rtlRun.js +31 -0
  86. package/dist/pdf-backend/rtlRun.js.map +1 -0
  87. package/dist/pdf-backend/shapedText.d.ts +122 -0
  88. package/dist/pdf-backend/shapedText.d.ts.map +1 -0
  89. package/dist/pdf-backend/shapedText.js +635 -0
  90. package/dist/pdf-backend/shapedText.js.map +1 -0
  91. package/dist/pdf-backend/svgVector.d.ts +9 -2
  92. package/dist/pdf-backend/svgVector.d.ts.map +1 -1
  93. package/dist/pdf-backend/svgVector.js +42 -18
  94. package/dist/pdf-backend/svgVector.js.map +1 -1
  95. package/dist/worker/client.d.ts.map +1 -1
  96. package/dist/worker/client.js +10 -1
  97. package/dist/worker/client.js.map +1 -1
  98. package/dist/worker/protocol.d.ts +5 -1
  99. package/dist/worker/protocol.d.ts.map +1 -1
  100. package/package.json +6 -5
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Text shaped with HarfBuzz, painted through glyph ids (issue #380).
3
+ *
4
+ * pdf-lib's own text path asks fontkit for the glyphs (`encodeText`). For
5
+ * a run HarfBuzz shapes (`complexShaping.ts`) the glyphs are registered
6
+ * with the font's subset here instead, as the vertical twins register
7
+ * theirs (`verticalFonts.ts`): the subset keeps every glyph a run shows and
8
+ * its `W` width, and the hex codes are the subset's ids (or the face's own,
9
+ * for a font embedded whole).
10
+ *
11
+ * Positions: a run is one `TJ` per stretch of glyphs at one height. Its
12
+ * numbers move the pen to each glyph's origin (`pen + xOffset`) and, after
13
+ * the last, to where HarfBuzz's advances end, so a run is exactly as wide
14
+ * as the layout measured it. A mark HarfBuzz raises or lowers (`yOffset`:
15
+ * a fatha on a shadda, a kasra under a dotted letter) is shown with the
16
+ * text rise (`Ts`) set to it, which moves no pen. Glyphs are shown left to
17
+ * right, a right-to-left run in visual order, as every right-to-left PDF
18
+ * shows them: readers put the line back in logical order from their
19
+ * positions.
20
+ *
21
+ * Reading the text back (`/ToUnicode`): clusters are graphemes, a letter
22
+ * with its marks. Each glyph newly added to the font is given the
23
+ * characters of its cluster it stands for ({@link clusterCodePoints}), and
24
+ * the font's map is written from them. That map is global to the font, so
25
+ * a glyph keeps the characters it was first given: a mirrored bracket
26
+ * shares its glyph with the other bracket, a contextual form can stand for
27
+ * other text elsewhere. A cluster whose glyphs do not read back as its own
28
+ * characters, a vocalised letter (readers set a raised or lowered mark on
29
+ * a line of its own, or after the next letter) and a cluster holding
30
+ * kashidas justification inserted are shown under an `/ActualText` span
31
+ * with the cluster's text as written, in logical order (PDF 1.7 §14.9.4).
32
+ * pdf.js 5 ignores the span and reads the glyphs; Poppler reads it, but
33
+ * turns a span of several characters around in a right-to-left line.
34
+ */
35
+ import { type Color, type PDFFont } from 'pdf-lib';
36
+ import { type PageCtx, type TextOutline, type TextShow } from './primitives';
37
+ /** How {@link drawShapedTextPx} sets a text. */
38
+ export interface ShapedTextOptions {
39
+ /** The text is one bidi run in this direction (a VDT segment flagged
40
+ * `rtl`, or one without it on a line that carries directions). Absent:
41
+ * the text is cut into runs first, by the engine's UAX #9
42
+ * (`resolveParagraph`, `lineRuns`). */
43
+ direction?: 'ltr' | 'rtl';
44
+ /** With no {@link direction}: the paragraph direction the runs are
45
+ * ordered in; by default the text's first strong letter's. */
46
+ base?: 'ltr' | 'rtl';
47
+ /** BCP 47 language of the text, for the font's `locl` forms. */
48
+ language?: string;
49
+ /** What copying and text extraction read for the glyphs: by default
50
+ * each glyph's characters, with the clusters that cannot be read so (see
51
+ * the module comment) under spans of their own; the whole text under one
52
+ * span when given (the line's repeated hyphen left out); null for no
53
+ * span at all. */
54
+ actualText?: string | null;
55
+ /** Leave tatweels (U+0640) out of the text read: justification inserted
56
+ * them. `true`: every one; a number: that many, the ones kashida
57
+ * justification inserted into a word (`VDTLineSegment.kashida`), so a
58
+ * tatweel the author typed stays in the text read. */
59
+ hideTatweel?: boolean | number;
60
+ outline?: TextOutline;
61
+ }
62
+ /**
63
+ * Paint `text` shaped by HarfBuzz from `xPx` on the baseline, in one text
64
+ * object: each bidi run in its direction, the runs left to right, each run
65
+ * cut by the file of the face that has its characters. Character spacing
66
+ * is turned off for a text with joining letters, whose joins it would
67
+ * break. On a mirrored page the text object is turned back about the box
68
+ * HarfBuzz's own advances give the text (`pushTextObject`'s `advancePx`),
69
+ * so it lands exactly where it was measured. Returns false, painting
70
+ * nothing, when HarfBuzz is not loaded: the caller paints the text the
71
+ * fontkit way.
72
+ */
73
+ export declare function drawShapedTextPx(ctx: PageCtx, text: string, xPx: number, baselinePx: number, font: PDFFont, sizePx: number, color: Color, options?: ShapedTextOptions): boolean;
74
+ /**
75
+ * Text of an SVG drawing (`svgVector.ts`) shaped by HarfBuzz: the show
76
+ * operators of one text object in `font`'s face at `size` (the drawing's
77
+ * units), and its advance in those units. No `/ActualText` spans: the
78
+ * drawing is a figure, read through its alternate text. Null when
79
+ * HarfBuzz is not loaded.
80
+ */
81
+ export declare function shapedSvgText(font: PDFFont, text: string, size: number, base?: 'ltr' | 'rtl'): {
82
+ shows: TextShow[];
83
+ advance: number;
84
+ } | null;
85
+ /** A styled run of a word painted by {@link drawStyledWordPx}: `[start,
86
+ * end)` in the word's text, and the face and colour it is set in. */
87
+ export interface StyledWordPart {
88
+ start: number;
89
+ end: number;
90
+ font: PDFFont;
91
+ color: Color;
92
+ }
93
+ /**
94
+ * Paint a word set in several styles (`VDTLineSegment.runs`, `كتا**ب**`)
95
+ * as one shaped run, so its letters keep the forms they take in the whole
96
+ * word, each glyph in the style of the run its character belongs to.
97
+ *
98
+ * The word is shaped once in its own face (`font`, the style it was
99
+ * measured in): that shaping gives every glyph's place and the word's
100
+ * width. Walking its glyphs left to right, each stretch of glyphs of one
101
+ * run is shown in that run's colour:
102
+ * - in the same face, the stretch's own glyphs, where they are;
103
+ * - in another face (a bold letter in a regular word), the word is shaped
104
+ * whole in that face too, so the letters at the cut take the joining
105
+ * forms of the whole word, and the glyphs of the stretch's characters are
106
+ * shown over the box the stretch has in the word's own shaping,
107
+ * horizontally scaled (`Tz`) to its width: the joins at both ends meet
108
+ * their neighbours, and the word keeps the width it was measured with.
109
+ * A stretch of vowel signs alone (no advance) keeps the word's face and
110
+ * takes only the colour, since a mark's place depends on its letter's
111
+ * glyph.
112
+ * A vowel sign in a run of its own (a red fatha) is a glyph of its own,
113
+ * so it is coloured apart from its letter. All the stretches are one text
114
+ * object, glyphs left to right (each stretch placed with `Td`), so the
115
+ * word reads back as one, as an unstyled word does.
116
+ *
117
+ * Returns false, painting nothing, when HarfBuzz is not loaded or a face
118
+ * sets the word from several files: the caller then paints the word in
119
+ * one style.
120
+ */
121
+ export declare function drawStyledWordPx(ctx: PageCtx, text: string, xPx: number, baselinePx: number, font: PDFFont, sizePx: number, color: Color, parts: readonly StyledWordPart[], options?: Pick<ShapedTextOptions, 'direction' | 'language' | 'hideTatweel' | 'actualText'>): boolean;
122
+ //# sourceMappingURL=shapedText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapedText.d.ts","sourceRoot":"","sources":["../../src/pdf-backend/shapedText.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAA+J,KAAK,KAAK,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAKhN,OAAO,EAAoE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAoa/I,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC;;;4CAGwC;IACxC,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B;mEAC+D;IAC/D,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;uBAImB;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;2DAGuD;IACvD,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAwGD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAgBT;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG;IAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAG5I;AAED;sEACsE;AACtE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;CACd;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,OAAO,GAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,YAAY,CAAM,GAC7F,OAAO,CAyET"}