pdf-parser.js 5.2.27 → 5.2.29

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 (145) hide show
  1. package/dist/{afm-widths-BYiX2L9D.cjs → afm-widths-BHD2HZIL.cjs} +553 -642
  2. package/dist/{afm-widths-blUDDjlI.js → afm-widths-B_IGbGky.js} +553 -642
  3. package/dist/afm-widths.cjs +1 -1
  4. package/dist/afm-widths.js +1 -1
  5. package/dist/annotations.cjs +5 -3
  6. package/dist/annotations.js +5 -3
  7. package/dist/builtin-encoding.cjs +17 -6
  8. package/dist/builtin-encoding.js +17 -6
  9. package/dist/bytes/crc32.cjs +5 -3
  10. package/dist/bytes/crc32.js +5 -3
  11. package/dist/bytes/flate.cjs +0 -1
  12. package/dist/bytes/flate.js +0 -1
  13. package/dist/cff-bounds.cjs +42 -24
  14. package/dist/cff-bounds.js +42 -24
  15. package/dist/cff.cjs +13 -6
  16. package/dist/cff.js +13 -6
  17. package/dist/cmap-table.cjs +54 -26
  18. package/dist/cmap-table.js +54 -26
  19. package/dist/cmap.cjs +5 -3
  20. package/dist/cmap.js +5 -3
  21. package/dist/content-write.cjs +3 -2
  22. package/dist/content-write.js +3 -2
  23. package/dist/crypto/aes.cjs +76 -55
  24. package/dist/crypto/aes.js +76 -55
  25. package/dist/crypto/md5.cjs +345 -149
  26. package/dist/crypto/md5.js +345 -149
  27. package/dist/crypto/rc4.cjs +5 -4
  28. package/dist/crypto/rc4.js +5 -4
  29. package/dist/crypto/sha2.cjs +92 -43
  30. package/dist/crypto/sha2.js +92 -43
  31. package/dist/embedded-font.cjs +4 -2
  32. package/dist/embedded-font.js +4 -2
  33. package/dist/encoding.cjs +1 -1
  34. package/dist/encoding.js +1 -1
  35. package/dist/encrypt-write.cjs +25 -21
  36. package/dist/encrypt-write.js +25 -21
  37. package/dist/encrypt.cjs +43 -64
  38. package/dist/encrypt.js +43 -64
  39. package/dist/filters.cjs +40 -20
  40. package/dist/filters.js +40 -20
  41. package/dist/font-face.cjs +2 -1
  42. package/dist/font-face.js +2 -1
  43. package/dist/font-read.cjs +12 -6
  44. package/dist/font-read.js +12 -6
  45. package/dist/font-tables.cjs +55 -28
  46. package/dist/font-tables.js +55 -28
  47. package/dist/gdef-table.cjs +6 -3
  48. package/dist/gdef-table.js +6 -3
  49. package/dist/glyf-contours.cjs +3 -1
  50. package/dist/glyf-contours.js +3 -1
  51. package/dist/glyf.cjs +22 -11
  52. package/dist/glyf.js +22 -11
  53. package/dist/gpos-table.cjs +37 -19
  54. package/dist/gpos-table.js +37 -19
  55. package/dist/gsub-table.cjs +28 -17
  56. package/dist/gsub-table.js +28 -17
  57. package/dist/hmtx-table.cjs +5 -3
  58. package/dist/hmtx-table.js +5 -3
  59. package/dist/image/ccitt-encode.cjs +8 -5
  60. package/dist/image/ccitt-encode.js +8 -5
  61. package/dist/image/ccitt.cjs +801 -209
  62. package/dist/image/ccitt.js +801 -209
  63. package/dist/image/jbig2-arith.cjs +340 -306
  64. package/dist/image/jbig2-arith.js +340 -306
  65. package/dist/image/jbig2-bitmap.cjs +8 -5
  66. package/dist/image/jbig2-bitmap.js +8 -5
  67. package/dist/image/jbig2-generic.cjs +240 -69
  68. package/dist/image/jbig2-generic.js +240 -69
  69. package/dist/image/jbig2-text.cjs +4 -2
  70. package/dist/image/jbig2-text.js +4 -2
  71. package/dist/image/jbig2.cjs +69 -31
  72. package/dist/image/jbig2.js +69 -31
  73. package/dist/image/jp2-boxes.cjs +52 -27
  74. package/dist/image/jp2-boxes.js +52 -27
  75. package/dist/image/jpeg-info.cjs +29 -24
  76. package/dist/image/jpeg-info.js +29 -24
  77. package/dist/image/jpeg2000-codestream.cjs +44 -24
  78. package/dist/image/jpeg2000-codestream.js +44 -24
  79. package/dist/image/jpeg2000-dwt.cjs +2 -1
  80. package/dist/image/jpeg2000-dwt.js +2 -1
  81. package/dist/image/jpeg2000-t1.cjs +21 -11
  82. package/dist/image/jpeg2000-t1.js +21 -11
  83. package/dist/image/jpeg2000-t2.cjs +12 -5
  84. package/dist/image/jpeg2000-t2.js +12 -5
  85. package/dist/image/jpeg2000-tagtree.cjs +8 -4
  86. package/dist/image/jpeg2000-tagtree.js +8 -4
  87. package/dist/image/jpeg2000.cjs +11 -6
  88. package/dist/image/jpeg2000.js +11 -6
  89. package/dist/image/png-decode.cjs +62 -39
  90. package/dist/image/png-decode.d.cts +3 -2
  91. package/dist/image/png-decode.d.ts +3 -2
  92. package/dist/image/png-decode.js +62 -39
  93. package/dist/image/png-filter.cjs +23 -15
  94. package/dist/image/png-filter.js +23 -15
  95. package/dist/images-read.cjs +41 -36
  96. package/dist/images-read.js +41 -36
  97. package/dist/index.cjs +1 -1
  98. package/dist/index.js +1 -1
  99. package/dist/interpret.cjs +39 -24
  100. package/dist/interpret.js +39 -24
  101. package/dist/lexer.cjs +86 -51
  102. package/dist/lexer.js +86 -51
  103. package/dist/math-content-write.cjs +9 -5
  104. package/dist/math-content-write.js +9 -5
  105. package/dist/math-font-write.cjs +2 -1
  106. package/dist/math-font-write.js +2 -1
  107. package/dist/math-font.cjs +16 -7
  108. package/dist/math-font.js +16 -7
  109. package/dist/math-table.cjs +25 -13
  110. package/dist/math-table.js +25 -13
  111. package/dist/matrix.cjs +3 -2
  112. package/dist/matrix.js +3 -2
  113. package/dist/measure.cjs +1 -1
  114. package/dist/measure.js +1 -1
  115. package/dist/navigation.cjs +10 -5
  116. package/dist/navigation.js +10 -5
  117. package/dist/ot-layout-common.cjs +4 -2
  118. package/dist/ot-layout-common.js +4 -2
  119. package/dist/parse.cjs +7 -5
  120. package/dist/parse.js +7 -5
  121. package/dist/pdf-text.cjs +5 -2
  122. package/dist/pdf-text.js +5 -2
  123. package/dist/predictors.cjs +14 -9
  124. package/dist/predictors.js +14 -9
  125. package/dist/raster.cjs +30 -19
  126. package/dist/raster.js +30 -19
  127. package/dist/read.cjs +17 -8
  128. package/dist/read.js +17 -8
  129. package/dist/serialize.cjs +6 -2
  130. package/dist/serialize.js +6 -2
  131. package/dist/sfnt-subset.cjs +25 -13
  132. package/dist/sfnt-subset.js +25 -13
  133. package/dist/sfnt.cjs +20 -10
  134. package/dist/sfnt.js +20 -10
  135. package/dist/text-group.cjs +0 -1
  136. package/dist/text-group.js +0 -1
  137. package/dist/tounicode.cjs +4 -2
  138. package/dist/tounicode.js +4 -2
  139. package/dist/winansi.cjs +1 -1
  140. package/dist/winansi.js +1 -1
  141. package/dist/write.cjs +20 -12
  142. package/dist/write.js +20 -12
  143. package/dist/xref.cjs +5 -2
  144. package/dist/xref.js +5 -2
  145. package/package.json +2 -2
package/dist/cff.js CHANGED
@@ -11,6 +11,7 @@ const INDEX_COUNT_SIZE = 2;
11
11
  const INDEX_OFF_SIZE_SIZE = 1;
12
12
  const MIN_OFF_SIZE = 1;
13
13
  const MAX_OFF_SIZE = 4;
14
+ const OFF_SIZE_3_BYTES = 3;
14
15
  const DICT_OPERATOR_MAX = 21;
15
16
  const DICT_OPERATOR_ESCAPE = 12;
16
17
  const DICT_OPERAND_INT16 = 28;
@@ -27,6 +28,12 @@ const DICT_OPERAND_MEDIUM_BIAS = 108;
27
28
  const DICT_OPERAND_MEDIUM_FIRST_BYTE_BIAS = 247;
28
29
  const DICT_OPERAND_NEGATIVE_MEDIUM_FIRST_BYTE_BIAS = 251;
29
30
  const BYTE_RADIX = 256;
31
+ const INT16_SIGN_BIT = 32768;
32
+ const UINT16_MODULUS = 65536;
33
+ const DICT_OPERAND_INT16_TOTAL_SIZE = 3;
34
+ const INT32_SIZE_BYTES = 4;
35
+ const DICT_OPERAND_INT32_TOTAL_SIZE = 5;
36
+ const REAL_NIBBLE_DIGIT_MAX = 9;
30
37
  const REAL_NIBBLE_DECIMAL_POINT = 10;
31
38
  const REAL_NIBBLE_EXPONENT = 11;
32
39
  const REAL_NIBBLE_NEGATIVE_EXPONENT = 12;
@@ -38,7 +45,7 @@ const LOW_NIBBLE_MASK = 15;
38
45
  function readOffsetAt(bytes, offset, offSize) {
39
46
  if (offSize === 1) return u8(bytes, offset);
40
47
  if (offSize === 2) return u16(bytes, offset);
41
- if (offSize === 3) return u24(bytes, offset);
48
+ if (offSize === OFF_SIZE_3_BYTES) return u24(bytes, offset);
42
49
  return u32(bytes, offset);
43
50
  }
44
51
  function readCffIndex(bytes, offset) {
@@ -79,7 +86,7 @@ function readRealOperand(data, start) {
79
86
  endOffset: i + 1
80
87
  };
81
88
  if (nibble === REAL_NIBBLE_RESERVED) return;
82
- if (nibble <= 9) text += String(nibble);
89
+ if (nibble <= REAL_NIBBLE_DIGIT_MAX) text += String(nibble);
83
90
  else if (nibble === REAL_NIBBLE_DECIMAL_POINT) text += ".";
84
91
  else if (nibble === REAL_NIBBLE_EXPONENT) text += "E";
85
92
  else if (nibble === REAL_NIBBLE_NEGATIVE_EXPONENT) text += "E-";
@@ -108,14 +115,14 @@ function parseCffDict(data) {
108
115
  if (b0 === DICT_OPERAND_INT16) {
109
116
  if (!hasBytes(data, i + 1, 2)) return;
110
117
  const raw = u16(data, i + 1);
111
- operands.push(raw >= 32768 ? raw - 65536 : raw);
112
- i += 3;
118
+ operands.push(raw >= INT16_SIGN_BIT ? raw - UINT16_MODULUS : raw);
119
+ i += DICT_OPERAND_INT16_TOTAL_SIZE;
113
120
  continue;
114
121
  }
115
122
  if (b0 === DICT_OPERAND_INT32) {
116
- if (!hasBytes(data, i + 1, 4)) return;
123
+ if (!hasBytes(data, i + 1, INT32_SIZE_BYTES)) return;
117
124
  operands.push(u32(data, i + 1) | 0);
118
- i += 5;
125
+ i += DICT_OPERAND_INT32_TOTAL_SIZE;
119
126
  continue;
120
127
  }
121
128
  if (b0 === DICT_OPERAND_REAL) {
@@ -4,17 +4,28 @@ const require_sfnt = require("./sfnt.cjs");
4
4
  const CMAP_HEADER_SIZE = 4;
5
5
  const SUBTABLE_RECORD_SIZE = 8;
6
6
  const MAX_UNICODE_CODE_POINT = 1114111;
7
+ const SUBTABLE_RECORD_OFFSET_FIELD = 4;
8
+ const CMAP_FORMAT_4 = 4;
9
+ const CMAP_FORMAT_6 = 6;
10
+ const CMAP_FORMAT_12 = 12;
11
+ const INT16_SIGN_BIT = 32768;
12
+ const UINT16_MODULUS = 65536;
13
+ const UINT16_MASK = 65535;
7
14
  const FORMAT_4_HEADER_SIZE = 14;
15
+ const FORMAT_4_SEG_COUNT_X2_FIELD = 6;
16
+ const FORMAT_4_PARALLEL_ARRAY_COUNT = 4;
17
+ const MAX_BMP_CODE_POINT = 65535;
18
+ const LAST_MAPPABLE_BMP_CODE = 65534;
8
19
  function parseFormat4(bytes, subtableOffset) {
9
20
  if (!require_sfnt.hasBytes(bytes, subtableOffset, FORMAT_4_HEADER_SIZE)) return;
10
- const segCountX2 = require_sfnt.u16(bytes, subtableOffset + 6);
21
+ const segCountX2 = require_sfnt.u16(bytes, subtableOffset + FORMAT_4_SEG_COUNT_X2_FIELD);
11
22
  if (segCountX2 === 0 || segCountX2 % 2 !== 0) return;
12
23
  const segCount = segCountX2 / 2;
13
24
  const endCodesOffset = subtableOffset + FORMAT_4_HEADER_SIZE;
14
25
  const startCodesOffset = endCodesOffset + segCountX2 + 2;
15
26
  const idDeltasOffset = startCodesOffset + segCountX2;
16
27
  const idRangeOffsetsOffset = idDeltasOffset + segCountX2;
17
- if (!require_sfnt.hasBytes(bytes, endCodesOffset, segCountX2 * 4 + 2)) return;
28
+ if (!require_sfnt.hasBytes(bytes, endCodesOffset, segCountX2 * FORMAT_4_PARALLEL_ARRAY_COUNT + 2)) return;
18
29
  const segments = [];
19
30
  for (let i = 0; i < segCount; i++) {
20
31
  const idRangeOffsetPos = idRangeOffsetsOffset + i * 2;
@@ -22,27 +33,27 @@ function parseFormat4(bytes, subtableOffset) {
22
33
  segments.push({
23
34
  endCode: require_sfnt.u16(bytes, endCodesOffset + i * 2),
24
35
  startCode: require_sfnt.u16(bytes, startCodesOffset + i * 2),
25
- idDelta: rawDelta >= 32768 ? rawDelta - 65536 : rawDelta,
36
+ idDelta: rawDelta >= INT16_SIGN_BIT ? rawDelta - UINT16_MODULUS : rawDelta,
26
37
  idRangeOffsetPos,
27
38
  idRangeOffset: require_sfnt.u16(bytes, idRangeOffsetPos)
28
39
  });
29
40
  }
30
41
  const lookup = (codePoint) => {
31
- if (codePoint > 65535) return;
42
+ if (codePoint > MAX_BMP_CODE_POINT) return;
32
43
  for (const segment of segments) {
33
44
  if (codePoint < segment.startCode || codePoint > segment.endCode) continue;
34
- if (segment.idRangeOffset === 0) return codePoint + segment.idDelta & 65535;
45
+ if (segment.idRangeOffset === 0) return codePoint + segment.idDelta & UINT16_MASK;
35
46
  const glyphIndexAddress = segment.idRangeOffsetPos + segment.idRangeOffset + (codePoint - segment.startCode) * 2;
36
47
  if (!require_sfnt.hasBytes(bytes, glyphIndexAddress, 2)) return;
37
48
  const glyphId = require_sfnt.u16(bytes, glyphIndexAddress);
38
- return glyphId === 0 ? void 0 : glyphId + segment.idDelta & 65535;
49
+ return glyphId === 0 ? void 0 : glyphId + segment.idDelta & UINT16_MASK;
39
50
  }
40
51
  };
41
52
  return {
42
53
  lookup,
43
54
  forEachMapping(visit) {
44
55
  for (const segment of segments) {
45
- const end = Math.min(segment.endCode, 65534);
56
+ const end = Math.min(segment.endCode, LAST_MAPPABLE_BMP_CODE);
46
57
  for (let code = segment.startCode; code <= end; code++) {
47
58
  const glyphId = lookup(code);
48
59
  if (glyphId !== void 0 && glyphId !== 0) visit(code, glyphId);
@@ -52,10 +63,13 @@ function parseFormat4(bytes, subtableOffset) {
52
63
  };
53
64
  }
54
65
  const FORMAT_12_HEADER_SIZE = 16;
66
+ const FORMAT_12_NUM_GROUPS_FIELD = 12;
55
67
  const FORMAT_12_GROUP_SIZE = 12;
68
+ const FORMAT_12_GROUP_END_CHAR_CODE_FIELD = 4;
69
+ const FORMAT_12_GROUP_START_GLYPH_ID_FIELD = 8;
56
70
  function parseFormat12(bytes, subtableOffset) {
57
71
  if (!require_sfnt.hasBytes(bytes, subtableOffset, FORMAT_12_HEADER_SIZE)) return;
58
- const numGroups = require_sfnt.u32(bytes, subtableOffset + 12);
72
+ const numGroups = require_sfnt.u32(bytes, subtableOffset + FORMAT_12_NUM_GROUPS_FIELD);
59
73
  const groupsOffset = subtableOffset + FORMAT_12_HEADER_SIZE;
60
74
  if (!require_sfnt.hasBytes(bytes, groupsOffset, numGroups * FORMAT_12_GROUP_SIZE)) return;
61
75
  const groups = [];
@@ -63,8 +77,8 @@ function parseFormat12(bytes, subtableOffset) {
63
77
  const recordOffset = groupsOffset + i * FORMAT_12_GROUP_SIZE;
64
78
  groups.push({
65
79
  startCharCode: require_sfnt.u32(bytes, recordOffset),
66
- endCharCode: require_sfnt.u32(bytes, recordOffset + 4),
67
- startGlyphId: require_sfnt.u32(bytes, recordOffset + 8)
80
+ endCharCode: require_sfnt.u32(bytes, recordOffset + FORMAT_12_GROUP_END_CHAR_CODE_FIELD),
81
+ startGlyphId: require_sfnt.u32(bytes, recordOffset + FORMAT_12_GROUP_START_GLYPH_ID_FIELD)
68
82
  });
69
83
  }
70
84
  return {
@@ -80,18 +94,20 @@ function parseFormat12(bytes, subtableOffset) {
80
94
  };
81
95
  }
82
96
  const FORMAT_0_SIZE = 262;
97
+ const FORMAT_0_GLYPH_ID_ARRAY_OFFSET = 6;
98
+ const MAX_FORMAT_0_CODE = 255;
83
99
  function parseFormat0(bytes, subtableOffset) {
84
100
  if (!require_sfnt.hasBytes(bytes, subtableOffset, FORMAT_0_SIZE)) return;
85
- const glyphIdArrayOffset = subtableOffset + 6;
101
+ const glyphIdArrayOffset = subtableOffset + FORMAT_0_GLYPH_ID_ARRAY_OFFSET;
86
102
  const lookup = (codePoint) => {
87
- if (codePoint < 0 || codePoint > 255) return;
103
+ if (codePoint < 0 || codePoint > MAX_FORMAT_0_CODE) return;
88
104
  const glyphId = require_sfnt.u8(bytes, glyphIdArrayOffset + codePoint);
89
105
  return glyphId === 0 ? void 0 : glyphId;
90
106
  };
91
107
  return {
92
108
  lookup,
93
109
  forEachMapping(visit) {
94
- for (let code = 0; code <= 255; code++) {
110
+ for (let code = 0; code <= MAX_FORMAT_0_CODE; code++) {
95
111
  const glyphId = lookup(code);
96
112
  if (glyphId !== void 0) visit(code, glyphId);
97
113
  }
@@ -99,10 +115,12 @@ function parseFormat0(bytes, subtableOffset) {
99
115
  };
100
116
  }
101
117
  const FORMAT_6_HEADER_SIZE = 10;
118
+ const FORMAT_6_FIRST_CODE_FIELD = 6;
119
+ const FORMAT_6_ENTRY_COUNT_FIELD = 8;
102
120
  function parseFormat6(bytes, subtableOffset) {
103
121
  if (!require_sfnt.hasBytes(bytes, subtableOffset, FORMAT_6_HEADER_SIZE)) return;
104
- const firstCode = require_sfnt.u16(bytes, subtableOffset + 6);
105
- const entryCount = require_sfnt.u16(bytes, subtableOffset + 8);
122
+ const firstCode = require_sfnt.u16(bytes, subtableOffset + FORMAT_6_FIRST_CODE_FIELD);
123
+ const entryCount = require_sfnt.u16(bytes, subtableOffset + FORMAT_6_ENTRY_COUNT_FIELD);
106
124
  const glyphIdArrayOffset = subtableOffset + FORMAT_6_HEADER_SIZE;
107
125
  if (!require_sfnt.hasBytes(bytes, glyphIdArrayOffset, entryCount * 2)) return;
108
126
  const lookup = (codePoint) => {
@@ -122,19 +140,29 @@ function parseFormat6(bytes, subtableOffset) {
122
140
  }
123
141
  };
124
142
  }
143
+ const PLATFORM_WINDOWS = 3;
144
+ const PLATFORM_UNICODE = 0;
145
+ const ENCODING_WINDOWS_UCS4 = 10;
146
+ const ENCODING_WINDOWS_UNICODE_BMP = 1;
147
+ const RANK_WINDOWS_UCS4_FORMAT_12 = 0;
148
+ const RANK_UNICODE_FORMAT_12 = 1;
149
+ const RANK_OTHER_FORMAT_12 = 2;
150
+ const RANK_WINDOWS_BMP_FORMAT_4 = 3;
151
+ const RANK_OTHER_FORMAT_4 = 4;
152
+ const RANK_FORMAT_6 = 5;
125
153
  function preferenceRank(subtable) {
126
- if (subtable.format === 12) {
127
- if (subtable.platformId === 3 && subtable.encodingId === 10) return 0;
128
- if (subtable.platformId === 0) return 1;
129
- return 2;
154
+ if (subtable.format === CMAP_FORMAT_12) {
155
+ if (subtable.platformId === PLATFORM_WINDOWS && subtable.encodingId === ENCODING_WINDOWS_UCS4) return RANK_WINDOWS_UCS4_FORMAT_12;
156
+ if (subtable.platformId === PLATFORM_UNICODE) return RANK_UNICODE_FORMAT_12;
157
+ return RANK_OTHER_FORMAT_12;
130
158
  }
131
- if (subtable.format === 4) return subtable.platformId === 3 && subtable.encodingId === 1 ? 3 : 4;
132
- return 5;
159
+ if (subtable.format === CMAP_FORMAT_4) return subtable.platformId === PLATFORM_WINDOWS && subtable.encodingId === ENCODING_WINDOWS_UNICODE_BMP ? RANK_WINDOWS_BMP_FORMAT_4 : RANK_OTHER_FORMAT_4;
160
+ return RANK_FORMAT_6;
133
161
  }
134
162
  function parseSubtable(bytes, record) {
135
- if (record.format === 12) return parseFormat12(bytes, record.offset);
136
- if (record.format === 4) return parseFormat4(bytes, record.offset);
137
- if (record.format === 6) return parseFormat6(bytes, record.offset);
163
+ if (record.format === CMAP_FORMAT_12) return parseFormat12(bytes, record.offset);
164
+ if (record.format === CMAP_FORMAT_4) return parseFormat4(bytes, record.offset);
165
+ if (record.format === CMAP_FORMAT_6) return parseFormat6(bytes, record.offset);
138
166
  return record.format === 0 ? parseFormat0(bytes, record.offset) : void 0;
139
167
  }
140
168
  function readCmapSubtables(font) {
@@ -145,7 +173,7 @@ function readCmapSubtables(font) {
145
173
  const subtables = [];
146
174
  for (let i = 0; i < numTables; i++) {
147
175
  const recordOffset = CMAP_HEADER_SIZE + i * SUBTABLE_RECORD_SIZE;
148
- const offset = require_sfnt.u32(cmapBytes, recordOffset + 4);
176
+ const offset = require_sfnt.u32(cmapBytes, recordOffset + SUBTABLE_RECORD_OFFSET_FIELD);
149
177
  if (!require_sfnt.hasBytes(cmapBytes, offset, 2)) continue;
150
178
  const record = {
151
179
  platformId: require_sfnt.u16(cmapBytes, recordOffset),
@@ -164,7 +192,7 @@ function readCmapSubtables(font) {
164
192
  return subtables;
165
193
  }
166
194
  function buildCmapLookup(font) {
167
- return readCmapSubtables(font).filter((s) => s.format === 4 || s.format === 6 || s.format === 12).sort((a, b) => preferenceRank(a) - preferenceRank(b))[0]?.lookup;
195
+ return readCmapSubtables(font).filter((s) => s.format === CMAP_FORMAT_4 || s.format === CMAP_FORMAT_6 || s.format === CMAP_FORMAT_12).sort((a, b) => preferenceRank(a) - preferenceRank(b))[0]?.lookup;
168
196
  }
169
197
  //#endregion
170
198
  exports.buildCmapLookup = buildCmapLookup;
@@ -3,17 +3,28 @@ import { hasBytes, sfntTableBytes, u16, u32, u8 } from "./sfnt.js";
3
3
  const CMAP_HEADER_SIZE = 4;
4
4
  const SUBTABLE_RECORD_SIZE = 8;
5
5
  const MAX_UNICODE_CODE_POINT = 1114111;
6
+ const SUBTABLE_RECORD_OFFSET_FIELD = 4;
7
+ const CMAP_FORMAT_4 = 4;
8
+ const CMAP_FORMAT_6 = 6;
9
+ const CMAP_FORMAT_12 = 12;
10
+ const INT16_SIGN_BIT = 32768;
11
+ const UINT16_MODULUS = 65536;
12
+ const UINT16_MASK = 65535;
6
13
  const FORMAT_4_HEADER_SIZE = 14;
14
+ const FORMAT_4_SEG_COUNT_X2_FIELD = 6;
15
+ const FORMAT_4_PARALLEL_ARRAY_COUNT = 4;
16
+ const MAX_BMP_CODE_POINT = 65535;
17
+ const LAST_MAPPABLE_BMP_CODE = 65534;
7
18
  function parseFormat4(bytes, subtableOffset) {
8
19
  if (!hasBytes(bytes, subtableOffset, FORMAT_4_HEADER_SIZE)) return;
9
- const segCountX2 = u16(bytes, subtableOffset + 6);
20
+ const segCountX2 = u16(bytes, subtableOffset + FORMAT_4_SEG_COUNT_X2_FIELD);
10
21
  if (segCountX2 === 0 || segCountX2 % 2 !== 0) return;
11
22
  const segCount = segCountX2 / 2;
12
23
  const endCodesOffset = subtableOffset + FORMAT_4_HEADER_SIZE;
13
24
  const startCodesOffset = endCodesOffset + segCountX2 + 2;
14
25
  const idDeltasOffset = startCodesOffset + segCountX2;
15
26
  const idRangeOffsetsOffset = idDeltasOffset + segCountX2;
16
- if (!hasBytes(bytes, endCodesOffset, segCountX2 * 4 + 2)) return;
27
+ if (!hasBytes(bytes, endCodesOffset, segCountX2 * FORMAT_4_PARALLEL_ARRAY_COUNT + 2)) return;
17
28
  const segments = [];
18
29
  for (let i = 0; i < segCount; i++) {
19
30
  const idRangeOffsetPos = idRangeOffsetsOffset + i * 2;
@@ -21,27 +32,27 @@ function parseFormat4(bytes, subtableOffset) {
21
32
  segments.push({
22
33
  endCode: u16(bytes, endCodesOffset + i * 2),
23
34
  startCode: u16(bytes, startCodesOffset + i * 2),
24
- idDelta: rawDelta >= 32768 ? rawDelta - 65536 : rawDelta,
35
+ idDelta: rawDelta >= INT16_SIGN_BIT ? rawDelta - UINT16_MODULUS : rawDelta,
25
36
  idRangeOffsetPos,
26
37
  idRangeOffset: u16(bytes, idRangeOffsetPos)
27
38
  });
28
39
  }
29
40
  const lookup = (codePoint) => {
30
- if (codePoint > 65535) return;
41
+ if (codePoint > MAX_BMP_CODE_POINT) return;
31
42
  for (const segment of segments) {
32
43
  if (codePoint < segment.startCode || codePoint > segment.endCode) continue;
33
- if (segment.idRangeOffset === 0) return codePoint + segment.idDelta & 65535;
44
+ if (segment.idRangeOffset === 0) return codePoint + segment.idDelta & UINT16_MASK;
34
45
  const glyphIndexAddress = segment.idRangeOffsetPos + segment.idRangeOffset + (codePoint - segment.startCode) * 2;
35
46
  if (!hasBytes(bytes, glyphIndexAddress, 2)) return;
36
47
  const glyphId = u16(bytes, glyphIndexAddress);
37
- return glyphId === 0 ? void 0 : glyphId + segment.idDelta & 65535;
48
+ return glyphId === 0 ? void 0 : glyphId + segment.idDelta & UINT16_MASK;
38
49
  }
39
50
  };
40
51
  return {
41
52
  lookup,
42
53
  forEachMapping(visit) {
43
54
  for (const segment of segments) {
44
- const end = Math.min(segment.endCode, 65534);
55
+ const end = Math.min(segment.endCode, LAST_MAPPABLE_BMP_CODE);
45
56
  for (let code = segment.startCode; code <= end; code++) {
46
57
  const glyphId = lookup(code);
47
58
  if (glyphId !== void 0 && glyphId !== 0) visit(code, glyphId);
@@ -51,10 +62,13 @@ function parseFormat4(bytes, subtableOffset) {
51
62
  };
52
63
  }
53
64
  const FORMAT_12_HEADER_SIZE = 16;
65
+ const FORMAT_12_NUM_GROUPS_FIELD = 12;
54
66
  const FORMAT_12_GROUP_SIZE = 12;
67
+ const FORMAT_12_GROUP_END_CHAR_CODE_FIELD = 4;
68
+ const FORMAT_12_GROUP_START_GLYPH_ID_FIELD = 8;
55
69
  function parseFormat12(bytes, subtableOffset) {
56
70
  if (!hasBytes(bytes, subtableOffset, FORMAT_12_HEADER_SIZE)) return;
57
- const numGroups = u32(bytes, subtableOffset + 12);
71
+ const numGroups = u32(bytes, subtableOffset + FORMAT_12_NUM_GROUPS_FIELD);
58
72
  const groupsOffset = subtableOffset + FORMAT_12_HEADER_SIZE;
59
73
  if (!hasBytes(bytes, groupsOffset, numGroups * FORMAT_12_GROUP_SIZE)) return;
60
74
  const groups = [];
@@ -62,8 +76,8 @@ function parseFormat12(bytes, subtableOffset) {
62
76
  const recordOffset = groupsOffset + i * FORMAT_12_GROUP_SIZE;
63
77
  groups.push({
64
78
  startCharCode: u32(bytes, recordOffset),
65
- endCharCode: u32(bytes, recordOffset + 4),
66
- startGlyphId: u32(bytes, recordOffset + 8)
79
+ endCharCode: u32(bytes, recordOffset + FORMAT_12_GROUP_END_CHAR_CODE_FIELD),
80
+ startGlyphId: u32(bytes, recordOffset + FORMAT_12_GROUP_START_GLYPH_ID_FIELD)
67
81
  });
68
82
  }
69
83
  return {
@@ -79,18 +93,20 @@ function parseFormat12(bytes, subtableOffset) {
79
93
  };
80
94
  }
81
95
  const FORMAT_0_SIZE = 262;
96
+ const FORMAT_0_GLYPH_ID_ARRAY_OFFSET = 6;
97
+ const MAX_FORMAT_0_CODE = 255;
82
98
  function parseFormat0(bytes, subtableOffset) {
83
99
  if (!hasBytes(bytes, subtableOffset, FORMAT_0_SIZE)) return;
84
- const glyphIdArrayOffset = subtableOffset + 6;
100
+ const glyphIdArrayOffset = subtableOffset + FORMAT_0_GLYPH_ID_ARRAY_OFFSET;
85
101
  const lookup = (codePoint) => {
86
- if (codePoint < 0 || codePoint > 255) return;
102
+ if (codePoint < 0 || codePoint > MAX_FORMAT_0_CODE) return;
87
103
  const glyphId = u8(bytes, glyphIdArrayOffset + codePoint);
88
104
  return glyphId === 0 ? void 0 : glyphId;
89
105
  };
90
106
  return {
91
107
  lookup,
92
108
  forEachMapping(visit) {
93
- for (let code = 0; code <= 255; code++) {
109
+ for (let code = 0; code <= MAX_FORMAT_0_CODE; code++) {
94
110
  const glyphId = lookup(code);
95
111
  if (glyphId !== void 0) visit(code, glyphId);
96
112
  }
@@ -98,10 +114,12 @@ function parseFormat0(bytes, subtableOffset) {
98
114
  };
99
115
  }
100
116
  const FORMAT_6_HEADER_SIZE = 10;
117
+ const FORMAT_6_FIRST_CODE_FIELD = 6;
118
+ const FORMAT_6_ENTRY_COUNT_FIELD = 8;
101
119
  function parseFormat6(bytes, subtableOffset) {
102
120
  if (!hasBytes(bytes, subtableOffset, FORMAT_6_HEADER_SIZE)) return;
103
- const firstCode = u16(bytes, subtableOffset + 6);
104
- const entryCount = u16(bytes, subtableOffset + 8);
121
+ const firstCode = u16(bytes, subtableOffset + FORMAT_6_FIRST_CODE_FIELD);
122
+ const entryCount = u16(bytes, subtableOffset + FORMAT_6_ENTRY_COUNT_FIELD);
105
123
  const glyphIdArrayOffset = subtableOffset + FORMAT_6_HEADER_SIZE;
106
124
  if (!hasBytes(bytes, glyphIdArrayOffset, entryCount * 2)) return;
107
125
  const lookup = (codePoint) => {
@@ -121,19 +139,29 @@ function parseFormat6(bytes, subtableOffset) {
121
139
  }
122
140
  };
123
141
  }
142
+ const PLATFORM_WINDOWS = 3;
143
+ const PLATFORM_UNICODE = 0;
144
+ const ENCODING_WINDOWS_UCS4 = 10;
145
+ const ENCODING_WINDOWS_UNICODE_BMP = 1;
146
+ const RANK_WINDOWS_UCS4_FORMAT_12 = 0;
147
+ const RANK_UNICODE_FORMAT_12 = 1;
148
+ const RANK_OTHER_FORMAT_12 = 2;
149
+ const RANK_WINDOWS_BMP_FORMAT_4 = 3;
150
+ const RANK_OTHER_FORMAT_4 = 4;
151
+ const RANK_FORMAT_6 = 5;
124
152
  function preferenceRank(subtable) {
125
- if (subtable.format === 12) {
126
- if (subtable.platformId === 3 && subtable.encodingId === 10) return 0;
127
- if (subtable.platformId === 0) return 1;
128
- return 2;
153
+ if (subtable.format === CMAP_FORMAT_12) {
154
+ if (subtable.platformId === PLATFORM_WINDOWS && subtable.encodingId === ENCODING_WINDOWS_UCS4) return RANK_WINDOWS_UCS4_FORMAT_12;
155
+ if (subtable.platformId === PLATFORM_UNICODE) return RANK_UNICODE_FORMAT_12;
156
+ return RANK_OTHER_FORMAT_12;
129
157
  }
130
- if (subtable.format === 4) return subtable.platformId === 3 && subtable.encodingId === 1 ? 3 : 4;
131
- return 5;
158
+ if (subtable.format === CMAP_FORMAT_4) return subtable.platformId === PLATFORM_WINDOWS && subtable.encodingId === ENCODING_WINDOWS_UNICODE_BMP ? RANK_WINDOWS_BMP_FORMAT_4 : RANK_OTHER_FORMAT_4;
159
+ return RANK_FORMAT_6;
132
160
  }
133
161
  function parseSubtable(bytes, record) {
134
- if (record.format === 12) return parseFormat12(bytes, record.offset);
135
- if (record.format === 4) return parseFormat4(bytes, record.offset);
136
- if (record.format === 6) return parseFormat6(bytes, record.offset);
162
+ if (record.format === CMAP_FORMAT_12) return parseFormat12(bytes, record.offset);
163
+ if (record.format === CMAP_FORMAT_4) return parseFormat4(bytes, record.offset);
164
+ if (record.format === CMAP_FORMAT_6) return parseFormat6(bytes, record.offset);
137
165
  return record.format === 0 ? parseFormat0(bytes, record.offset) : void 0;
138
166
  }
139
167
  function readCmapSubtables(font) {
@@ -144,7 +172,7 @@ function readCmapSubtables(font) {
144
172
  const subtables = [];
145
173
  for (let i = 0; i < numTables; i++) {
146
174
  const recordOffset = CMAP_HEADER_SIZE + i * SUBTABLE_RECORD_SIZE;
147
- const offset = u32(cmapBytes, recordOffset + 4);
175
+ const offset = u32(cmapBytes, recordOffset + SUBTABLE_RECORD_OFFSET_FIELD);
148
176
  if (!hasBytes(cmapBytes, offset, 2)) continue;
149
177
  const record = {
150
178
  platformId: u16(cmapBytes, recordOffset),
@@ -163,7 +191,7 @@ function readCmapSubtables(font) {
163
191
  return subtables;
164
192
  }
165
193
  function buildCmapLookup(font) {
166
- return readCmapSubtables(font).filter((s) => s.format === 4 || s.format === 6 || s.format === 12).sort((a, b) => preferenceRank(a) - preferenceRank(b))[0]?.lookup;
194
+ return readCmapSubtables(font).filter((s) => s.format === CMAP_FORMAT_4 || s.format === CMAP_FORMAT_6 || s.format === CMAP_FORMAT_12).sort((a, b) => preferenceRank(a) - preferenceRank(b))[0]?.lookup;
167
195
  }
168
196
  //#endregion
169
197
  export { buildCmapLookup, readCmapSubtables };
package/dist/cmap.cjs CHANGED
@@ -2,14 +2,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_bytes_reader = require("./bytes/reader.cjs");
3
3
  const require_lexer = require("./lexer.cjs");
4
4
  //#region src/cmap.ts
5
+ const BYTE_RADIX = 256;
6
+ const BITS_PER_BYTE = 8;
5
7
  function hexBytesToNumber(bytes) {
6
8
  let value = 0;
7
- for (const byte of bytes) value = value * 256 + byte;
9
+ for (const byte of bytes) value = value * BYTE_RADIX + byte;
8
10
  return value;
9
11
  }
10
12
  function decodeUtf16BEString(bytes) {
11
13
  const units = [];
12
- for (let i = 0; i + 1 < bytes.length; i += 2) units.push((bytes[i] ?? 0) << 8 | (bytes[i + 1] ?? 0));
14
+ for (let i = 0; i + 1 < bytes.length; i += 2) units.push((bytes[i] ?? 0) << BITS_PER_BYTE | (bytes[i + 1] ?? 0));
13
15
  return String.fromCharCode(...units);
14
16
  }
15
17
  function parseToUnicodeCMap(bytes, sink) {
@@ -85,7 +87,7 @@ function readBfRange(reader, map, sink) {
85
87
  function registerBfRangeSingle(map, lo, hi, dstBytes) {
86
88
  if (dstBytes.length < 2) return;
87
89
  const prefix = decodeUtf16BEString(dstBytes.subarray(0, dstBytes.length - 2));
88
- const baseUnit = (dstBytes[dstBytes.length - 2] ?? 0) << 8 | (dstBytes[dstBytes.length - 1] ?? 0);
90
+ const baseUnit = (dstBytes[dstBytes.length - 2] ?? 0) << BITS_PER_BYTE | (dstBytes[dstBytes.length - 1] ?? 0);
89
91
  for (let code = lo; code <= hi; code++) map.set(code, prefix + String.fromCharCode(baseUnit + (code - lo)));
90
92
  }
91
93
  function readBfRangeArray(reader, map, lo, sink) {
package/dist/cmap.js CHANGED
@@ -1,14 +1,16 @@
1
1
  import { ByteReader } from "./bytes/reader.js";
2
2
  import { nextToken } from "./lexer.js";
3
3
  //#region src/cmap.ts
4
+ const BYTE_RADIX = 256;
5
+ const BITS_PER_BYTE = 8;
4
6
  function hexBytesToNumber(bytes) {
5
7
  let value = 0;
6
- for (const byte of bytes) value = value * 256 + byte;
8
+ for (const byte of bytes) value = value * BYTE_RADIX + byte;
7
9
  return value;
8
10
  }
9
11
  function decodeUtf16BEString(bytes) {
10
12
  const units = [];
11
- for (let i = 0; i + 1 < bytes.length; i += 2) units.push((bytes[i] ?? 0) << 8 | (bytes[i + 1] ?? 0));
13
+ for (let i = 0; i + 1 < bytes.length; i += 2) units.push((bytes[i] ?? 0) << BITS_PER_BYTE | (bytes[i + 1] ?? 0));
12
14
  return String.fromCharCode(...units);
13
15
  }
14
16
  function parseToUnicodeCMap(bytes, sink) {
@@ -84,7 +86,7 @@ function readBfRange(reader, map, sink) {
84
86
  function registerBfRangeSingle(map, lo, hi, dstBytes) {
85
87
  if (dstBytes.length < 2) return;
86
88
  const prefix = decodeUtf16BEString(dstBytes.subarray(0, dstBytes.length - 2));
87
- const baseUnit = (dstBytes[dstBytes.length - 2] ?? 0) << 8 | (dstBytes[dstBytes.length - 1] ?? 0);
89
+ const baseUnit = (dstBytes[dstBytes.length - 2] ?? 0) << BITS_PER_BYTE | (dstBytes[dstBytes.length - 1] ?? 0);
88
90
  for (let code = lo; code <= hi; code++) map.set(code, prefix + String.fromCharCode(baseUnit + (code - lo)));
89
91
  }
90
92
  function readBfRangeArray(reader, map, lo, sink) {
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_afm_widths = require("./afm-widths-BYiX2L9D.cjs");
2
+ const require_afm_widths = require("./afm-widths-BHD2HZIL.cjs");
3
3
  const require_objects = require("./objects.cjs");
4
4
  const require_bytes_writer = require("./bytes/writer.cjs");
5
5
  const require_serialize = require("./serialize.cjs");
@@ -8,6 +8,7 @@ const require_embedded_font = require("./embedded-font.cjs");
8
8
  //#region src/content-write.ts
9
9
  const GLYPH_SPACE_UNITS_PER_EM = 1e3;
10
10
  const EMBEDDED_HORIZONTAL_SCALE_PERCENT = 100;
11
+ const PERCENT_SCALE_FACTOR = 100;
11
12
  function writeRgbOperator(writer, color, operator) {
12
13
  writer.writeAscii(`${require_serialize.formatNumber(color.r)} ${require_serialize.formatNumber(color.g)} ${require_serialize.formatNumber(color.b)} ${operator}\n`);
13
14
  }
@@ -46,7 +47,7 @@ function writeShowTextBlock(writer, item, resourceName, scalePercent, show) {
46
47
  function writeStandardText(writer, item, standardName, resourceName, measurer) {
47
48
  const encoded = require_afm_widths.encodeForShow(item.text, standardName);
48
49
  const scale = measurer.horizontalScaleFor(item.font);
49
- writeShowTextBlock(writer, item, resourceName, scale * 100, {
50
+ writeShowTextBlock(writer, item, resourceName, scale * PERCENT_SCALE_FACTOR, {
50
51
  operand: require_objects.pdfHexString(encoded.codes),
51
52
  operator: "Tj"
52
53
  });
@@ -1,4 +1,4 @@
1
- import { h as encodeForShow } from "./afm-widths-blUDDjlI.js";
1
+ import { h as encodeForShow } from "./afm-widths-B_IGbGky.js";
2
2
  import { pdfArray, pdfHexString, pdfNum } from "./objects.js";
3
3
  import { ByteWriter } from "./bytes/writer.js";
4
4
  import { formatNumber, writeObject } from "./serialize.js";
@@ -7,6 +7,7 @@ import { encodeForShowEmbedded } from "./embedded-font.js";
7
7
  //#region src/content-write.ts
8
8
  const GLYPH_SPACE_UNITS_PER_EM = 1e3;
9
9
  const EMBEDDED_HORIZONTAL_SCALE_PERCENT = 100;
10
+ const PERCENT_SCALE_FACTOR = 100;
10
11
  function writeRgbOperator(writer, color, operator) {
11
12
  writer.writeAscii(`${formatNumber(color.r)} ${formatNumber(color.g)} ${formatNumber(color.b)} ${operator}\n`);
12
13
  }
@@ -45,7 +46,7 @@ function writeShowTextBlock(writer, item, resourceName, scalePercent, show) {
45
46
  function writeStandardText(writer, item, standardName, resourceName, measurer) {
46
47
  const encoded = encodeForShow(item.text, standardName);
47
48
  const scale = measurer.horizontalScaleFor(item.font);
48
- writeShowTextBlock(writer, item, resourceName, scale * 100, {
49
+ writeShowTextBlock(writer, item, resourceName, scale * PERCENT_SCALE_FACTOR, {
49
50
  operand: pdfHexString(encoded.codes),
50
51
  operator: "Tj"
51
52
  });