pdf-lite 1.4.0 → 1.5.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 (94) hide show
  1. package/dist/acroform/acroform.d.ts +3 -3
  2. package/dist/acroform/acroform.js +2 -2
  3. package/dist/acroform/appearance/index.d.ts +4 -4
  4. package/dist/acroform/appearance/index.js +4 -4
  5. package/dist/acroform/appearance/{PdfAppearanceStream.d.ts → pdf-appearance-stream.d.ts} +9 -3
  6. package/dist/acroform/appearance/{PdfAppearanceStream.js → pdf-appearance-stream.js} +14 -5
  7. package/dist/acroform/appearance/{PdfButtonAppearanceStream.d.ts → pdf-button-appearance-stream.d.ts} +3 -2
  8. package/dist/acroform/appearance/pdf-button-appearance-stream.js +54 -0
  9. package/dist/acroform/appearance/pdf-choice-appearance-stream.d.ts +22 -0
  10. package/dist/acroform/appearance/pdf-choice-appearance-stream.js +75 -0
  11. package/dist/acroform/appearance/pdf-graphics.d.ts +51 -0
  12. package/dist/acroform/appearance/pdf-graphics.js +239 -0
  13. package/dist/acroform/appearance/{PdfTextAppearanceStream.d.ts → pdf-text-appearance-stream.d.ts} +7 -2
  14. package/dist/acroform/appearance/pdf-text-appearance-stream.js +104 -0
  15. package/dist/acroform/fields/index.d.ts +7 -7
  16. package/dist/acroform/fields/index.js +7 -7
  17. package/dist/acroform/fields/pdf-button-form-field.d.ts +23 -0
  18. package/dist/acroform/fields/pdf-button-form-field.js +102 -0
  19. package/dist/acroform/fields/pdf-choice-form-field.d.ts +18 -0
  20. package/dist/acroform/fields/pdf-choice-form-field.js +131 -0
  21. package/dist/acroform/fields/{PdfFormFieldFlags.d.ts → pdf-form-field-flags.d.ts} +5 -6
  22. package/dist/acroform/fields/{PdfFormFieldFlags.js → pdf-form-field-flags.js} +12 -18
  23. package/dist/acroform/fields/{PdfFormField.d.ts → pdf-form-field.d.ts} +15 -11
  24. package/dist/acroform/fields/{PdfFormField.js → pdf-form-field.js} +68 -134
  25. package/dist/acroform/fields/{PdfSignatureFormField.d.ts → pdf-signature-form-field.d.ts} +1 -1
  26. package/dist/acroform/fields/{PdfSignatureFormField.js → pdf-signature-form-field.js} +1 -1
  27. package/dist/acroform/fields/{PdfTextFormField.d.ts → pdf-text-form-field.d.ts} +1 -1
  28. package/dist/acroform/fields/pdf-text-form-field.js +77 -0
  29. package/dist/acroform/fields/types.d.ts +5 -0
  30. package/dist/acroform/index.d.ts +2 -2
  31. package/dist/acroform/index.js +2 -2
  32. package/dist/acroform/manager.d.ts +7 -3
  33. package/dist/acroform/manager.js +14 -8
  34. package/dist/acroform/{PdfAcroForm.d.ts → pdf-acro-form.d.ts} +12 -6
  35. package/dist/acroform/{PdfAcroForm.js → pdf-acro-form.js} +43 -29
  36. package/dist/acroform/{PdfFontEncodingCache.d.ts → pdf-font-encoding-cache.d.ts} +11 -0
  37. package/dist/acroform/pdf-font-encoding-cache.js +188 -0
  38. package/dist/acroform/xfa/index.d.ts +3 -3
  39. package/dist/acroform/xfa/index.js +2 -2
  40. package/dist/acroform/xfa/{PdfXfaForm.d.ts → pdf-xfa-form.d.ts} +1 -2
  41. package/dist/acroform/xfa/{PdfXfaForm.js → pdf-xfa-form.js} +2 -10
  42. package/dist/annotations/index.d.ts +4 -4
  43. package/dist/annotations/index.js +4 -4
  44. package/dist/annotations/{PdfAnnotationFlags.d.ts → pdf-annotation-flags.d.ts} +3 -4
  45. package/dist/annotations/{PdfAnnotationFlags.js → pdf-annotation-flags.js} +5 -6
  46. package/dist/annotations/{PdfAnnotation.d.ts → pdf-annotation.d.ts} +25 -4
  47. package/dist/annotations/{PdfAnnotation.js → pdf-annotation.js} +4 -3
  48. package/dist/annotations/{PdfWidgetAnnotation.d.ts → pdf-widget-annotation.d.ts} +1 -1
  49. package/dist/annotations/{PdfWidgetAnnotation.js → pdf-widget-annotation.js} +1 -1
  50. package/dist/core/objects/pdf-stream.d.ts +1 -0
  51. package/dist/core/objects/pdf-stream.js +6 -2
  52. package/dist/core/parser/incremental-parser.d.ts +0 -13
  53. package/dist/core/parser/incremental-parser.js +1 -18
  54. package/dist/core/streams/object-stream.d.ts +1 -1
  55. package/dist/core/streams/object-stream.js +1 -1
  56. package/dist/errors.d.ts +22 -0
  57. package/dist/errors.js +24 -0
  58. package/dist/fonts/index.d.ts +1 -1
  59. package/dist/fonts/index.js +1 -1
  60. package/dist/fonts/pdf-font.d.ts +64 -7
  61. package/dist/fonts/pdf-font.js +188 -8
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.js +1 -0
  64. package/dist/pdf/index.d.ts +0 -1
  65. package/dist/pdf/index.js +0 -1
  66. package/dist/pdf/pdf-document.d.ts +2 -1
  67. package/dist/pdf/pdf-document.js +15 -11
  68. package/dist/utils/encodePdfText.d.ts +17 -0
  69. package/dist/utils/encodePdfText.js +61 -0
  70. package/dist/utils/index.d.ts +1 -1
  71. package/dist/utils/index.js +1 -1
  72. package/package.json +1 -1
  73. package/dist/acroform/PdfFontEncodingCache.js +0 -75
  74. package/dist/acroform/appearance/PdfButtonAppearanceStream.js +0 -54
  75. package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +0 -15
  76. package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +0 -48
  77. package/dist/acroform/appearance/PdfTextAppearanceStream.js +0 -75
  78. package/dist/acroform/fields/PdfButtonFormField.d.ts +0 -9
  79. package/dist/acroform/fields/PdfButtonFormField.js +0 -35
  80. package/dist/acroform/fields/PdfChoiceFormField.d.ts +0 -9
  81. package/dist/acroform/fields/PdfChoiceFormField.js +0 -46
  82. package/dist/acroform/fields/PdfTextFormField.js +0 -52
  83. package/dist/pdf/errors.d.ts +0 -6
  84. package/dist/pdf/errors.js +0 -6
  85. /package/dist/acroform/fields/{PdfDefaultAppearance.d.ts → pdf-default-appearance.d.ts} +0 -0
  86. /package/dist/acroform/fields/{PdfDefaultAppearance.js → pdf-default-appearance.js} +0 -0
  87. /package/dist/acroform/xfa/{PdfXfaData.d.ts → pdf-xfa-data.d.ts} +0 -0
  88. /package/dist/acroform/xfa/{PdfXfaData.js → pdf-xfa-data.js} +0 -0
  89. /package/dist/annotations/{PdfAnnotationWriter.d.ts → pdf-annotation-writer.d.ts} +0 -0
  90. /package/dist/annotations/{PdfAnnotationWriter.js → pdf-annotation-writer.js} +0 -0
  91. /package/dist/fonts/{font-manager.d.ts → manager.d.ts} +0 -0
  92. /package/dist/fonts/{font-manager.js → manager.js} +0 -0
  93. /package/dist/utils/{IterableReadableStream.d.ts → iterable-readable-stream.d.ts} +0 -0
  94. /package/dist/utils/{IterableReadableStream.js → iterable-readable-stream.js} +0 -0
@@ -1,4 +1,4 @@
1
- import { IterableReadableStream } from '../../utils/IterableReadableStream.js';
1
+ import { IterableReadableStream } from '../../utils/iterable-readable-stream.js';
2
2
  import { pdfDecoderAsync } from '../generators.js';
3
3
  export class PdfObjectStream extends IterableReadableStream {
4
4
  constructor(input) {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Error thrown when the parser needs more input to continue parsing.
3
+ */
4
+ export declare class NoMoreTokensError extends Error {
5
+ }
6
+ /**
7
+ * Error thrown when the end of file has been reached and no more input is available.
8
+ */
9
+ export declare class EofReachedError extends Error {
10
+ }
11
+ /**
12
+ * Error thrown when an unexpected token is encountered during parsing.
13
+ */
14
+ export declare class UnexpectedTokenError extends Error {
15
+ constructor(expected: string, actual: string | null);
16
+ }
17
+ /**
18
+ * Error thrown when attempting to access a compressed object
19
+ * that requires decompression from an object stream.
20
+ */
21
+ export declare class FoundCompressedObjectError extends Error {
22
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Error thrown when the parser needs more input to continue parsing.
3
+ */
4
+ export class NoMoreTokensError extends Error {
5
+ }
6
+ /**
7
+ * Error thrown when the end of file has been reached and no more input is available.
8
+ */
9
+ export class EofReachedError extends Error {
10
+ }
11
+ /**
12
+ * Error thrown when an unexpected token is encountered during parsing.
13
+ */
14
+ export class UnexpectedTokenError extends Error {
15
+ constructor(expected, actual) {
16
+ super(`Unexpected token: expected ${expected}, but got ${actual === null ? 'EOF' : actual}`);
17
+ }
18
+ }
19
+ /**
20
+ * Error thrown when attempting to access a compressed object
21
+ * that requires decompression from an object stream.
22
+ */
23
+ export class FoundCompressedObjectError extends Error {
24
+ }
@@ -1,4 +1,4 @@
1
1
  export * from './types.js';
2
- export * from './font-manager.js';
2
+ export * from './manager.js';
3
3
  export * from './pdf-font.js';
4
4
  export * from './parsers/index.js';
@@ -1,4 +1,4 @@
1
1
  export * from './types.js';
2
- export * from './font-manager.js';
2
+ export * from './manager.js';
3
3
  export * from './pdf-font.js';
4
4
  export * from './parsers/index.js';
@@ -4,9 +4,10 @@ import { PdfName } from '../core/objects/pdf-name.js';
4
4
  import { PdfNumber } from '../core/objects/pdf-number.js';
5
5
  import { PdfArray } from '../core/objects/pdf-array.js';
6
6
  import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
7
- import type { PdfFontManager } from './font-manager.js';
7
+ import type { PdfFontManager } from './manager.js';
8
8
  import type { FontDescriptor, UnicodeFontDescriptor, FontParser } from './types.js';
9
9
  import type { ByteArray } from '../types.js';
10
+ type PdfStandardFontName = 'Helvetica' | 'Helvetica-Bold' | 'Helvetica-Oblique' | 'Helvetica-BoldOblique' | 'Times-Roman' | 'Times-Bold' | 'Times-Italic' | 'Times-BoldItalic' | 'Courier' | 'Courier-Bold' | 'Courier-Oblique' | 'Courier-BoldOblique' | 'Symbol' | 'ZapfDingbats';
10
11
  /**
11
12
  * Represents an embedded font in a PDF document.
12
13
  * Extends PdfDictionary to provide both font metadata and PDF dictionary structure.
@@ -38,11 +39,6 @@ export declare class PdfFont extends PdfDictionary<{
38
39
  * Includes FontDescriptor, FontFile2, CIDFont, ToUnicode, etc.
39
40
  */
40
41
  protected auxiliaryObjects: PdfIndirectObject[];
41
- /**
42
- * @internal
43
- * Reference to the font manager that created this font.
44
- */
45
- private manager?;
46
42
  /**
47
43
  * @internal
48
44
  * Font descriptor with metrics and properties.
@@ -53,6 +49,7 @@ export declare class PdfFont extends PdfDictionary<{
53
49
  * Original font file bytes.
54
50
  */
55
51
  private _fontData?;
52
+ constructor(fontName: string);
56
53
  constructor(options: {
57
54
  dict?: PdfDictionary;
58
55
  fontName?: string;
@@ -109,6 +106,39 @@ export declare class PdfFont extends PdfDictionary<{
109
106
  * Sets the character widths array.
110
107
  */
111
108
  set widths(values: number[] | undefined);
109
+ /**
110
+ * Gets the raw character width (in 1000-unit em square) for a character code.
111
+ * Returns null if the character is not in the font's width table.
112
+ *
113
+ * @param charCode - The character code to get the width for
114
+ * @returns The raw character width or null if not found
115
+ */
116
+ getRawCharacterWidth(charCode: number): number | null;
117
+ /**
118
+ * Gets the character width scaled to the specified font size.
119
+ * Returns null if the character is not in the font's width table.
120
+ *
121
+ * @param charCode - The character code to get the width for
122
+ * @param fontSize - The font size to scale to
123
+ * @returns The scaled character width or null if not found
124
+ */
125
+ getCharacterWidth(charCode: number, fontSize: number): number | null;
126
+ /**
127
+ * Checks if the font has width data for a character code.
128
+ *
129
+ * @param charCode - The character code to check
130
+ * @returns True if width data is available, false otherwise
131
+ */
132
+ hasCharacterWidth(charCode: number): boolean;
133
+ /**
134
+ * Gets character widths for all characters in a string.
135
+ * Returns null for characters not in the font's width table.
136
+ *
137
+ * @param text - The text to get character widths for
138
+ * @param fontSize - The font size to scale to
139
+ * @returns Array of character widths (null for missing characters)
140
+ */
141
+ getCharacterWidthsForString(text: string, fontSize: number): (number | null)[];
112
142
  /**
113
143
  * Returns the resource name for string coercion.
114
144
  * This enables using PdfFont objects in template literals like:
@@ -150,9 +180,35 @@ export declare class PdfFont extends PdfDictionary<{
150
180
  * These fonts don't require font data as they're built into PDF viewers.
151
181
  *
152
182
  * @param fontName - One of the 14 standard PDF fonts
183
+ * @param widths - Optional AFM widths array (1/1000 em units) for chars 32–126
153
184
  * @returns A PdfFont instance ready to be written to the PDF
154
185
  */
155
- static fromStandardFont(fontName: 'Helvetica' | 'Helvetica-Bold' | 'Helvetica-Oblique' | 'Helvetica-BoldOblique' | 'Times-Roman' | 'Times-Bold' | 'Times-Italic' | 'Times-BoldItalic' | 'Courier' | 'Courier-Bold' | 'Courier-Oblique' | 'Courier-BoldOblique' | 'Symbol' | 'ZapfDingbats'): PdfFont;
186
+ static fromStandardFont(fontName: PdfStandardFontName, widths?: number[]): PdfFont;
187
+ private static readonly _HELVETICA_WIDTHS;
188
+ private static readonly _HELVETICA_BOLD_WIDTHS;
189
+ private static readonly _TIMES_ROMAN_WIDTHS;
190
+ private static readonly _TIMES_BOLD_WIDTHS;
191
+ private static readonly _TIMES_ITALIC_WIDTHS;
192
+ private static readonly _TIMES_BOLD_ITALIC_WIDTHS;
193
+ static readonly HELVETICA: PdfFont;
194
+ static readonly HELVETICA_BOLD: PdfFont;
195
+ static readonly HELVETICA_OBLIQUE: PdfFont;
196
+ static readonly HELVETICA_BOLD_OBLIQUE: PdfFont;
197
+ static readonly TIMES_ROMAN: PdfFont;
198
+ static readonly TIMES_BOLD: PdfFont;
199
+ static readonly TIMES_ITALIC: PdfFont;
200
+ static readonly TIMES_BOLD_ITALIC: PdfFont;
201
+ static readonly COURIER: PdfFont;
202
+ static readonly COURIER_BOLD: PdfFont;
203
+ static readonly COURIER_OBLIQUE: PdfFont;
204
+ static readonly COURIER_BOLD_OBLIQUE: PdfFont;
205
+ static readonly SYMBOL: PdfFont;
206
+ static readonly ZAPF_DINGBATS: PdfFont;
207
+ private static readonly BY_BASE_FONT;
208
+ /**
209
+ * Returns the static PdfFont instance for a standard font name, or null if not found.
210
+ */
211
+ static getStandardFont(fontName: string): PdfFont | null;
156
212
  /**
157
213
  * Creates a TrueType font from font file data.
158
214
  * Uses WinAnsiEncoding for standard 8-bit character support.
@@ -183,3 +239,4 @@ export declare class PdfFont extends PdfDictionary<{
183
239
  */
184
240
  private static buildCIDWidthArray;
185
241
  }
242
+ export {};
@@ -27,11 +27,6 @@ export class PdfFont extends PdfDictionary {
27
27
  * Includes FontDescriptor, FontFile2, CIDFont, ToUnicode, etc.
28
28
  */
29
29
  auxiliaryObjects = [];
30
- /**
31
- * @internal
32
- * Reference to the font manager that created this font.
33
- */
34
- manager;
35
30
  /**
36
31
  * @internal
37
32
  * Font descriptor with metrics and properties.
@@ -42,15 +37,22 @@ export class PdfFont extends PdfDictionary {
42
37
  * Original font file bytes.
43
38
  */
44
39
  _fontData;
45
- constructor(options) {
40
+ constructor(optionsOrFontName) {
46
41
  super();
42
+ // Handle string parameter (simple fontName)
43
+ if (typeof optionsOrFontName === 'string') {
44
+ this.fontName = optionsOrFontName;
45
+ this.resourceName = optionsOrFontName;
46
+ return;
47
+ }
48
+ // Handle options object (existing behavior)
49
+ const options = optionsOrFontName;
47
50
  if (options.dict) {
48
51
  this.copyFrom(options.dict);
49
52
  }
50
53
  this.fontName = options.fontName;
51
54
  this.resourceName = options.resourceName ?? '';
52
55
  this.encoding = options.encoding;
53
- this.manager = options.manager;
54
56
  this.container = options.container;
55
57
  this._descriptor = options.descriptor;
56
58
  this._fontData = options.fontData;
@@ -169,6 +171,60 @@ export class PdfFont extends PdfDictionary {
169
171
  this.delete('Widths');
170
172
  }
171
173
  }
174
+ /**
175
+ * Gets the raw character width (in 1000-unit em square) for a character code.
176
+ * Returns null if the character is not in the font's width table.
177
+ *
178
+ * @param charCode - The character code to get the width for
179
+ * @returns The raw character width or null if not found
180
+ */
181
+ getRawCharacterWidth(charCode) {
182
+ if (this.widths === undefined || this.firstChar === undefined) {
183
+ return null;
184
+ }
185
+ const widthIndex = charCode - this.firstChar;
186
+ if (widthIndex >= 0 && widthIndex < this.widths.length) {
187
+ return this.widths[widthIndex];
188
+ }
189
+ return null;
190
+ }
191
+ /**
192
+ * Gets the character width scaled to the specified font size.
193
+ * Returns null if the character is not in the font's width table.
194
+ *
195
+ * @param charCode - The character code to get the width for
196
+ * @param fontSize - The font size to scale to
197
+ * @returns The scaled character width or null if not found
198
+ */
199
+ getCharacterWidth(charCode, fontSize) {
200
+ const rawWidth = this.getRawCharacterWidth(charCode);
201
+ return rawWidth !== null ? (rawWidth * fontSize) / 1000 : null;
202
+ }
203
+ /**
204
+ * Checks if the font has width data for a character code.
205
+ *
206
+ * @param charCode - The character code to check
207
+ * @returns True if width data is available, false otherwise
208
+ */
209
+ hasCharacterWidth(charCode) {
210
+ return this.getRawCharacterWidth(charCode) !== null;
211
+ }
212
+ /**
213
+ * Gets character widths for all characters in a string.
214
+ * Returns null for characters not in the font's width table.
215
+ *
216
+ * @param text - The text to get character widths for
217
+ * @param fontSize - The font size to scale to
218
+ * @returns Array of character widths (null for missing characters)
219
+ */
220
+ getCharacterWidthsForString(text, fontSize) {
221
+ const widths = [];
222
+ for (const char of text) {
223
+ const charCode = char.charCodeAt(0);
224
+ widths.push(this.getCharacterWidth(charCode, fontSize));
225
+ }
226
+ return widths;
227
+ }
172
228
  /**
173
229
  * Returns the resource name for string coercion.
174
230
  * This enables using PdfFont objects in template literals like:
@@ -235,16 +291,140 @@ export class PdfFont extends PdfDictionary {
235
291
  * These fonts don't require font data as they're built into PDF viewers.
236
292
  *
237
293
  * @param fontName - One of the 14 standard PDF fonts
294
+ * @param widths - Optional AFM widths array (1/1000 em units) for chars 32–126
238
295
  * @returns A PdfFont instance ready to be written to the PDF
239
296
  */
240
- static fromStandardFont(fontName) {
297
+ static fromStandardFont(fontName, widths) {
241
298
  const font = new PdfFont({ fontName });
242
299
  // Build Type1 font dictionary
243
300
  font.set('Type', new PdfName('Font'));
244
301
  font.set('Subtype', new PdfName('Type1'));
245
302
  font.set('BaseFont', new PdfName(fontName));
303
+ if (widths) {
304
+ font.firstChar = 32;
305
+ font.lastChar = 32 + widths.length - 1;
306
+ font.widths = widths;
307
+ }
246
308
  return font;
247
309
  }
310
+ // Helvetica AFM widths, chars 32–126 (95 values, 1/1000 em units)
311
+ static _HELVETICA_WIDTHS = [
312
+ 278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333,
313
+ 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278,
314
+ 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278,
315
+ 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944,
316
+ 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556,
317
+ 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500,
318
+ 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584,
319
+ ];
320
+ // Helvetica-Bold AFM widths, chars 32–126
321
+ static _HELVETICA_BOLD_WIDTHS = [
322
+ 278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333,
323
+ 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333,
324
+ 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278,
325
+ 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944,
326
+ 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556,
327
+ 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556,
328
+ 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584,
329
+ ];
330
+ // Times-Roman AFM widths, chars 32–126
331
+ static _TIMES_ROMAN_WIDTHS = [
332
+ 250, 333, 408, 500, 500, 833, 778, 180, 333, 333, 500, 564, 250, 333,
333
+ 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278,
334
+ 564, 564, 564, 444, 921, 722, 667, 667, 722, 611, 556, 722, 722, 333,
335
+ 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944,
336
+ 722, 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444,
337
+ 333, 500, 500, 278, 278, 500, 278, 778, 500, 500, 500, 500, 333, 389,
338
+ 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541,
339
+ ];
340
+ // Times-Bold AFM widths, chars 32–126
341
+ static _TIMES_BOLD_WIDTHS = [
342
+ 250, 333, 555, 500, 500, 1000, 833, 278, 333, 333, 500, 570, 250, 333,
343
+ 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333,
344
+ 570, 570, 570, 500, 930, 722, 667, 722, 722, 667, 611, 778, 778, 389,
345
+ 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000,
346
+ 722, 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444,
347
+ 333, 500, 556, 278, 333, 556, 278, 833, 556, 500, 556, 556, 444, 389,
348
+ 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520,
349
+ ];
350
+ // Times-Italic AFM widths, chars 32–126
351
+ static _TIMES_ITALIC_WIDTHS = [
352
+ 250, 333, 420, 500, 500, 833, 778, 214, 333, 333, 500, 675, 250, 333,
353
+ 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333,
354
+ 675, 675, 675, 500, 920, 611, 611, 667, 722, 611, 611, 722, 722, 333,
355
+ 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833,
356
+ 611, 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444,
357
+ 278, 500, 500, 278, 278, 444, 278, 722, 500, 500, 500, 500, 389, 389,
358
+ 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541,
359
+ ];
360
+ // Times-BoldItalic AFM widths, chars 32–126
361
+ static _TIMES_BOLD_ITALIC_WIDTHS = [
362
+ 250, 389, 555, 500, 500, 833, 778, 278, 333, 333, 500, 570, 250, 333,
363
+ 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333,
364
+ 570, 570, 570, 500, 832, 667, 667, 667, 722, 667, 667, 722, 778, 389,
365
+ 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889,
366
+ 667, 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444,
367
+ 333, 500, 556, 278, 278, 500, 278, 778, 556, 500, 500, 500, 389, 389,
368
+ 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570,
369
+ ];
370
+ static HELVETICA = PdfFont.fromStandardFont('Helvetica', [
371
+ ...PdfFont._HELVETICA_WIDTHS,
372
+ ]);
373
+ static HELVETICA_BOLD = PdfFont.fromStandardFont('Helvetica-Bold', [...PdfFont._HELVETICA_BOLD_WIDTHS]);
374
+ static HELVETICA_OBLIQUE = PdfFont.fromStandardFont('Helvetica-Oblique', [...PdfFont._HELVETICA_WIDTHS]);
375
+ static HELVETICA_BOLD_OBLIQUE = PdfFont.fromStandardFont('Helvetica-BoldOblique', [...PdfFont._HELVETICA_BOLD_WIDTHS]);
376
+ static TIMES_ROMAN = PdfFont.fromStandardFont('Times-Roman', [
377
+ ...PdfFont._TIMES_ROMAN_WIDTHS,
378
+ ]);
379
+ static TIMES_BOLD = PdfFont.fromStandardFont('Times-Bold', [
380
+ ...PdfFont._TIMES_BOLD_WIDTHS,
381
+ ]);
382
+ static TIMES_ITALIC = PdfFont.fromStandardFont('Times-Italic', [
383
+ ...PdfFont._TIMES_ITALIC_WIDTHS,
384
+ ]);
385
+ static TIMES_BOLD_ITALIC = PdfFont.fromStandardFont('Times-BoldItalic', [...PdfFont._TIMES_BOLD_ITALIC_WIDTHS]);
386
+ static COURIER = PdfFont.fromStandardFont('Courier', Array(95).fill(600));
387
+ static COURIER_BOLD = PdfFont.fromStandardFont('Courier-Bold', Array(95).fill(600));
388
+ static COURIER_OBLIQUE = PdfFont.fromStandardFont('Courier-Oblique', Array(95).fill(600));
389
+ static COURIER_BOLD_OBLIQUE = PdfFont.fromStandardFont('Courier-BoldOblique', Array(95).fill(600));
390
+ static SYMBOL = PdfFont.fromStandardFont('Symbol');
391
+ static ZAPF_DINGBATS = PdfFont.fromStandardFont('ZapfDingbats');
392
+ static BY_BASE_FONT = new Map([
393
+ ['Helvetica', PdfFont.HELVETICA],
394
+ ['Helv', PdfFont.HELVETICA], // Alias for backward compatibility with old code using 'Helv'
395
+ ['Helvetica-Bold', PdfFont.HELVETICA_BOLD],
396
+ ['Helv-Bold', PdfFont.HELVETICA_BOLD], // Alias for backward compatibility with old code using 'Helv-Bold'
397
+ ['Helvetica-Oblique', PdfFont.HELVETICA_OBLIQUE],
398
+ ['Helv-Oblique', PdfFont.HELVETICA_OBLIQUE], // Alias for backward compatibility with old code using 'Helv-Oblique'
399
+ ['Helvetica-BoldOblique', PdfFont.HELVETICA_BOLD_OBLIQUE],
400
+ ['Helv-BoldOblique', PdfFont.HELVETICA_BOLD_OBLIQUE], // Alias for backward compatibility with old code using 'Helv-BoldOblique'
401
+ ['Times-Roman', PdfFont.TIMES_ROMAN],
402
+ ['TiRo', PdfFont.TIMES_ROMAN],
403
+ ['Times-Bold', PdfFont.TIMES_BOLD],
404
+ ['TiBo', PdfFont.TIMES_BOLD],
405
+ ['Times-Italic', PdfFont.TIMES_ITALIC],
406
+ ['TiIt', PdfFont.TIMES_ITALIC],
407
+ ['Times-BoldItalic', PdfFont.TIMES_BOLD_ITALIC],
408
+ ['TiBI', PdfFont.TIMES_BOLD_ITALIC],
409
+ ['Courier', PdfFont.COURIER],
410
+ ['Cour', PdfFont.COURIER], // Alias for backward compatibility with old code using 'Cour'
411
+ ['Courier-Bold', PdfFont.COURIER_BOLD],
412
+ ['Cour-Bold', PdfFont.COURIER_BOLD], // Alias for backward compatibility with old code using 'Cour-Bold'
413
+ ['Courier-Oblique', PdfFont.COURIER_OBLIQUE],
414
+ ['Cour-Oblique', PdfFont.COURIER_OBLIQUE], // Alias for backward compatibility with old code using 'Cour-Oblique'
415
+ ['Courier-BoldOblique', PdfFont.COURIER_BOLD_OBLIQUE],
416
+ ['Cour-BoldOblique', PdfFont.COURIER_BOLD_OBLIQUE], // Alias for backward compatibility with old code using 'Cour-BoldOblique'
417
+ ['Symbol', PdfFont.SYMBOL],
418
+ ['ZapfDingbats', PdfFont.ZAPF_DINGBATS],
419
+ ['ZaDb', PdfFont.ZAPF_DINGBATS],
420
+ ]);
421
+ /**
422
+ * Returns the static PdfFont instance for a standard font name, or null if not found.
423
+ */
424
+ static getStandardFont(fontName) {
425
+ const font = PdfFont.BY_BASE_FONT.get(fontName);
426
+ return font ?? null;
427
+ }
248
428
  /**
249
429
  * Creates a TrueType font from font file data.
250
430
  * Uses WinAnsiEncoding for standard 8-bit character support.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
+ export * from './errors.js';
2
3
  export * from './core/index.js';
3
4
  export * from './crypto/index.js';
4
5
  export * from './filters/index.js';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
+ export * from './errors.js';
2
3
  export * from './core/index.js';
3
4
  export * from './crypto/index.js';
4
5
  export * from './filters/index.js';
@@ -1,4 +1,3 @@
1
- export * from './errors.js';
2
1
  export * from './pdf-document.js';
3
2
  export * from './pdf-reader.js';
4
3
  export * from './pdf-revision.js';
package/dist/pdf/index.js CHANGED
@@ -1,4 +1,3 @@
1
- export * from './errors.js';
2
1
  export * from './pdf-document.js';
3
2
  export * from './pdf-reader.js';
4
3
  export * from './pdf-revision.js';
@@ -13,7 +13,7 @@ import { PdfDocumentSecurityStoreObject } from '../signing/document-security-sto
13
13
  import { ByteArray } from '../types.js';
14
14
  import { PdfDocumentVerificationResult, PdfSigner } from '../signing/signer.js';
15
15
  import { PdfAcroFormManager } from '../acroform/manager.js';
16
- import { PdfFontManager } from '../fonts/font-manager.js';
16
+ import { PdfFontManager } from '../fonts/manager.js';
17
17
  /**
18
18
  * Represents a PDF document with support for reading, writing, and modifying PDF files.
19
19
  * Handles document structure, revisions, encryption, and digital signatures.
@@ -246,6 +246,7 @@ export declare class PdfDocument extends PdfObject {
246
246
  * @param newObjects - Additional objects to add before committing
247
247
  */
248
248
  commit(...newObjects: PdfObject[]): Promise<void>;
249
+ private ensureEncryptionDictionary;
249
250
  /**
250
251
  * Sets the Document Security Store (DSS) for the document.
251
252
  * Used for long-term validation of digital signatures.
@@ -14,11 +14,11 @@ import { PdfByteOffsetToken } from '../core/tokens/byte-offset-token.js';
14
14
  import { PdfNumberToken } from '../core/tokens/number-token.js';
15
15
  import { PdfXRefTableEntryToken } from '../core/tokens/xref-table-entry-token.js';
16
16
  import { PdfStartXRef } from '../core/objects/pdf-start-xref.js';
17
- import { FoundCompressedObjectError } from './errors.js';
17
+ import { FoundCompressedObjectError } from '../errors.js';
18
18
  import { PdfReader } from './pdf-reader.js';
19
19
  import { PdfSigner } from '../signing/signer.js';
20
20
  import { PdfAcroFormManager } from '../acroform/manager.js';
21
- import { PdfFontManager } from '../fonts/font-manager.js';
21
+ import { PdfFontManager } from '../fonts/manager.js';
22
22
  import { concatUint8Arrays } from '../utils/concatUint8Arrays.js';
23
23
  /**
24
24
  * Represents a PDF document with support for reading, writing, and modifying PDF files.
@@ -593,20 +593,24 @@ export class PdfDocument extends PdfObject {
593
593
  newObject instanceof PdfIndirectObject &&
594
594
  this.isObjectEncryptable(newObject)) {
595
595
  await this.securityHandler.write();
596
- if (!this.hasEncryptionDictionary) {
597
- const encryptionDictObject = new PdfIndirectObject({
598
- content: this.securityHandler.dict,
599
- encryptable: false,
600
- });
601
- this.latestRevision.addObject(encryptionDictObject);
602
- this.trailerDict.set('Encrypt', encryptionDictObject.reference);
603
- this.hasEncryptionDictionary = true;
604
- }
596
+ this.ensureEncryptionDictionary();
605
597
  await this.securityHandler.encryptObject(newObject);
606
598
  }
607
599
  }
608
600
  await this.update();
609
601
  }
602
+ ensureEncryptionDictionary() {
603
+ if (this.hasEncryptionDictionary) {
604
+ return;
605
+ }
606
+ const encryptionDictObject = new PdfIndirectObject({
607
+ content: this.securityHandler.dict,
608
+ encryptable: false,
609
+ });
610
+ this.latestRevision.addObject(encryptionDictObject);
611
+ this.trailerDict.set('Encrypt', encryptionDictObject.reference);
612
+ this.hasEncryptionDictionary = true;
613
+ }
610
614
  /**
611
615
  * Sets the Document Security Store (DSS) for the document.
612
616
  * Used for long-term validation of digital signatures.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Encodes a text string for use in a PDF content stream text operator (`Tj`).
3
+ *
4
+ * PDF literal strings `(...)` in content streams are raw bytes interpreted by the
5
+ * font's encoding — NOT UTF-8. This function produces the correct PDF string token:
6
+ *
7
+ * - Type0/Identity-H fonts: hex string `<XXXX...>` with 2 bytes per character (CID = Unicode codepoint)
8
+ * - Single-byte fonts: PDF literal `(...)` with octal escapes `\ooo` for byte values ≥ 0x80,
9
+ * using the reverse encoding map when available for characters outside the Latin-1 range.
10
+ *
11
+ * @param text - The Unicode text to encode
12
+ * @param isUnicode - True if the font uses Type0/Identity-H encoding (2-byte CID per character)
13
+ * @param reverseEncodingMap - Optional map from Unicode character to byte code,
14
+ * derived by inverting the font's Differences-based encoding map
15
+ * @returns A PDF string token ready to use before `Tj`, e.g. `<0050> Tj` or `(text) Tj`
16
+ */
17
+ export declare function encodePdfText(text: string, isUnicode: boolean, reverseEncodingMap?: Map<string, number>): string;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Encodes a text string for use in a PDF content stream text operator (`Tj`).
3
+ *
4
+ * PDF literal strings `(...)` in content streams are raw bytes interpreted by the
5
+ * font's encoding — NOT UTF-8. This function produces the correct PDF string token:
6
+ *
7
+ * - Type0/Identity-H fonts: hex string `<XXXX...>` with 2 bytes per character (CID = Unicode codepoint)
8
+ * - Single-byte fonts: PDF literal `(...)` with octal escapes `\ooo` for byte values ≥ 0x80,
9
+ * using the reverse encoding map when available for characters outside the Latin-1 range.
10
+ *
11
+ * @param text - The Unicode text to encode
12
+ * @param isUnicode - True if the font uses Type0/Identity-H encoding (2-byte CID per character)
13
+ * @param reverseEncodingMap - Optional map from Unicode character to byte code,
14
+ * derived by inverting the font's Differences-based encoding map
15
+ * @returns A PDF string token ready to use before `Tj`, e.g. `<0050> Tj` or `(text) Tj`
16
+ */
17
+ export function encodePdfText(text, isUnicode, reverseEncodingMap) {
18
+ if (isUnicode) {
19
+ // Type0 / Identity-H: 2-byte big-endian CID per code point
20
+ let hex = '<';
21
+ for (const char of text) {
22
+ const code = char.codePointAt(0) ?? 0;
23
+ hex += code.toString(16).padStart(4, '0');
24
+ }
25
+ return hex + '>';
26
+ }
27
+ // Single-byte font: PDF literal string with octal escapes for non-ASCII bytes
28
+ let result = '(';
29
+ for (const char of text) {
30
+ const code = char.charCodeAt(0);
31
+ if (code === 0x28) {
32
+ result += '\\('; // (
33
+ }
34
+ else if (code === 0x29) {
35
+ result += '\\)'; // )
36
+ }
37
+ else if (code === 0x5c) {
38
+ result += '\\\\'; // \
39
+ }
40
+ else if (code === 0x0a) {
41
+ result += '\\n';
42
+ }
43
+ else if (code === 0x0d) {
44
+ result += '\\r';
45
+ }
46
+ else if (code < 0x80) {
47
+ result += char; // ASCII: safe to write directly
48
+ }
49
+ else if (reverseEncodingMap?.has(char)) {
50
+ // Custom font encoding (Differences): use the mapped byte code
51
+ const byteCode = reverseEncodingMap.get(char);
52
+ result += '\\' + byteCode.toString(8).padStart(3, '0');
53
+ }
54
+ else if (code <= 0xff) {
55
+ // Latin-1 range: encode as octal so UTF-8 serialisation doesn't mangle it
56
+ result += '\\' + code.toString(8).padStart(3, '0');
57
+ }
58
+ // Characters above 0xFF with no mapping are silently dropped
59
+ }
60
+ return result + ')';
61
+ }
@@ -1,4 +1,4 @@
1
- export * from './IterableReadableStream.js';
1
+ export * from './iterable-readable-stream.js';
2
2
  export * from './algos.js';
3
3
  export * from './assert.js';
4
4
  export * from './bytesToHex.js';
@@ -1,4 +1,4 @@
1
- export * from './IterableReadableStream.js';
1
+ export * from './iterable-readable-stream.js';
2
2
  export * from './algos.js';
3
3
  export * from './assert.js';
4
4
  export * from './bytesToHex.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-lite",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "exports": {