imagescript 3.2.1 → 3.4.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 (101) hide show
  1. package/README.md +35 -10
  2. package/THIRD_PARTY_NOTICES.md +298 -2
  3. package/dist/animation.d.ts +25 -8
  4. package/dist/animation.js +44 -13
  5. package/dist/codecs/av1/cdef.js +197 -0
  6. package/dist/codecs/av1/data.js +141 -0
  7. package/dist/codecs/av1/decode.js +1769 -0
  8. package/dist/codecs/av1/filmgrain.js +219 -0
  9. package/dist/codecs/av1/frame.js +114 -0
  10. package/dist/codecs/av1/ipred.js +491 -0
  11. package/dist/codecs/av1/itx.js +950 -0
  12. package/dist/codecs/av1/loopfilter.js +149 -0
  13. package/dist/codecs/av1/msac.js +161 -0
  14. package/dist/codecs/av1/obu.js +516 -0
  15. package/dist/codecs/av1/postfilter.js +28 -0
  16. package/dist/codecs/av1/restoration.js +193 -0
  17. package/dist/codecs/av1/tables.js +160 -0
  18. package/dist/codecs/avif.js +581 -0
  19. package/dist/codecs/bmp.js +317 -0
  20. package/dist/codecs/crc.js +5 -0
  21. package/dist/codecs/gif.js +10 -35
  22. package/dist/codecs/hdr.d.ts +25 -0
  23. package/dist/codecs/hdr.js +201 -0
  24. package/dist/codecs/ico.js +48 -0
  25. package/dist/codecs/jpeg.js +11 -28
  26. package/dist/codecs/jxl/bits.js +126 -0
  27. package/dist/codecs/jxl/blend.js +117 -0
  28. package/dist/codecs/jxl/color.js +116 -0
  29. package/dist/codecs/jxl/dct.js +404 -0
  30. package/dist/codecs/jxl/entropy.js +556 -0
  31. package/dist/codecs/jxl/features.js +325 -0
  32. package/dist/codecs/jxl/filters.js +119 -0
  33. package/dist/codecs/jxl/frame-header.js +195 -0
  34. package/dist/codecs/jxl/frame.js +319 -0
  35. package/dist/codecs/jxl/headers.js +249 -0
  36. package/dist/codecs/jxl/idct.js +484 -0
  37. package/dist/codecs/jxl/modular.js +688 -0
  38. package/dist/codecs/jxl/quant.js +219 -0
  39. package/dist/codecs/jxl/upsample.js +52 -0
  40. package/dist/codecs/jxl/vardct.js +472 -0
  41. package/dist/codecs/jxl.js +89 -0
  42. package/dist/codecs/netpbm.js +239 -0
  43. package/dist/codecs/png.js +22 -10
  44. package/dist/codecs/qoi.js +150 -0
  45. package/dist/codecs/tga.js +3 -1
  46. package/dist/codecs/tiff.js +7 -2
  47. package/dist/codecs/vp8-enc-dsp.js +932 -0
  48. package/dist/codecs/vp8-enc-tables.js +78 -0
  49. package/dist/codecs/vp8-enc.js +1930 -0
  50. package/dist/codecs/vp8.js +3 -1
  51. package/dist/codecs/vp8l.js +126 -58
  52. package/dist/codecs/webp.js +47 -11
  53. package/dist/codecs/zlib.js +81 -69
  54. package/dist/frame.d.ts +1 -0
  55. package/dist/frame.js +4 -2
  56. package/dist/gif.d.ts +1 -0
  57. package/dist/gif.js +2 -2
  58. package/dist/image-type.d.ts +15 -1
  59. package/dist/image-type.js +45 -2
  60. package/dist/image.d.ts +89 -13
  61. package/dist/image.js +266 -113
  62. package/dist/index.d.ts +3 -2
  63. package/dist/index.js +4 -4
  64. package/dist/render/bidi.js +350 -0
  65. package/dist/render/buffer.js +362 -0
  66. package/dist/render/color.js +164 -0
  67. package/dist/render/colr.js +523 -0
  68. package/dist/render/font.js +173 -241
  69. package/dist/render/hinting.js +38 -22
  70. package/dist/render/layout.js +1553 -0
  71. package/dist/render/linebreak.js +210 -0
  72. package/dist/render/segment.js +106 -0
  73. package/dist/render/shape.js +984 -0
  74. package/dist/render/shapers/arabic.js +284 -0
  75. package/dist/render/shapers/hangul.js +142 -0
  76. package/dist/render/shapers/hebrew.js +49 -0
  77. package/dist/render/shapers/index.js +52 -0
  78. package/dist/render/shapers/indic.js +579 -0
  79. package/dist/render/shapers/khmer.js +104 -0
  80. package/dist/render/shapers/machine.js +129 -0
  81. package/dist/render/shapers/myanmar.js +121 -0
  82. package/dist/render/shapers/syllabic.js +100 -0
  83. package/dist/render/shapers/thai.js +125 -0
  84. package/dist/render/shapers/use.js +235 -0
  85. package/dist/render/svg.js +102 -23
  86. package/dist/render/text.js +373 -103
  87. package/dist/render/unicode-data.js +63 -0
  88. package/dist/render/unicode.js +50 -0
  89. package/dist/text-layout.d.ts +4 -1
  90. package/dist/text-layout.js +2 -2
  91. package/dist/util/alpha.js +43 -0
  92. package/dist/util/blur.js +20 -33
  93. package/dist/util/bytes.js +40 -0
  94. package/dist/util/limits.js +34 -0
  95. package/dist/util/options.js +7 -0
  96. package/dist/util/resample.js +126 -7
  97. package/dist/util/rotate.js +43 -0
  98. package/dist/version.js +1 -1
  99. package/licenses/HarfBuzz.txt +42 -0
  100. package/licenses/Unicode-3.0.txt +39 -0
  101. package/package.json +25 -2
@@ -0,0 +1,210 @@
1
+ import { lineBreak, generalCategory, eastAsianWidth, extendedPictographic } from "./unicode-data.js";
2
+ import { value, valueIndex } from "./unicode.js";
3
+ const DOTTED_CIRCLE = 0x25cc;
4
+ export function lineBreaks(codepoints) {
5
+ const n = codepoints.length;
6
+ const breaks = new Uint8Array(n + 1);
7
+ if (!n)
8
+ return breaks;
9
+ const cls = new Array(n), gc = new Array(n), wide = new Uint8Array(n), pictographicCn = new Uint8Array(n), attached = new Uint8Array(n);
10
+ for (let i = 0; i < n; i++) {
11
+ const cp = codepoints[i];
12
+ let c = value(lineBreak, cp);
13
+ const g = value(generalCategory, cp);
14
+ if (c === 'AI' || c === 'SG' || c === 'XX')
15
+ c = 'AL';
16
+ else if (c === 'SA')
17
+ c = g === 'Mn' || g === 'Mc' ? 'CM' : 'AL';
18
+ else if (c === 'CJ')
19
+ c = 'NS';
20
+ cls[i] = c;
21
+ gc[i] = g;
22
+ const ea = value(eastAsianWidth, cp);
23
+ wide[i] = ea === 'F' || ea === 'W' || ea === 'H' ? 1 : 0;
24
+ pictographicCn[i] = valueIndex(extendedPictographic, cp) && g === 'Cn' ? 1 : 0;
25
+ }
26
+ const raw = cls.slice();
27
+ for (let i = 0; i < n; i++) {
28
+ if (cls[i] !== 'CM' && cls[i] !== 'ZWJ')
29
+ continue;
30
+ const base = i > 0 ? i - 1 : -1;
31
+ if (base >= 0 && !['BK', 'CR', 'LF', 'NL', 'SP', 'ZW'].includes(cls[base])) {
32
+ attached[i] = 1;
33
+ cls[i] = cls[base];
34
+ gc[i] = gc[base];
35
+ wide[i] = wide[base];
36
+ pictographicCn[i] = pictographicCn[base];
37
+ }
38
+ else {
39
+ cls[i] = 'AL';
40
+ gc[i] = 'Lu';
41
+ wide[i] = 0;
42
+ pictographicCn[i] = 0;
43
+ }
44
+ }
45
+ const before = (i) => {
46
+ let j = i - 1;
47
+ while (j >= 0 && attached[j])
48
+ j--;
49
+ return j;
50
+ };
51
+ const after = (i) => {
52
+ let j = i;
53
+ while (j < n && attached[j])
54
+ j++;
55
+ return j;
56
+ };
57
+ const beforeSpaces = (i) => {
58
+ let j = before(i);
59
+ while (j >= 0 && cls[j] === 'SP')
60
+ j = before(j);
61
+ return j;
62
+ };
63
+ const is = (j, ...classes) => j >= 0 && j < n && classes.includes(cls[j]);
64
+ for (let i = 1; i < n; i++) {
65
+ const a = i - 1, b = i;
66
+ const B = cls[b], rawA = raw[a], rawB = raw[b];
67
+ breaks[i] = (() => {
68
+ if (rawA === 'BK')
69
+ return 2;
70
+ if (rawA === 'CR' && rawB === 'LF')
71
+ return 0;
72
+ if (rawA === 'CR' || rawA === 'LF' || rawA === 'NL')
73
+ return 2;
74
+ if (rawB === 'BK' || rawB === 'CR' || rawB === 'LF' || rawB === 'NL')
75
+ return 0;
76
+ if (rawB === 'SP' || rawB === 'ZW')
77
+ return 0;
78
+ if (is(beforeSpaces(b), 'ZW') && raw[beforeSpaces(b)] === 'ZW')
79
+ return 1;
80
+ if (rawA === 'ZWJ')
81
+ return 0;
82
+ if (attached[b])
83
+ return 0;
84
+ const p = before(b), P = cls[p];
85
+ if (B === 'WJ' || P === 'WJ')
86
+ return 0;
87
+ if (P === 'GL')
88
+ return 0;
89
+ if (B === 'GL' && !['SP', 'HY', 'HH'].includes(P))
90
+ return 0;
91
+ if (B === 'CL' || B === 'CP' || B === 'EX' || B === 'SY')
92
+ return 0;
93
+ const s = beforeSpaces(b);
94
+ if (is(s, 'OP'))
95
+ return 0;
96
+ if (is(s, 'QU') && gc[s] === 'Pi') {
97
+ const q = before(s);
98
+ if (q < 0 || ['BK', 'CR', 'LF', 'NL', 'OP', 'QU', 'GL', 'SP', 'ZW'].includes(cls[q]))
99
+ return 0;
100
+ }
101
+ if (B === 'QU' && gc[b] === 'Pf') {
102
+ const q = after(b + 1);
103
+ if (q >= n || ['SP', 'GL', 'WJ', 'CL', 'QU', 'CP', 'EX', 'IS', 'SY', 'BK', 'CR', 'LF', 'NL', 'ZW'].includes(cls[q]))
104
+ return 0;
105
+ }
106
+ if (P === 'SP' && B === 'IS' && is(after(b + 1), 'NU'))
107
+ return 1;
108
+ if (B === 'IS')
109
+ return 0;
110
+ if (is(s, 'CL', 'CP') && B === 'NS')
111
+ return 0;
112
+ if (is(s, 'B2') && B === 'B2')
113
+ return 0;
114
+ if (P === 'SP')
115
+ return 1;
116
+ if (B === 'QU' && gc[b] !== 'Pi')
117
+ return 0;
118
+ if (P === 'QU' && gc[p] !== 'Pf')
119
+ return 0;
120
+ if (B === 'QU') {
121
+ if (!wide[p])
122
+ return 0;
123
+ const q = after(b + 1);
124
+ if (q >= n || !wide[q])
125
+ return 0;
126
+ }
127
+ if (P === 'QU') {
128
+ if (!wide[b])
129
+ return 0;
130
+ const q = before(p);
131
+ if (q < 0 || !wide[q])
132
+ return 0;
133
+ }
134
+ if (B === 'CB' || P === 'CB')
135
+ return 1;
136
+ if ((P === 'HY' || P === 'HH') && (B === 'AL' || B === 'HL')) {
137
+ const q = before(p);
138
+ if (q < 0 || ['BK', 'CR', 'LF', 'NL', 'SP', 'ZW', 'CB', 'GL'].includes(cls[q]))
139
+ return 0;
140
+ }
141
+ if (B === 'BA' || B === 'HH' || B === 'HY' || B === 'NS' || P === 'BB')
142
+ return 0;
143
+ if ((P === 'HY' || P === 'HH') && B !== 'HL' && is(before(p), 'HL'))
144
+ return 0;
145
+ if (P === 'SY' && B === 'HL')
146
+ return 0;
147
+ if (B === 'IN')
148
+ return 0;
149
+ if ((P === 'AL' || P === 'HL') && B === 'NU' || P === 'NU' && (B === 'AL' || B === 'HL'))
150
+ return 0;
151
+ if (P === 'PR' && (B === 'ID' || B === 'EB' || B === 'EM') || (P === 'ID' || P === 'EB' || P === 'EM') && B === 'PO')
152
+ return 0;
153
+ if ((P === 'PR' || P === 'PO') && (B === 'AL' || B === 'HL') || (P === 'AL' || P === 'HL') && (B === 'PR' || B === 'PO'))
154
+ return 0;
155
+ if (B === 'PO' || B === 'PR' || B === 'NU') {
156
+ let q = p;
157
+ if (B !== 'NU' && (cls[q] === 'CL' || cls[q] === 'CP'))
158
+ q = before(q);
159
+ while (is(q, 'SY', 'IS'))
160
+ q = before(q);
161
+ if (is(q, 'NU'))
162
+ return 0;
163
+ }
164
+ if ((P === 'PO' || P === 'PR') && B === 'OP') {
165
+ const q = after(b + 1);
166
+ if (is(q, 'NU') || is(q, 'IS') && is(after(q + 1), 'NU'))
167
+ return 0;
168
+ }
169
+ if ((P === 'PO' || P === 'PR' || P === 'HY' || P === 'IS') && B === 'NU')
170
+ return 0;
171
+ if (P === 'JL' && ['JL', 'JV', 'H2', 'H3'].includes(B))
172
+ return 0;
173
+ if ((P === 'JV' || P === 'H2') && (B === 'JV' || B === 'JT'))
174
+ return 0;
175
+ if ((P === 'JT' || P === 'H3') && B === 'JT')
176
+ return 0;
177
+ if (['JL', 'JV', 'JT', 'H2', 'H3'].includes(P) && B === 'PO' || P === 'PR' && ['JL', 'JV', 'JT', 'H2', 'H3'].includes(B))
178
+ return 0;
179
+ if ((P === 'AL' || P === 'HL') && (B === 'AL' || B === 'HL'))
180
+ return 0;
181
+ const aksara = (j) => is(j, 'AK', 'AS') || j >= 0 && j < n && codepoints[j] === DOTTED_CIRCLE;
182
+ if (P === 'AP' && aksara(b))
183
+ return 0;
184
+ if (aksara(p) && (B === 'VF' || B === 'VI'))
185
+ return 0;
186
+ if (P === 'VI' && aksara(before(p)) && (B === 'AK' || codepoints[b] === DOTTED_CIRCLE))
187
+ return 0;
188
+ if (aksara(p) && aksara(b) && is(after(b + 1), 'VF'))
189
+ return 0;
190
+ if (P === 'IS' && (B === 'AL' || B === 'HL'))
191
+ return 0;
192
+ if ((P === 'AL' || P === 'HL' || P === 'NU') && B === 'OP' && !wide[b])
193
+ return 0;
194
+ if (P === 'CP' && !wide[p] && (B === 'AL' || B === 'HL' || B === 'NU'))
195
+ return 0;
196
+ if (P === 'RI' && B === 'RI') {
197
+ let count = 0;
198
+ for (let q = p; is(q, 'RI'); q = before(q))
199
+ count++;
200
+ if (count % 2)
201
+ return 0;
202
+ }
203
+ if (B === 'EM' && (P === 'EB' || pictographicCn[p]))
204
+ return 0;
205
+ return 1;
206
+ })();
207
+ }
208
+ breaks[n] = 2;
209
+ return breaks;
210
+ }
@@ -0,0 +1,106 @@
1
+ import { graphemeBreak, conjunctBreak, extendedPictographic, script, brackets } from "./unicode-data.js";
2
+ import { value, valueIndex } from "./unicode.js";
3
+ export function graphemeBoundaries(codepoints) {
4
+ const n = codepoints.length, boundaries = new Uint8Array(n + 1);
5
+ if (!n)
6
+ return boundaries;
7
+ boundaries[0] = boundaries[n] = 1;
8
+ const gcb = new Array(n), incb = new Array(n), pictographic = new Uint8Array(n);
9
+ for (let i = 0; i < n; i++) {
10
+ gcb[i] = value(graphemeBreak, codepoints[i]);
11
+ incb[i] = value(conjunctBreak, codepoints[i]);
12
+ pictographic[i] = valueIndex(extendedPictographic, codepoints[i]) ? 1 : 0;
13
+ }
14
+ let emoji = false, emojiZWJ = false, ri = 0;
15
+ let linker = false;
16
+ for (let i = 1; i < n; i++) {
17
+ const a = gcb[i - 1], b = gcb[i];
18
+ emojiZWJ = emoji && a === 'ZWJ';
19
+ if (pictographic[i - 1])
20
+ emoji = true;
21
+ else if (a !== 'EX')
22
+ emoji = false;
23
+ ri = a === 'RI' ? ri + 1 : 0;
24
+ if (incb[i - 1] === 'Linker')
25
+ linker = true;
26
+ else if (incb[i - 1] !== 'Extend')
27
+ linker = false;
28
+ let boundary;
29
+ if (a === 'CR' && b === 'LF')
30
+ boundary = false;
31
+ else if (a === 'CN' || a === 'CR' || a === 'LF' || b === 'CN' || b === 'CR' || b === 'LF')
32
+ boundary = true;
33
+ else if (a === 'L' && (b === 'L' || b === 'V' || b === 'LV' || b === 'LVT'))
34
+ boundary = false;
35
+ else if ((a === 'LV' || a === 'V') && (b === 'V' || b === 'T'))
36
+ boundary = false;
37
+ else if ((a === 'LVT' || a === 'T') && b === 'T')
38
+ boundary = false;
39
+ else if (b === 'EX' || b === 'ZWJ' || b === 'SM' || a === 'PP')
40
+ boundary = false;
41
+ else if (linker && incb[i] === 'Consonant')
42
+ boundary = false;
43
+ else if (emojiZWJ && pictographic[i])
44
+ boundary = false;
45
+ else if (a === 'RI' && b === 'RI')
46
+ boundary = ri % 2 === 0;
47
+ else
48
+ boundary = true;
49
+ boundaries[i] = boundary ? 1 : 0;
50
+ }
51
+ return boundaries;
52
+ }
53
+ let pairs = null;
54
+ const closingOf = (u) => {
55
+ if (!pairs) {
56
+ pairs = new Map();
57
+ for (let i = 0; i < brackets.length; i += 3)
58
+ if (brackets[i + 2] === 1)
59
+ pairs.set(brackets[i], brackets[i + 1]);
60
+ }
61
+ return pairs.get(u) ?? 0;
62
+ };
63
+ export function scripts(codepoints) {
64
+ const n = codepoints.length, out = new Array(n);
65
+ let current = '';
66
+ const stack = [];
67
+ for (let i = 0; i < n; i++) {
68
+ const u = codepoints[i];
69
+ let s = value(script, u);
70
+ if (s === 'Zyyy' || s === 'Zinh' || s === 'Zzzz') {
71
+ const closing = closingOf(u);
72
+ if (closing) {
73
+ if (stack.length >= 64)
74
+ stack.shift();
75
+ stack.push([closing, current]);
76
+ s = current;
77
+ }
78
+ else {
79
+ let k = stack.length - 1;
80
+ while (k >= 0 && stack[k][0] !== u && !(u === 0x232a && stack[k][0] === 0x3009) && !(u === 0x3009 && stack[k][0] === 0x232a))
81
+ k--;
82
+ if (k >= 0) {
83
+ s = stack[k][1];
84
+ stack.length = k;
85
+ }
86
+ else
87
+ s = current;
88
+ }
89
+ }
90
+ else {
91
+ if (!current)
92
+ for (const entry of stack)
93
+ if (!entry[1])
94
+ entry[1] = s;
95
+ current = s;
96
+ }
97
+ out[i] = s;
98
+ }
99
+ const first = out.find(s => s) ?? 'Zyyy';
100
+ for (let i = 0; i < n && !out[i]; i++)
101
+ out[i] = first;
102
+ for (let i = 0; i < n; i++)
103
+ if (!out[i])
104
+ out[i] = first;
105
+ return out;
106
+ }