restty 0.1.16 → 0.1.18

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 (53) hide show
  1. package/README.md +4 -9
  2. package/dist/app/atlas-builder.d.ts +38 -0
  3. package/dist/app/font-sources.d.ts +2 -0
  4. package/dist/app/pane-app-manager.d.ts +43 -0
  5. package/dist/app/panes-context-menu.d.ts +10 -0
  6. package/dist/app/panes-styles.d.ts +5 -0
  7. package/dist/app/panes-types.d.ts +89 -0
  8. package/dist/app/panes.d.ts +10 -0
  9. package/dist/app/restty.d.ts +20 -0
  10. package/dist/app/session.d.ts +6 -0
  11. package/dist/app/types.d.ts +123 -0
  12. package/dist/{app/index.js → chunk-53vdvhe3.js} +24014 -23787
  13. package/dist/fonts/manager.d.ts +24 -0
  14. package/dist/fonts/nerd-constraints.d.ts +4 -0
  15. package/dist/fonts/nerd-ranges.d.ts +2 -0
  16. package/dist/fonts/types.d.ts +51 -0
  17. package/dist/grid/grid.d.ts +22 -0
  18. package/dist/grid/types.d.ts +32 -0
  19. package/dist/ime/ime.d.ts +13 -0
  20. package/dist/ime/types.d.ts +8 -0
  21. package/dist/input/ansi.d.ts +3 -0
  22. package/dist/input/mouse.d.ts +10 -0
  23. package/dist/input/output.d.ts +11 -0
  24. package/dist/input/types.d.ts +7 -0
  25. package/dist/internal.js +105 -56213
  26. package/dist/pty/kitty-media.d.ts +3 -0
  27. package/dist/pty/pty.d.ts +11 -0
  28. package/dist/pty/types.d.ts +49 -0
  29. package/dist/renderer/box-drawing-map.d.ts +4 -0
  30. package/dist/renderer/shaders.d.ts +7 -0
  31. package/dist/renderer/shapes.d.ts +42 -1
  32. package/dist/renderer/types.d.ts +43 -0
  33. package/dist/renderer/webgpu.d.ts +11 -0
  34. package/dist/restty.js +20 -0
  35. package/dist/selection/selection.d.ts +24 -0
  36. package/dist/selection/types.d.ts +13 -0
  37. package/dist/theme/catalog.d.ts +5 -0
  38. package/dist/theme/ghostty.d.ts +18 -0
  39. package/dist/unicode/ghostty-symbol-ranges.d.ts +1 -0
  40. package/dist/unicode/symbols.d.ts +6 -0
  41. package/dist/wasm/embedded.d.ts +1 -0
  42. package/dist/wasm/runtime.d.ts +29 -0
  43. package/package.json +8 -61
  44. package/dist/fonts/index.js +0 -5332
  45. package/dist/grid/index.js +0 -71
  46. package/dist/ime/index.js +0 -84
  47. package/dist/index.js +0 -56210
  48. package/dist/input/index.js +0 -1047
  49. package/dist/pty/index.js +0 -338
  50. package/dist/renderer/index.js +0 -1612
  51. package/dist/selection/index.js +0 -226
  52. package/dist/theme/index.js +0 -11218
  53. package/dist/wasm/index.js +0 -6003
@@ -1,1612 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, {
5
- get: all[name],
6
- enumerable: true,
7
- configurable: true,
8
- set: (newValue) => all[name] = () => newValue
9
- });
10
- };
11
-
12
- // src/renderer/box-drawing-map.ts
13
- var BOX_LINE_MAP = new Map([
14
- [9472, [0, 1, 0, 1]],
15
- [9473, [0, 2, 0, 2]],
16
- [9474, [1, 0, 1, 0]],
17
- [9475, [2, 0, 2, 0]],
18
- [9484, [0, 1, 1, 0]],
19
- [9485, [0, 2, 1, 0]],
20
- [9486, [0, 1, 2, 0]],
21
- [9487, [0, 2, 2, 0]],
22
- [9488, [0, 0, 1, 1]],
23
- [9489, [0, 0, 1, 2]],
24
- [9490, [0, 0, 2, 1]],
25
- [9491, [0, 0, 2, 2]],
26
- [9492, [1, 1, 0, 0]],
27
- [9493, [1, 2, 0, 0]],
28
- [9494, [2, 1, 0, 0]],
29
- [9495, [2, 2, 0, 0]],
30
- [9496, [1, 0, 0, 1]],
31
- [9497, [1, 0, 0, 2]],
32
- [9498, [2, 0, 0, 1]],
33
- [9499, [2, 0, 0, 2]],
34
- [9500, [1, 1, 1, 0]],
35
- [9501, [1, 2, 1, 0]],
36
- [9502, [2, 1, 1, 0]],
37
- [9503, [1, 1, 2, 0]],
38
- [9504, [2, 1, 2, 0]],
39
- [9505, [2, 2, 1, 0]],
40
- [9506, [1, 2, 2, 0]],
41
- [9507, [2, 2, 2, 0]],
42
- [9508, [1, 0, 1, 1]],
43
- [9509, [1, 0, 1, 2]],
44
- [9510, [2, 0, 1, 1]],
45
- [9511, [1, 0, 2, 1]],
46
- [9512, [2, 0, 2, 1]],
47
- [9513, [2, 0, 1, 2]],
48
- [9514, [1, 0, 2, 2]],
49
- [9515, [2, 0, 2, 2]],
50
- [9516, [0, 1, 1, 1]],
51
- [9517, [0, 1, 1, 2]],
52
- [9518, [0, 2, 1, 1]],
53
- [9519, [0, 2, 1, 2]],
54
- [9520, [0, 1, 2, 1]],
55
- [9521, [0, 1, 2, 2]],
56
- [9522, [0, 2, 2, 1]],
57
- [9523, [0, 2, 2, 2]],
58
- [9524, [1, 1, 0, 1]],
59
- [9525, [1, 1, 0, 2]],
60
- [9526, [1, 2, 0, 1]],
61
- [9527, [1, 2, 0, 2]],
62
- [9528, [2, 1, 0, 1]],
63
- [9529, [2, 1, 0, 2]],
64
- [9530, [2, 2, 0, 1]],
65
- [9531, [2, 2, 0, 2]],
66
- [9532, [1, 1, 1, 1]],
67
- [9533, [1, 1, 1, 2]],
68
- [9534, [1, 2, 1, 1]],
69
- [9535, [1, 2, 1, 2]],
70
- [9536, [2, 1, 1, 1]],
71
- [9537, [1, 1, 2, 1]],
72
- [9538, [2, 1, 2, 1]],
73
- [9539, [2, 1, 1, 2]],
74
- [9540, [2, 2, 1, 1]],
75
- [9541, [1, 1, 2, 2]],
76
- [9542, [1, 2, 2, 1]],
77
- [9543, [2, 2, 1, 2]],
78
- [9544, [1, 2, 2, 2]],
79
- [9545, [2, 1, 2, 2]],
80
- [9546, [2, 2, 2, 1]],
81
- [9547, [2, 2, 2, 2]],
82
- [9552, [0, 3, 0, 3]],
83
- [9553, [3, 0, 3, 0]],
84
- [9554, [0, 3, 1, 0]],
85
- [9555, [0, 1, 3, 0]],
86
- [9556, [0, 3, 3, 0]],
87
- [9557, [0, 0, 1, 3]],
88
- [9558, [0, 0, 3, 1]],
89
- [9559, [0, 0, 3, 3]],
90
- [9560, [1, 3, 0, 0]],
91
- [9561, [3, 1, 0, 0]],
92
- [9562, [3, 3, 0, 0]],
93
- [9563, [1, 0, 0, 3]],
94
- [9564, [3, 0, 0, 1]],
95
- [9565, [3, 0, 0, 3]],
96
- [9566, [1, 3, 1, 0]],
97
- [9567, [3, 1, 3, 0]],
98
- [9568, [3, 3, 3, 0]],
99
- [9569, [1, 0, 1, 3]],
100
- [9570, [3, 0, 3, 1]],
101
- [9571, [3, 0, 3, 3]],
102
- [9572, [0, 3, 1, 3]],
103
- [9573, [0, 1, 3, 1]],
104
- [9574, [0, 3, 3, 3]],
105
- [9575, [1, 3, 0, 3]],
106
- [9576, [3, 1, 0, 1]],
107
- [9577, [3, 3, 0, 3]],
108
- [9578, [1, 3, 1, 3]],
109
- [9579, [3, 1, 3, 1]],
110
- [9580, [3, 3, 3, 3]],
111
- [9588, [0, 0, 0, 1]],
112
- [9589, [1, 0, 0, 0]],
113
- [9590, [0, 1, 0, 0]],
114
- [9591, [0, 0, 1, 0]],
115
- [9592, [0, 0, 0, 2]],
116
- [9593, [2, 0, 0, 0]],
117
- [9594, [0, 2, 0, 0]],
118
- [9595, [0, 0, 2, 0]],
119
- [9596, [0, 2, 0, 1]],
120
- [9597, [1, 0, 2, 0]],
121
- [9598, [0, 1, 0, 2]],
122
- [9599, [2, 0, 1, 0]]
123
- ]);
124
-
125
- // src/renderer/shapes.ts
126
- var BOX_STYLE_NONE = 0;
127
- var BOX_STYLE_LIGHT = 1;
128
- var BOX_STYLE_HEAVY = 2;
129
- var BOX_STYLE_DOUBLE = 3;
130
- function isPrivateUse(cp) {
131
- return cp >= 57344 && cp <= 63743 || cp >= 983040 && cp <= 1048573 || cp >= 1048576 && cp <= 1114109;
132
- }
133
- function isSpaceCp(cp) {
134
- return cp === 0 || cp === 32 || cp === 8194;
135
- }
136
- function isBoxDrawing(cp) {
137
- return cp >= 9472 && cp <= 9599;
138
- }
139
- function isBlockElement(cp) {
140
- return cp >= 9600 && cp <= 9631;
141
- }
142
- function isLegacyComputing(cp) {
143
- return cp >= 129792 && cp <= 130047 || cp >= 117760 && cp <= 118463;
144
- }
145
- function isPowerline(cp) {
146
- return cp >= 57520 && cp <= 57559;
147
- }
148
- function isBraille(cp) {
149
- return cp >= 10240 && cp <= 10495;
150
- }
151
- function isGraphicsElement(cp) {
152
- return isBoxDrawing(cp) || isBlockElement(cp) || isLegacyComputing(cp) || isPowerline(cp);
153
- }
154
- function isSymbolCp(cp) {
155
- return isPrivateUse(cp) || isGraphicsElement(cp);
156
- }
157
- function applyAlpha(color, alpha) {
158
- return [color[0], color[1], color[2], color[3] * alpha];
159
- }
160
- function pushRect(out, x, y, w, h, color) {
161
- out.push(x, y, w, h, color[0], color[1], color[2], color[3]);
162
- }
163
- function pushRectSnapped(out, x, y, w, h, color) {
164
- const x0 = Math.floor(x);
165
- const y0 = Math.floor(y);
166
- const x1 = Math.ceil(x + w);
167
- const y1 = Math.ceil(y + h);
168
- const width = Math.max(0, x1 - x0);
169
- const height = Math.max(0, y1 - y0);
170
- if (width <= 0 || height <= 0)
171
- return;
172
- out.push(x0, y0, width, height, color[0], color[1], color[2], color[3]);
173
- }
174
- function pushRectBox(out, x, y, w, h, color) {
175
- const x0 = Math.round(x);
176
- const y0 = Math.round(y);
177
- const width = Math.max(1, Math.round(w));
178
- const height = Math.max(1, Math.round(h));
179
- if (width <= 0 || height <= 0)
180
- return;
181
- out.push(x0, y0, width, height, color[0], color[1], color[2], color[3]);
182
- }
183
- function fillFrac(out, x, y, cellW, cellH, fx0, fx1, fy0, fy1, color) {
184
- const px0 = x + cellW * fx0;
185
- const px1 = x + cellW * fx1;
186
- const py0 = y + cellH * fy0;
187
- const py1 = y + cellH * fy1;
188
- pushRectSnapped(out, px0, py0, px1 - px0, py1 - py0, color);
189
- }
190
- function drawBlockElement(cp, x, y, cellW, cellH, color, out) {
191
- const full = () => pushRectSnapped(out, x, y, cellW, cellH, color);
192
- const lower = (fraction) => fillFrac(out, x, y, cellW, cellH, 0, 1, 1 - fraction, 1, color);
193
- const upper = (fraction) => fillFrac(out, x, y, cellW, cellH, 0, 1, 0, fraction, color);
194
- const left = (fraction) => fillFrac(out, x, y, cellW, cellH, 0, fraction, 0, 1, color);
195
- const right = (fraction) => fillFrac(out, x, y, cellW, cellH, 1 - fraction, 1, 0, 1, color);
196
- switch (cp) {
197
- case 9600:
198
- upper(0.5);
199
- return true;
200
- case 9601:
201
- lower(0.125);
202
- return true;
203
- case 9602:
204
- lower(0.25);
205
- return true;
206
- case 9603:
207
- lower(0.375);
208
- return true;
209
- case 9604:
210
- lower(0.5);
211
- return true;
212
- case 9605:
213
- lower(0.625);
214
- return true;
215
- case 9606:
216
- lower(0.75);
217
- return true;
218
- case 9607:
219
- lower(0.875);
220
- return true;
221
- case 9608:
222
- full();
223
- return true;
224
- case 9609:
225
- left(0.875);
226
- return true;
227
- case 9610:
228
- left(0.75);
229
- return true;
230
- case 9611:
231
- left(0.625);
232
- return true;
233
- case 9612:
234
- left(0.5);
235
- return true;
236
- case 9613:
237
- left(0.375);
238
- return true;
239
- case 9614:
240
- left(0.25);
241
- return true;
242
- case 9615:
243
- left(0.125);
244
- return true;
245
- case 9616:
246
- right(0.5);
247
- return true;
248
- case 9617:
249
- pushRectSnapped(out, x, y, cellW, cellH, applyAlpha(color, 0.25));
250
- return true;
251
- case 9618:
252
- pushRectSnapped(out, x, y, cellW, cellH, applyAlpha(color, 0.5));
253
- return true;
254
- case 9619:
255
- pushRectSnapped(out, x, y, cellW, cellH, applyAlpha(color, 0.75));
256
- return true;
257
- case 9620:
258
- upper(0.125);
259
- return true;
260
- case 9621:
261
- right(0.125);
262
- return true;
263
- case 9622:
264
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0.5, 1, color);
265
- return true;
266
- case 9623:
267
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0.5, 1, color);
268
- return true;
269
- case 9624:
270
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0, 0.5, color);
271
- return true;
272
- case 9625:
273
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0, 1, color);
274
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0.5, 1, color);
275
- return true;
276
- case 9626:
277
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0, 0.5, color);
278
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0.5, 1, color);
279
- return true;
280
- case 9627:
281
- fillFrac(out, x, y, cellW, cellH, 0, 1, 0, 0.5, color);
282
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0.5, 1, color);
283
- return true;
284
- case 9628:
285
- fillFrac(out, x, y, cellW, cellH, 0, 1, 0, 0.5, color);
286
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0.5, 1, color);
287
- return true;
288
- case 9629:
289
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0, 0.5, color);
290
- return true;
291
- case 9630:
292
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0, 0.5, color);
293
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0.5, 1, color);
294
- return true;
295
- case 9631:
296
- fillFrac(out, x, y, cellW, cellH, 0.5, 1, 0, 1, color);
297
- fillFrac(out, x, y, cellW, cellH, 0, 0.5, 0.5, 1, color);
298
- return true;
299
- default:
300
- return false;
301
- }
302
- }
303
- function drawBoxDrawing(cp, x, y, cellW, cellH, color, out) {
304
- const spec = BOX_LINE_MAP.get(cp);
305
- if (!spec) {
306
- const minDim2 = Math.min(cellW, cellH);
307
- const light2 = Math.max(1, Math.round(minDim2 * 0.08));
308
- const heavy2 = Math.max(light2 + 1, Math.round(light2 * 1.8));
309
- const dashedH = (count, thickness) => {
310
- const gap2 = Math.max(1, Math.round(thickness));
311
- const totalGap = gap2 * (count - 1);
312
- const seg = Math.max(1, Math.floor((cellW - totalGap) / count));
313
- const y0 = y + cellH * 0.5 - thickness * 0.5;
314
- let px = x;
315
- for (let i = 0;i < count; i += 1) {
316
- pushRectBox(out, px, y0, seg, thickness, color);
317
- px += seg + gap2;
318
- }
319
- };
320
- const dashedV = (count, thickness) => {
321
- const gap2 = Math.max(1, Math.round(thickness));
322
- const totalGap = gap2 * (count - 1);
323
- const seg = Math.max(1, Math.floor((cellH - totalGap) / count));
324
- const x0 = x + cellW * 0.5 - thickness * 0.5;
325
- let py = y;
326
- for (let i = 0;i < count; i += 1) {
327
- pushRectBox(out, x0, py, thickness, seg, color);
328
- py += seg + gap2;
329
- }
330
- };
331
- const drawDiagonal = (dir) => {
332
- const thickness = light2;
333
- const steps = Math.max(2, Math.round(Math.max(cellW, cellH)));
334
- for (let i = 0;i < steps; i += 1) {
335
- const t = steps === 1 ? 0 : i / (steps - 1);
336
- const px = dir === "ul_lr" ? x + t * cellW : x + (1 - t) * cellW;
337
- const py = y + t * cellH;
338
- pushRectBox(out, px - thickness * 0.5, py - thickness * 0.5, thickness, thickness, color);
339
- }
340
- };
341
- const drawArc = (corner) => {
342
- const thickness = light2;
343
- const halfThick = thickness * 0.5;
344
- const cx2 = x + cellW * 0.5;
345
- const cy2 = y + cellH * 0.5;
346
- const r = Math.min(cellW, cellH) * 0.5;
347
- const steps = Math.max(24, Math.round(r * 4));
348
- const s = 0.25;
349
- const cubicBezier = (x0, y0, cx1, cy1, cx22, cy22, x1, y1) => {
350
- for (let i = 0;i <= steps; i++) {
351
- const t = i / steps;
352
- const mt = 1 - t;
353
- const px = mt * mt * mt * x0 + 3 * mt * mt * t * cx1 + 3 * mt * t * t * cx22 + t * t * t * x1;
354
- const py = mt * mt * mt * y0 + 3 * mt * mt * t * cy1 + 3 * mt * t * t * cy22 + t * t * t * y1;
355
- pushRectBox(out, px - halfThick, py - halfThick, thickness, thickness, color);
356
- }
357
- };
358
- if (corner === "br") {
359
- pushRectBox(out, cx2 - halfThick, cy2 + r, thickness, y + cellH - (cy2 + r), color);
360
- cubicBezier(cx2, cy2 + r, cx2, cy2 + s * r, cx2 + s * r, cy2, cx2 + r, cy2);
361
- pushRectBox(out, cx2 + r, cy2 - halfThick, x + cellW - (cx2 + r), thickness, color);
362
- } else if (corner === "bl") {
363
- pushRectBox(out, cx2 - halfThick, cy2 + r, thickness, y + cellH - (cy2 + r), color);
364
- cubicBezier(cx2, cy2 + r, cx2, cy2 + s * r, cx2 - s * r, cy2, cx2 - r, cy2);
365
- pushRectBox(out, x, cy2 - halfThick, cx2 - r - x, thickness, color);
366
- } else if (corner === "tl") {
367
- pushRectBox(out, cx2 - halfThick, y, thickness, cy2 - r - y, color);
368
- cubicBezier(cx2, cy2 - r, cx2, cy2 - s * r, cx2 - s * r, cy2, cx2 - r, cy2);
369
- pushRectBox(out, x, cy2 - halfThick, cx2 - r - x, thickness, color);
370
- } else {
371
- pushRectBox(out, cx2 - halfThick, y, thickness, cy2 - r - y, color);
372
- cubicBezier(cx2, cy2 - r, cx2, cy2 - s * r, cx2 + s * r, cy2, cx2 + r, cy2);
373
- pushRectBox(out, cx2 + r, cy2 - halfThick, x + cellW - (cx2 + r), thickness, color);
374
- }
375
- };
376
- switch (cp) {
377
- case 9476:
378
- dashedH(3, light2);
379
- return true;
380
- case 9477:
381
- dashedH(3, heavy2);
382
- return true;
383
- case 9480:
384
- dashedH(4, light2);
385
- return true;
386
- case 9481:
387
- dashedH(4, heavy2);
388
- return true;
389
- case 9478:
390
- dashedV(3, light2);
391
- return true;
392
- case 9479:
393
- dashedV(3, heavy2);
394
- return true;
395
- case 9482:
396
- dashedV(4, light2);
397
- return true;
398
- case 9483:
399
- dashedV(4, heavy2);
400
- return true;
401
- case 9548:
402
- dashedH(2, light2);
403
- return true;
404
- case 9549:
405
- dashedH(2, heavy2);
406
- return true;
407
- case 9550:
408
- dashedV(2, light2);
409
- return true;
410
- case 9551:
411
- dashedV(2, heavy2);
412
- return true;
413
- case 9581:
414
- drawArc("br");
415
- return true;
416
- case 9582:
417
- drawArc("bl");
418
- return true;
419
- case 9583:
420
- drawArc("tl");
421
- return true;
422
- case 9584:
423
- drawArc("tr");
424
- return true;
425
- case 9585:
426
- drawDiagonal("ur_ll");
427
- return true;
428
- case 9586:
429
- drawDiagonal("ul_lr");
430
- return true;
431
- case 9587:
432
- drawDiagonal("ul_lr");
433
- drawDiagonal("ur_ll");
434
- return true;
435
- default:
436
- return false;
437
- }
438
- }
439
- const [up, right, down, left] = spec;
440
- const minDim = Math.min(cellW, cellH);
441
- const light = Math.max(1, Math.round(minDim * 0.08));
442
- const heavy = Math.max(light + 1, Math.round(light * 1.8));
443
- const gap = Math.max(1, Math.round(light));
444
- const cx = x + cellW * 0.5;
445
- const cy = y + cellH * 0.5;
446
- const drawH = (style, x0, x1) => {
447
- if (style === BOX_STYLE_NONE)
448
- return;
449
- if (x1 <= x0)
450
- return;
451
- const thickness = style === BOX_STYLE_HEAVY ? heavy : light;
452
- const t = Math.max(1, Math.round(thickness));
453
- if (style === BOX_STYLE_DOUBLE) {
454
- const offset = (gap + t) * 0.5;
455
- const y02 = cy - offset - t * 0.5;
456
- const y1 = cy + offset - t * 0.5;
457
- pushRectSnapped(out, x0, y02, x1 - x0, t, color);
458
- pushRectSnapped(out, x0, y1, x1 - x0, t, color);
459
- return;
460
- }
461
- const y0 = cy - t * 0.5;
462
- pushRectSnapped(out, x0, y0, x1 - x0, t, color);
463
- };
464
- const drawV = (style, y0, y1) => {
465
- if (style === BOX_STYLE_NONE)
466
- return;
467
- if (y1 <= y0)
468
- return;
469
- const thickness = style === BOX_STYLE_HEAVY ? heavy : light;
470
- const t = Math.max(1, Math.round(thickness));
471
- if (style === BOX_STYLE_DOUBLE) {
472
- const offset = (gap + t) * 0.5;
473
- const x02 = cx - offset - t * 0.5;
474
- const x1 = cx + offset - t * 0.5;
475
- pushRectSnapped(out, x02, y0, t, y1 - y0, color);
476
- pushRectSnapped(out, x1, y0, t, y1 - y0, color);
477
- return;
478
- }
479
- const x0 = cx - t * 0.5;
480
- pushRectSnapped(out, x0, y0, t, y1 - y0, color);
481
- };
482
- if (left !== BOX_STYLE_NONE && left === right)
483
- drawH(left, x, x + cellW);
484
- else {
485
- drawH(left, x, cx);
486
- drawH(right, cx, x + cellW);
487
- }
488
- if (up !== BOX_STYLE_NONE && up === down)
489
- drawV(up, y, y + cellH);
490
- else {
491
- drawV(up, y, cy);
492
- drawV(down, cy, y + cellH);
493
- }
494
- return true;
495
- }
496
- function drawBraille(cp, x, y, cellW, cellH, color, out) {
497
- if (!isBraille(cp))
498
- return false;
499
- const bits = cp - 10240;
500
- if (!bits)
501
- return true;
502
- const dotW = Math.max(1, Math.round(cellW * 0.18));
503
- const dotH = Math.max(1, Math.round(cellH * 0.18));
504
- const colX = [x + cellW * 0.25 - dotW * 0.5, x + cellW * 0.75 - dotW * 0.5];
505
- const rowY = [
506
- y + cellH * 0.125 - dotH * 0.5,
507
- y + cellH * 0.375 - dotH * 0.5,
508
- y + cellH * 0.625 - dotH * 0.5,
509
- y + cellH * 0.875 - dotH * 0.5
510
- ];
511
- const dots = [
512
- [0, 0, 1],
513
- [0, 1, 2],
514
- [0, 2, 4],
515
- [1, 0, 8],
516
- [1, 1, 16],
517
- [1, 2, 32],
518
- [0, 3, 64],
519
- [1, 3, 128]
520
- ];
521
- for (const [cx, cy, mask] of dots) {
522
- if (bits & mask) {
523
- pushRectSnapped(out, colX[cx], rowY[cy], dotW, dotH, color);
524
- }
525
- }
526
- return true;
527
- }
528
- function drawPowerline(cp, x, y, cellW, cellH, color, out) {
529
- if (!isPowerline(cp))
530
- return false;
531
- const w = cellW;
532
- const h = cellH;
533
- const steps = Math.max(2, Math.round(Math.max(w, h)));
534
- const drawTriangle = (mode) => {
535
- for (let i = 0;i < steps; i += 1) {
536
- const t = steps === 1 ? 0 : i / (steps - 1);
537
- const py = y + t * h;
538
- let x0 = x;
539
- let x1 = x + w;
540
- if (mode === "right") {
541
- const span = w * (1 - Math.abs(t - 0.5) * 2);
542
- x1 = x + span;
543
- } else if (mode === "left") {
544
- const span = w * (1 - Math.abs(t - 0.5) * 2);
545
- x0 = x + (w - span);
546
- } else if (mode === "diag_ul_lr") {
547
- x1 = x + t * w;
548
- } else if (mode === "diag_ur_ll") {
549
- x0 = x + t * w;
550
- } else if (mode === "diag_ul_lr_inv") {
551
- x1 = x + (1 - t) * w;
552
- } else if (mode === "diag_ur_ll_inv") {
553
- x0 = x + (1 - t) * w;
554
- }
555
- pushRectSnapped(out, x0, py, Math.max(1, x1 - x0), 1, color);
556
- }
557
- };
558
- switch (cp) {
559
- case 57520:
560
- drawTriangle("right");
561
- return true;
562
- case 57522:
563
- drawTriangle("left");
564
- return true;
565
- case 57528:
566
- drawTriangle("diag_ul_lr");
567
- return true;
568
- case 57530:
569
- drawTriangle("diag_ur_ll");
570
- return true;
571
- case 57532:
572
- drawTriangle("diag_ul_lr_inv");
573
- return true;
574
- case 57534:
575
- drawTriangle("diag_ur_ll_inv");
576
- return true;
577
- case 57529:
578
- case 57531:
579
- case 57533:
580
- case 57535:
581
- case 57521:
582
- case 57523:
583
- drawTriangle(cp === 57529 || cp === 57535 ? "diag_ul_lr" : "diag_ur_ll");
584
- return true;
585
- default:
586
- return false;
587
- }
588
- }
589
- function constrainGlyphBox(glyph, constraint, metrics, constraintWidth) {
590
- if (!constraint)
591
- return glyph;
592
- const sizeMode = constraint.size ?? "none";
593
- const alignH = constraint.align_horizontal ?? "none";
594
- const alignV = constraint.align_vertical ?? "none";
595
- const padLeft = constraint.pad_left ?? 0;
596
- const padRight = constraint.pad_right ?? 0;
597
- const padTop = constraint.pad_top ?? 0;
598
- const padBottom = constraint.pad_bottom ?? 0;
599
- const relW = constraint.relative_width ?? 1;
600
- const relH = constraint.relative_height ?? 1;
601
- const relX = constraint.relative_x ?? 0;
602
- const relY = constraint.relative_y ?? 0;
603
- const maxWidth = constraint.max_constraint_width ?? 2;
604
- const minConstraintWidth = Math.min(constraintWidth, maxWidth);
605
- if (glyph.width <= 0 || glyph.height <= 0)
606
- return glyph;
607
- const groupWidth = glyph.width / relW;
608
- const groupHeight = glyph.height / relH;
609
- let groupX = glyph.x - groupWidth * relX;
610
- let groupY = glyph.y - groupHeight * relY;
611
- const padWidthFactor = minConstraintWidth - (padLeft + padRight);
612
- const padHeightFactor = 1 - (padBottom + padTop);
613
- const targetWidth = padWidthFactor * metrics.faceWidth;
614
- const baseHeight = (constraint.height ?? "cell") === "icon" ? minConstraintWidth > 1 ? metrics.iconHeight : metrics.iconHeightSingle : metrics.faceHeight;
615
- const targetHeight = padHeightFactor * baseHeight;
616
- let widthFactor = targetWidth / groupWidth;
617
- let heightFactor = targetHeight / groupHeight;
618
- const scaleDownFit = Math.min(1, widthFactor, heightFactor);
619
- const scaleCover = Math.min(widthFactor, heightFactor);
620
- if (sizeMode === "fit") {
621
- widthFactor = scaleDownFit;
622
- heightFactor = scaleDownFit;
623
- } else if (sizeMode === "cover") {
624
- widthFactor = scaleCover;
625
- heightFactor = scaleCover;
626
- } else if (sizeMode === "fit_cover1") {
627
- widthFactor = scaleCover;
628
- heightFactor = scaleCover;
629
- if (minConstraintWidth > 1 && heightFactor > 1) {
630
- const single = constrainGlyphBox({ x: 0, y: 0, width: groupWidth, height: groupHeight }, { ...constraint, max_constraint_width: 1 }, metrics, 1);
631
- const singleScale = single.height / groupHeight;
632
- heightFactor = Math.max(1, singleScale);
633
- widthFactor = heightFactor;
634
- }
635
- } else if (sizeMode === "stretch") {} else {
636
- widthFactor = 1;
637
- heightFactor = 1;
638
- }
639
- if (constraint.max_xy_ratio !== undefined && constraint.max_xy_ratio !== null) {
640
- const ratio = constraint.max_xy_ratio;
641
- if (groupWidth * widthFactor > groupHeight * heightFactor * ratio) {
642
- widthFactor = groupHeight * heightFactor * ratio / groupWidth;
643
- }
644
- }
645
- const centerX = groupX + groupWidth * 0.5;
646
- const centerY = groupY + groupHeight * 0.5;
647
- const scaledGroupWidth = groupWidth * widthFactor;
648
- const scaledGroupHeight = groupHeight * heightFactor;
649
- groupX = centerX - scaledGroupWidth * 0.5;
650
- groupY = centerY - scaledGroupHeight * 0.5;
651
- const padBottomDy = padBottom * metrics.faceHeight;
652
- const padTopDy = padTop * metrics.faceHeight;
653
- const startY = metrics.faceY + padBottomDy;
654
- const endY = metrics.faceY + (metrics.faceHeight - scaledGroupHeight - padTopDy);
655
- const centerYAligned = (startY + endY) * 0.5;
656
- if (!(sizeMode === "none" && alignV === "none")) {
657
- if (alignV === "start")
658
- groupY = startY;
659
- else if (alignV === "end")
660
- groupY = endY;
661
- else if (alignV === "center" || alignV === "center1")
662
- groupY = centerYAligned;
663
- else
664
- groupY = Math.max(startY, Math.min(groupY, endY));
665
- }
666
- const padLeftDx = padLeft * metrics.faceWidth;
667
- const padRightDx = padRight * metrics.faceWidth;
668
- const fullFaceSpan = metrics.faceWidth + (minConstraintWidth - 1) * metrics.cellWidth;
669
- const startX = padLeftDx;
670
- const endX = fullFaceSpan - scaledGroupWidth - padRightDx;
671
- if (!(sizeMode === "none" && alignH === "none")) {
672
- if (alignH === "start")
673
- groupX = startX;
674
- else if (alignH === "end")
675
- groupX = Math.max(startX, endX);
676
- else if (alignH === "center")
677
- groupX = Math.max(startX, (startX + endX) * 0.5);
678
- else if (alignH === "center1") {
679
- const end1 = metrics.faceWidth - scaledGroupWidth - padRightDx;
680
- groupX = Math.max(startX, (startX + end1) * 0.5);
681
- } else {
682
- groupX = Math.max(startX, Math.min(groupX, endX));
683
- }
684
- }
685
- return {
686
- width: glyph.width * widthFactor,
687
- height: glyph.height * heightFactor,
688
- x: groupX + scaledGroupWidth * relX,
689
- y: groupY + scaledGroupHeight * relY
690
- };
691
- }
692
- // src/renderer/shaders.ts
693
- var RECT_SHADER = `
694
- struct Uniforms {
695
- res: vec2f,
696
- _pad: vec2f,
697
- blend: vec2f,
698
- _pad2: vec2f,
699
- };
700
-
701
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
702
-
703
- struct VSIn {
704
- @location(0) quad: vec2f,
705
- @location(1) pos: vec2f,
706
- @location(2) size: vec2f,
707
- @location(3) color: vec4f,
708
- };
709
-
710
- struct VSOut {
711
- @builtin(position) position: vec4f,
712
- @location(0) color: vec4f,
713
- };
714
-
715
- // sRGB to linear conversion for proper blending
716
- fn srgbToLinear(c: f32) -> f32 {
717
- if (c <= 0.04045) {
718
- return c / 12.92;
719
- }
720
- return pow((c + 0.055) / 1.055, 2.4);
721
- }
722
-
723
- fn srgbToLinear3(c: vec3f) -> vec3f {
724
- return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));
725
- }
726
-
727
- @vertex
728
- fn vsMain(input: VSIn) -> VSOut {
729
- let pixel = input.pos + input.quad * input.size;
730
- let clip = vec2f(
731
- (pixel.x / uniforms.res.x) * 2.0 - 1.0,
732
- 1.0 - (pixel.y / uniforms.res.y) * 2.0
733
- );
734
-
735
- var out: VSOut;
736
- out.position = vec4f(clip.x, clip.y, 0.0, 1.0);
737
- out.color = input.color;
738
- return out;
739
- }
740
-
741
- @fragment
742
- fn fsMain(input: VSOut) -> @location(0) vec4f {
743
- let useLinear = uniforms.blend.x > 0.5;
744
- var color = input.color;
745
- if (useLinear) {
746
- color = vec4f(srgbToLinear3(color.rgb), color.a);
747
- }
748
- color = vec4f(color.rgb * color.a, color.a);
749
- return color;
750
- }
751
- `;
752
- var RECT_SHADER_GL_VERT = `#version 300 es
753
- precision highp float;
754
-
755
- uniform vec2 u_resolution;
756
-
757
- layout(location = 0) in vec2 a_quad;
758
- layout(location = 1) in vec2 a_pos;
759
- layout(location = 2) in vec2 a_size;
760
- layout(location = 3) in vec4 a_color;
761
-
762
- out vec4 v_color;
763
-
764
- void main() {
765
- vec2 pixel = a_pos + a_quad * a_size;
766
- vec2 clip = vec2(
767
- (pixel.x / u_resolution.x) * 2.0 - 1.0,
768
- 1.0 - (pixel.y / u_resolution.y) * 2.0
769
- );
770
- gl_Position = vec4(clip, 0.0, 1.0);
771
- v_color = a_color;
772
- }
773
- `;
774
- var RECT_SHADER_GL_FRAG = `#version 300 es
775
- precision highp float;
776
-
777
- uniform vec2 u_blend;
778
-
779
- in vec4 v_color;
780
- out vec4 fragColor;
781
-
782
- // sRGB to linear conversion for proper blending
783
- float srgbToLinear(float c) {
784
- if (c <= 0.04045) {
785
- return c / 12.92;
786
- }
787
- return pow((c + 0.055) / 1.055, 2.4);
788
- }
789
-
790
- vec3 srgbToLinear(vec3 c) {
791
- return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));
792
- }
793
-
794
- void main() {
795
- bool useLinear = u_blend.x > 0.5;
796
- vec4 color = v_color;
797
- if (useLinear) {
798
- color.rgb = srgbToLinear(color.rgb);
799
- }
800
- color.rgb *= color.a;
801
- fragColor = color;
802
- }
803
- `;
804
- var GLYPH_SHADER_GL_VERT = `#version 300 es
805
- precision highp float;
806
-
807
- uniform vec2 u_resolution;
808
-
809
- layout(location = 0) in vec2 a_quad;
810
- layout(location = 1) in vec2 a_pos;
811
- layout(location = 2) in vec2 a_size;
812
- layout(location = 3) in vec2 a_uv0;
813
- layout(location = 4) in vec2 a_uv1;
814
- layout(location = 5) in vec4 a_color;
815
- layout(location = 6) in vec4 a_bg;
816
- layout(location = 7) in float a_slant;
817
- layout(location = 8) in float a_mode;
818
-
819
- out vec2 v_uv;
820
- out vec4 v_color;
821
- out vec4 v_bg;
822
- out float v_mode;
823
-
824
- void main() {
825
- vec2 pixel = a_pos + vec2(a_quad.x * a_size.x + a_slant * (1.0 - a_quad.y), a_quad.y * a_size.y);
826
- vec2 clip = vec2(
827
- (pixel.x / u_resolution.x) * 2.0 - 1.0,
828
- 1.0 - (pixel.y / u_resolution.y) * 2.0
829
- );
830
- v_uv = a_uv0 + (a_uv1 - a_uv0) * a_quad;
831
- gl_Position = vec4(clip, 0.0, 1.0);
832
- v_color = a_color;
833
- v_bg = a_bg;
834
- v_mode = a_mode;
835
- }
836
- `;
837
- var GLYPH_SHADER_GL_FRAG = `#version 300 es
838
- precision highp float;
839
-
840
- uniform sampler2D u_atlas;
841
- uniform vec2 u_blend;
842
-
843
- in vec2 v_uv;
844
- in vec4 v_color;
845
- in vec4 v_bg;
846
- in float v_mode;
847
- out vec4 fragColor;
848
-
849
- // sRGB to linear conversion for proper blending
850
- float srgbToLinear(float c) {
851
- if (c <= 0.04045) {
852
- return c / 12.92;
853
- }
854
- return pow((c + 0.055) / 1.055, 2.4);
855
- }
856
-
857
- // Linear to sRGB conversion
858
- float linearToSrgb(float c) {
859
- if (c <= 0.0031308) {
860
- return c * 12.92;
861
- }
862
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
863
- }
864
-
865
- vec3 srgbToLinear(vec3 c) {
866
- return vec3(srgbToLinear(c.r), srgbToLinear(c.g), srgbToLinear(c.b));
867
- }
868
-
869
- vec3 linearToSrgb(vec3 c) {
870
- return vec3(linearToSrgb(c.r), linearToSrgb(c.g), linearToSrgb(c.b));
871
- }
872
-
873
- float luminance(vec3 color) {
874
- return dot(color, vec3(0.2126, 0.7152, 0.0722));
875
- }
876
-
877
- void main() {
878
- vec4 atlasSample = texture(u_atlas, v_uv);
879
- bool useLinear = u_blend.x > 0.5;
880
- bool useCorrection = u_blend.y > 0.5;
881
-
882
- if (v_mode > 0.5) {
883
- vec4 color = atlasSample;
884
- if (useLinear) {
885
- color.rgb = srgbToLinear(color.rgb);
886
- }
887
- color.rgb *= color.a;
888
- fragColor = color;
889
- return;
890
- }
891
-
892
- vec4 fg = v_color;
893
- vec4 bg = v_bg;
894
- if (useLinear) {
895
- fg.rgb = srgbToLinear(fg.rgb);
896
- bg.rgb = srgbToLinear(bg.rgb);
897
- }
898
- fg.rgb *= fg.a;
899
- bg.rgb *= bg.a;
900
-
901
- float alpha = atlasSample.a;
902
- if (useCorrection && useLinear) {
903
- float fg_l = luminance(fg.rgb);
904
- float bg_l = luminance(bg.rgb);
905
- if (abs(fg_l - bg_l) > 0.001) {
906
- float blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));
907
- alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);
908
- }
909
- }
910
-
911
- vec4 color = fg * alpha;
912
- fragColor = color;
913
- }
914
- `;
915
- var GLYPH_SHADER = `
916
- struct Uniforms {
917
- res: vec2f,
918
- _pad: vec2f,
919
- blend: vec2f,
920
- _pad2: vec2f,
921
- };
922
-
923
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
924
- @group(0) @binding(1) var atlasSampler: sampler;
925
- @group(0) @binding(2) var atlasTex: texture_2d<f32>;
926
-
927
- struct VSIn {
928
- @location(0) quad: vec2f,
929
- @location(1) pos: vec2f,
930
- @location(2) size: vec2f,
931
- @location(3) uv0: vec2f,
932
- @location(4) uv1: vec2f,
933
- @location(5) color: vec4f,
934
- @location(6) bg: vec4f,
935
- @location(7) slant: f32,
936
- @location(8) mode: f32,
937
- };
938
-
939
- struct VSOut {
940
- @builtin(position) position: vec4f,
941
- @location(0) uv: vec2f,
942
- @location(1) color: vec4f,
943
- @location(2) bg: vec4f,
944
- @location(3) mode: f32,
945
- };
946
-
947
- @vertex
948
- fn vsMain(input: VSIn) -> VSOut {
949
- let pixel = input.pos +
950
- vec2f(input.quad.x * input.size.x + input.slant * (1.0 - input.quad.y), input.quad.y * input.size.y);
951
- let clip = vec2f(
952
- (pixel.x / uniforms.res.x) * 2.0 - 1.0,
953
- 1.0 - (pixel.y / uniforms.res.y) * 2.0
954
- );
955
- let uv = input.uv0 + (input.uv1 - input.uv0) * input.quad;
956
-
957
- var out: VSOut;
958
- out.position = vec4f(clip.x, clip.y, 0.0, 1.0);
959
- out.uv = uv;
960
- out.color = input.color;
961
- out.bg = input.bg;
962
- out.mode = input.mode;
963
- return out;
964
- }
965
-
966
- // sRGB to linear conversion for proper blending
967
- fn srgbToLinear(c: f32) -> f32 {
968
- if (c <= 0.04045) {
969
- return c / 12.92;
970
- }
971
- return pow((c + 0.055) / 1.055, 2.4);
972
- }
973
-
974
- // Linear to sRGB conversion
975
- fn linearToSrgb(c: f32) -> f32 {
976
- if (c <= 0.0031308) {
977
- return c * 12.92;
978
- }
979
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
980
- }
981
-
982
- fn srgbToLinear3(c: vec3f) -> vec3f {
983
- return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));
984
- }
985
-
986
- fn linearToSrgb3(c: vec3f) -> vec3f {
987
- return vec3f(linearToSrgb(c.x), linearToSrgb(c.y), linearToSrgb(c.z));
988
- }
989
-
990
- fn luminance(color: vec3f) -> f32 {
991
- return dot(color, vec3f(0.2126, 0.7152, 0.0722));
992
- }
993
-
994
- @fragment
995
- fn fsMain(input: VSOut) -> @location(0) vec4f {
996
- let atlasSample = textureSample(atlasTex, atlasSampler, input.uv);
997
- let useLinear = uniforms.blend.x > 0.5;
998
- let useCorrection = uniforms.blend.y > 0.5;
999
-
1000
- if (input.mode > 0.5) {
1001
- var color = atlasSample;
1002
- if (useLinear) {
1003
- color = vec4f(srgbToLinear3(color.rgb), color.a);
1004
- }
1005
- return vec4f(color.rgb * color.a, color.a);
1006
- }
1007
-
1008
- var alpha = atlasSample.a;
1009
-
1010
- var fg = input.color;
1011
- var bg = input.bg;
1012
- if (useLinear) {
1013
- fg = vec4f(srgbToLinear3(fg.rgb), fg.a);
1014
- bg = vec4f(srgbToLinear3(bg.rgb), bg.a);
1015
- }
1016
- fg = vec4f(fg.rgb * fg.a, fg.a);
1017
- bg = vec4f(bg.rgb * bg.a, bg.a);
1018
-
1019
- if (useCorrection && useLinear) {
1020
- let fg_l = luminance(fg.rgb);
1021
- let bg_l = luminance(bg.rgb);
1022
- if (abs(fg_l - bg_l) > 0.001) {
1023
- let blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));
1024
- alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);
1025
- }
1026
- }
1027
-
1028
- var color = fg * alpha;
1029
- return color;
1030
- }
1031
- `;
1032
- var GLYPH_SHADER_NEAREST = `
1033
- struct Uniforms {
1034
- res: vec2f,
1035
- _pad: vec2f,
1036
- blend: vec2f,
1037
- _pad2: vec2f,
1038
- };
1039
-
1040
- @group(0) @binding(0) var<uniform> uniforms: Uniforms;
1041
- @group(0) @binding(1) var atlasSampler: sampler;
1042
- @group(0) @binding(2) var atlasTex: texture_2d<f32>;
1043
-
1044
- struct VSIn {
1045
- @location(0) quad: vec2f,
1046
- @location(1) pos: vec2f,
1047
- @location(2) size: vec2f,
1048
- @location(3) uv0: vec2f,
1049
- @location(4) uv1: vec2f,
1050
- @location(5) color: vec4f,
1051
- @location(6) bg: vec4f,
1052
- @location(7) slant: f32,
1053
- @location(8) mode: f32,
1054
- };
1055
-
1056
- struct VSOut {
1057
- @builtin(position) position: vec4f,
1058
- @location(0) uv: vec2f,
1059
- @location(1) color: vec4f,
1060
- @location(2) bg: vec4f,
1061
- @location(3) mode: f32,
1062
- };
1063
-
1064
- @vertex
1065
- fn vsMain(input: VSIn) -> VSOut {
1066
- let pixel = input.pos +
1067
- vec2f(input.quad.x * input.size.x + input.slant * (1.0 - input.quad.y), input.quad.y * input.size.y);
1068
- let clip = vec2f(
1069
- (pixel.x / uniforms.res.x) * 2.0 - 1.0,
1070
- 1.0 - (pixel.y / uniforms.res.y) * 2.0
1071
- );
1072
- let uv = input.uv0 + (input.uv1 - input.uv0) * input.quad;
1073
-
1074
- var out: VSOut;
1075
- out.position = vec4f(clip.x, clip.y, 0.0, 1.0);
1076
- out.uv = uv;
1077
- out.color = input.color;
1078
- out.bg = input.bg;
1079
- out.mode = input.mode;
1080
- return out;
1081
- }
1082
-
1083
- // sRGB to linear conversion for proper blending
1084
- fn srgbToLinear(c: f32) -> f32 {
1085
- if (c <= 0.04045) {
1086
- return c / 12.92;
1087
- }
1088
- return pow((c + 0.055) / 1.055, 2.4);
1089
- }
1090
-
1091
- // Linear to sRGB conversion
1092
- fn linearToSrgb(c: f32) -> f32 {
1093
- if (c <= 0.0031308) {
1094
- return c * 12.92;
1095
- }
1096
- return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
1097
- }
1098
-
1099
- fn srgbToLinear3(c: vec3f) -> vec3f {
1100
- return vec3f(srgbToLinear(c.x), srgbToLinear(c.y), srgbToLinear(c.z));
1101
- }
1102
-
1103
- fn linearToSrgb3(c: vec3f) -> vec3f {
1104
- return vec3f(linearToSrgb(c.x), linearToSrgb(c.y), linearToSrgb(c.z));
1105
- }
1106
-
1107
- fn luminance(color: vec3f) -> f32 {
1108
- return dot(color, vec3f(0.2126, 0.7152, 0.0722));
1109
- }
1110
-
1111
- @fragment
1112
- fn fsMain(input: VSOut) -> @location(0) vec4f {
1113
- let atlasSample = textureSample(atlasTex, atlasSampler, input.uv);
1114
- let useLinear = uniforms.blend.x > 0.5;
1115
- let useCorrection = uniforms.blend.y > 0.5;
1116
-
1117
- if (input.mode > 0.5) {
1118
- var color = atlasSample;
1119
- if (useLinear) {
1120
- color = vec4f(srgbToLinear3(color.rgb), color.a);
1121
- }
1122
- return vec4f(color.rgb * color.a, color.a);
1123
- }
1124
-
1125
- var alpha = atlasSample.a;
1126
-
1127
- var fg = input.color;
1128
- var bg = input.bg;
1129
- if (useLinear) {
1130
- fg = vec4f(srgbToLinear3(fg.rgb), fg.a);
1131
- bg = vec4f(srgbToLinear3(bg.rgb), bg.a);
1132
- }
1133
- fg = vec4f(fg.rgb * fg.a, fg.a);
1134
- bg = vec4f(bg.rgb * bg.a, bg.a);
1135
-
1136
- if (useCorrection && useLinear) {
1137
- let fg_l = luminance(fg.rgb);
1138
- let bg_l = luminance(bg.rgb);
1139
- if (abs(fg_l - bg_l) > 0.001) {
1140
- let blend_l = srgbToLinear(linearToSrgb(fg_l) * alpha + linearToSrgb(bg_l) * (1.0 - alpha));
1141
- alpha = clamp((blend_l - bg_l) / (fg_l - bg_l), 0.0, 1.0);
1142
- }
1143
- }
1144
-
1145
- var color = fg * alpha;
1146
- return color;
1147
- }
1148
- `;
1149
- // src/renderer/webgpu.ts
1150
- function getPreferredAndSrgbFormats() {
1151
- const preferredFormat = navigator.gpu.getPreferredCanvasFormat();
1152
- const srgbFormat = preferredFormat === "bgra8unorm" ? "bgra8unorm-srgb" : preferredFormat === "rgba8unorm" ? "rgba8unorm-srgb" : preferredFormat;
1153
- return { preferredFormat, srgbFormat };
1154
- }
1155
- function configureContextFormat(context, device, preferredFormat, srgbFormat) {
1156
- let format = preferredFormat;
1157
- try {
1158
- context.configure({ device, format: srgbFormat, alphaMode: "opaque" });
1159
- format = srgbFormat;
1160
- } catch {
1161
- context.configure({ device, format: preferredFormat, alphaMode: "opaque" });
1162
- }
1163
- return { format, srgbSwapchain: format.endsWith("-srgb") };
1164
- }
1165
- function createWebGPUCoreState(device, format, srgbSwapchain) {
1166
- const quadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]);
1167
- const vertexBuffer = device.createBuffer({
1168
- size: quadVertices.byteLength,
1169
- usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
1170
- mappedAtCreation: true
1171
- });
1172
- new Float32Array(vertexBuffer.getMappedRange()).set(quadVertices);
1173
- vertexBuffer.unmap();
1174
- const rectModule = device.createShaderModule({ code: RECT_SHADER });
1175
- const glyphModule = device.createShaderModule({ code: GLYPH_SHADER });
1176
- const glyphNearestModule = device.createShaderModule({ code: GLYPH_SHADER_NEAREST });
1177
- const rectPipeline = device.createRenderPipeline({
1178
- layout: "auto",
1179
- vertex: {
1180
- module: rectModule,
1181
- entryPoint: "vsMain",
1182
- buffers: [
1183
- {
1184
- arrayStride: 8,
1185
- attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
1186
- },
1187
- {
1188
- arrayStride: 32,
1189
- stepMode: "instance",
1190
- attributes: [
1191
- { shaderLocation: 1, offset: 0, format: "float32x2" },
1192
- { shaderLocation: 2, offset: 8, format: "float32x2" },
1193
- { shaderLocation: 3, offset: 16, format: "float32x4" }
1194
- ]
1195
- }
1196
- ]
1197
- },
1198
- fragment: {
1199
- module: rectModule,
1200
- entryPoint: "fsMain",
1201
- targets: [
1202
- {
1203
- format,
1204
- blend: {
1205
- color: {
1206
- srcFactor: "one",
1207
- dstFactor: "one-minus-src-alpha",
1208
- operation: "add"
1209
- },
1210
- alpha: {
1211
- srcFactor: "one",
1212
- dstFactor: "one-minus-src-alpha",
1213
- operation: "add"
1214
- }
1215
- }
1216
- }
1217
- ]
1218
- },
1219
- primitive: { topology: "triangle-list", cullMode: "none" }
1220
- });
1221
- const glyphPipeline = device.createRenderPipeline({
1222
- layout: "auto",
1223
- vertex: {
1224
- module: glyphModule,
1225
- entryPoint: "vsMain",
1226
- buffers: [
1227
- {
1228
- arrayStride: 8,
1229
- attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
1230
- },
1231
- {
1232
- arrayStride: 72,
1233
- stepMode: "instance",
1234
- attributes: [
1235
- { shaderLocation: 1, offset: 0, format: "float32x2" },
1236
- { shaderLocation: 2, offset: 8, format: "float32x2" },
1237
- { shaderLocation: 3, offset: 16, format: "float32x2" },
1238
- { shaderLocation: 4, offset: 24, format: "float32x2" },
1239
- { shaderLocation: 5, offset: 32, format: "float32x4" },
1240
- { shaderLocation: 6, offset: 48, format: "float32x4" },
1241
- { shaderLocation: 7, offset: 64, format: "float32" },
1242
- { shaderLocation: 8, offset: 68, format: "float32" }
1243
- ]
1244
- }
1245
- ]
1246
- },
1247
- fragment: {
1248
- module: glyphModule,
1249
- entryPoint: "fsMain",
1250
- targets: [
1251
- {
1252
- format,
1253
- blend: {
1254
- color: {
1255
- srcFactor: "one",
1256
- dstFactor: "one-minus-src-alpha",
1257
- operation: "add"
1258
- },
1259
- alpha: {
1260
- srcFactor: "one",
1261
- dstFactor: "one-minus-src-alpha",
1262
- operation: "add"
1263
- }
1264
- }
1265
- }
1266
- ]
1267
- },
1268
- primitive: { topology: "triangle-list", cullMode: "none" }
1269
- });
1270
- const glyphPipelineNearest = device.createRenderPipeline({
1271
- layout: "auto",
1272
- vertex: {
1273
- module: glyphNearestModule,
1274
- entryPoint: "vsMain",
1275
- buffers: [
1276
- {
1277
- arrayStride: 8,
1278
- attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
1279
- },
1280
- {
1281
- arrayStride: 72,
1282
- stepMode: "instance",
1283
- attributes: [
1284
- { shaderLocation: 1, offset: 0, format: "float32x2" },
1285
- { shaderLocation: 2, offset: 8, format: "float32x2" },
1286
- { shaderLocation: 3, offset: 16, format: "float32x2" },
1287
- { shaderLocation: 4, offset: 24, format: "float32x2" },
1288
- { shaderLocation: 5, offset: 32, format: "float32x4" },
1289
- { shaderLocation: 6, offset: 48, format: "float32x4" },
1290
- { shaderLocation: 7, offset: 64, format: "float32" },
1291
- { shaderLocation: 8, offset: 68, format: "float32" }
1292
- ]
1293
- }
1294
- ]
1295
- },
1296
- fragment: {
1297
- module: glyphNearestModule,
1298
- entryPoint: "fsMain",
1299
- targets: [
1300
- {
1301
- format,
1302
- blend: {
1303
- color: {
1304
- srcFactor: "one",
1305
- dstFactor: "one-minus-src-alpha",
1306
- operation: "add"
1307
- },
1308
- alpha: {
1309
- srcFactor: "one",
1310
- dstFactor: "one-minus-src-alpha",
1311
- operation: "add"
1312
- }
1313
- }
1314
- }
1315
- ]
1316
- },
1317
- primitive: { topology: "triangle-list", cullMode: "none" }
1318
- });
1319
- return {
1320
- device,
1321
- format,
1322
- srgbSwapchain,
1323
- rectPipeline,
1324
- glyphPipeline,
1325
- glyphPipelineNearest,
1326
- vertexBuffer
1327
- };
1328
- }
1329
- async function initWebGPUCore(canvas) {
1330
- if (!navigator.gpu)
1331
- return null;
1332
- const adapter = await navigator.gpu.requestAdapter();
1333
- if (!adapter)
1334
- return null;
1335
- const device = await adapter.requestDevice();
1336
- const context = canvas.getContext("webgpu");
1337
- if (!context)
1338
- return null;
1339
- const { preferredFormat, srgbFormat } = getPreferredAndSrgbFormats();
1340
- const { format, srgbSwapchain } = configureContextFormat(context, device, preferredFormat, srgbFormat);
1341
- return createWebGPUCoreState(device, format, srgbSwapchain);
1342
- }
1343
- async function initWebGPU(canvas, options = {}) {
1344
- const core = options.core ?? await initWebGPUCore(canvas);
1345
- if (!core)
1346
- return null;
1347
- const context = canvas.getContext("webgpu");
1348
- if (!context)
1349
- return null;
1350
- try {
1351
- context.configure({ device: core.device, format: core.format, alphaMode: "opaque" });
1352
- } catch {
1353
- return null;
1354
- }
1355
- const uniformBuffer = core.device.createBuffer({
1356
- size: 8 * 4,
1357
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
1358
- });
1359
- const rectBindGroup = core.device.createBindGroup({
1360
- layout: core.rectPipeline.getBindGroupLayout(0),
1361
- entries: [{ binding: 0, resource: { buffer: uniformBuffer } }]
1362
- });
1363
- return {
1364
- core,
1365
- device: core.device,
1366
- context,
1367
- format: core.format,
1368
- srgbSwapchain: core.srgbSwapchain,
1369
- rectPipeline: core.rectPipeline,
1370
- glyphPipeline: core.glyphPipeline,
1371
- glyphPipelineNearest: core.glyphPipelineNearest,
1372
- rectBindGroup,
1373
- uniformBuffer,
1374
- vertexBuffer: core.vertexBuffer,
1375
- rectInstanceBuffer: core.device.createBuffer({
1376
- size: 4,
1377
- usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
1378
- }),
1379
- rectCapacity: 4,
1380
- glyphInstanceBuffer: core.device.createBuffer({
1381
- size: 4,
1382
- usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
1383
- }),
1384
- glyphCapacity: 4,
1385
- glyphAtlases: new Map
1386
- };
1387
- }
1388
- function compileShader(gl, type, source) {
1389
- const shader = gl.createShader(type);
1390
- if (!shader)
1391
- return null;
1392
- gl.shaderSource(shader, source);
1393
- gl.compileShader(shader);
1394
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
1395
- console.error("Shader compile error:", gl.getShaderInfoLog(shader));
1396
- gl.deleteShader(shader);
1397
- return null;
1398
- }
1399
- return shader;
1400
- }
1401
- function createProgram(gl, vertSrc, fragSrc) {
1402
- const vert = compileShader(gl, gl.VERTEX_SHADER, vertSrc);
1403
- const frag = compileShader(gl, gl.FRAGMENT_SHADER, fragSrc);
1404
- if (!vert || !frag)
1405
- return null;
1406
- const program = gl.createProgram();
1407
- if (!program)
1408
- return null;
1409
- gl.attachShader(program, vert);
1410
- gl.attachShader(program, frag);
1411
- gl.linkProgram(program);
1412
- if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
1413
- console.error("Program link error:", gl.getProgramInfoLog(program));
1414
- gl.deleteProgram(program);
1415
- return null;
1416
- }
1417
- gl.deleteShader(vert);
1418
- gl.deleteShader(frag);
1419
- return program;
1420
- }
1421
- function initWebGL(canvas) {
1422
- const gl = canvas.getContext("webgl2", { antialias: false, alpha: false });
1423
- if (!gl)
1424
- return null;
1425
- const rectProgram = createProgram(gl, RECT_SHADER_GL_VERT, RECT_SHADER_GL_FRAG);
1426
- const glyphProgram = createProgram(gl, GLYPH_SHADER_GL_VERT, GLYPH_SHADER_GL_FRAG);
1427
- if (!rectProgram || !glyphProgram)
1428
- return null;
1429
- const rectResolutionLoc = gl.getUniformLocation(rectProgram, "u_resolution");
1430
- const rectBlendLoc = gl.getUniformLocation(rectProgram, "u_blend");
1431
- const glyphResolutionLoc = gl.getUniformLocation(glyphProgram, "u_resolution");
1432
- const glyphBlendLoc = gl.getUniformLocation(glyphProgram, "u_blend");
1433
- const glyphAtlasLoc = gl.getUniformLocation(glyphProgram, "u_atlas");
1434
- if (!rectResolutionLoc || !rectBlendLoc || !glyphResolutionLoc || !glyphBlendLoc || !glyphAtlasLoc) {
1435
- return null;
1436
- }
1437
- const quadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]);
1438
- const quadBuffer = gl.createBuffer();
1439
- if (!quadBuffer)
1440
- return null;
1441
- gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
1442
- gl.bufferData(gl.ARRAY_BUFFER, quadVertices, gl.STATIC_DRAW);
1443
- const rectVao = gl.createVertexArray();
1444
- if (!rectVao)
1445
- return null;
1446
- gl.bindVertexArray(rectVao);
1447
- gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
1448
- gl.enableVertexAttribArray(0);
1449
- gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
1450
- const rectInstanceBuffer = gl.createBuffer();
1451
- if (!rectInstanceBuffer)
1452
- return null;
1453
- gl.bindBuffer(gl.ARRAY_BUFFER, rectInstanceBuffer);
1454
- gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.DYNAMIC_DRAW);
1455
- gl.enableVertexAttribArray(1);
1456
- gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 32, 0);
1457
- gl.vertexAttribDivisor(1, 1);
1458
- gl.enableVertexAttribArray(2);
1459
- gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 32, 8);
1460
- gl.vertexAttribDivisor(2, 1);
1461
- gl.enableVertexAttribArray(3);
1462
- gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 32, 16);
1463
- gl.vertexAttribDivisor(3, 1);
1464
- gl.bindVertexArray(null);
1465
- const glyphVao = gl.createVertexArray();
1466
- if (!glyphVao)
1467
- return null;
1468
- gl.bindVertexArray(glyphVao);
1469
- gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
1470
- gl.enableVertexAttribArray(0);
1471
- gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
1472
- const glyphInstanceBuffer = gl.createBuffer();
1473
- if (!glyphInstanceBuffer)
1474
- return null;
1475
- gl.bindBuffer(gl.ARRAY_BUFFER, glyphInstanceBuffer);
1476
- gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.DYNAMIC_DRAW);
1477
- gl.enableVertexAttribArray(1);
1478
- gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 72, 0);
1479
- gl.vertexAttribDivisor(1, 1);
1480
- gl.enableVertexAttribArray(2);
1481
- gl.vertexAttribPointer(2, 2, gl.FLOAT, false, 72, 8);
1482
- gl.vertexAttribDivisor(2, 1);
1483
- gl.enableVertexAttribArray(3);
1484
- gl.vertexAttribPointer(3, 2, gl.FLOAT, false, 72, 16);
1485
- gl.vertexAttribDivisor(3, 1);
1486
- gl.enableVertexAttribArray(4);
1487
- gl.vertexAttribPointer(4, 2, gl.FLOAT, false, 72, 24);
1488
- gl.vertexAttribDivisor(4, 1);
1489
- gl.enableVertexAttribArray(5);
1490
- gl.vertexAttribPointer(5, 4, gl.FLOAT, false, 72, 32);
1491
- gl.vertexAttribDivisor(5, 1);
1492
- gl.enableVertexAttribArray(6);
1493
- gl.vertexAttribPointer(6, 4, gl.FLOAT, false, 72, 48);
1494
- gl.vertexAttribDivisor(6, 1);
1495
- gl.enableVertexAttribArray(7);
1496
- gl.vertexAttribPointer(7, 1, gl.FLOAT, false, 72, 64);
1497
- gl.vertexAttribDivisor(7, 1);
1498
- gl.enableVertexAttribArray(8);
1499
- gl.vertexAttribPointer(8, 1, gl.FLOAT, false, 72, 68);
1500
- gl.vertexAttribDivisor(8, 1);
1501
- gl.bindVertexArray(null);
1502
- gl.enable(gl.BLEND);
1503
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
1504
- return {
1505
- gl,
1506
- rectProgram,
1507
- glyphProgram,
1508
- rectResolutionLoc,
1509
- rectBlendLoc,
1510
- glyphResolutionLoc,
1511
- glyphBlendLoc,
1512
- glyphAtlasLoc,
1513
- quadBuffer,
1514
- rectVao,
1515
- glyphVao,
1516
- rectInstanceBuffer,
1517
- glyphInstanceBuffer,
1518
- rectCapacity: 1024,
1519
- glyphCapacity: 1024,
1520
- glyphAtlases: new Map
1521
- };
1522
- }
1523
- function ensureInstanceBuffer(state, kind, byteLength) {
1524
- const bufferKey = kind === "rect" ? "rectInstanceBuffer" : "glyphInstanceBuffer";
1525
- const capKey = kind === "rect" ? "rectCapacity" : "glyphCapacity";
1526
- if (byteLength <= state[capKey])
1527
- return;
1528
- const newSize = Math.max(byteLength, state[capKey] * 2, 1024);
1529
- state[bufferKey] = state.device.createBuffer({
1530
- size: newSize,
1531
- usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
1532
- });
1533
- state[capKey] = newSize;
1534
- }
1535
- function configureContext(state) {
1536
- state.context.configure({
1537
- device: state.device,
1538
- format: state.format,
1539
- alphaMode: "opaque"
1540
- });
1541
- }
1542
- function ensureGLInstanceBuffer(state, kind, byteLength) {
1543
- const { gl } = state;
1544
- const bufferKey = kind === "rect" ? "rectInstanceBuffer" : "glyphInstanceBuffer";
1545
- const capKey = kind === "rect" ? "rectCapacity" : "glyphCapacity";
1546
- const vaoKey = kind === "rect" ? "rectVao" : "glyphVao";
1547
- if (byteLength <= state[capKey])
1548
- return;
1549
- const newSize = Math.max(byteLength, state[capKey] * 2, 1024);
1550
- gl.bindVertexArray(state[vaoKey]);
1551
- gl.bindBuffer(gl.ARRAY_BUFFER, state[bufferKey]);
1552
- gl.bufferData(gl.ARRAY_BUFFER, newSize, gl.DYNAMIC_DRAW);
1553
- state[capKey] = newSize;
1554
- gl.bindVertexArray(null);
1555
- }
1556
- function createResizeState() {
1557
- return {
1558
- active: false,
1559
- lastAt: 0,
1560
- cols: 0,
1561
- rows: 0,
1562
- dpr: 1
1563
- };
1564
- }
1565
- function createScrollbarState() {
1566
- return {
1567
- lastInputAt: 0,
1568
- lastTotal: 0,
1569
- lastOffset: 0,
1570
- lastLen: 0
1571
- };
1572
- }
1573
- export {
1574
- pushRectSnapped,
1575
- pushRectBox,
1576
- pushRect,
1577
- isSymbolCp,
1578
- isSpaceCp,
1579
- isPrivateUse,
1580
- isPowerline,
1581
- isLegacyComputing,
1582
- isGraphicsElement,
1583
- isBraille,
1584
- isBoxDrawing,
1585
- isBlockElement,
1586
- initWebGPUCore,
1587
- initWebGPU,
1588
- initWebGL,
1589
- ensureInstanceBuffer,
1590
- ensureGLInstanceBuffer,
1591
- drawPowerline,
1592
- drawBraille,
1593
- drawBoxDrawing,
1594
- drawBlockElement,
1595
- createScrollbarState,
1596
- createResizeState,
1597
- constrainGlyphBox,
1598
- configureContext,
1599
- applyAlpha,
1600
- RECT_SHADER_GL_VERT,
1601
- RECT_SHADER_GL_FRAG,
1602
- RECT_SHADER,
1603
- GLYPH_SHADER_NEAREST,
1604
- GLYPH_SHADER_GL_VERT,
1605
- GLYPH_SHADER_GL_FRAG,
1606
- GLYPH_SHADER,
1607
- BOX_STYLE_NONE,
1608
- BOX_STYLE_LIGHT,
1609
- BOX_STYLE_HEAVY,
1610
- BOX_STYLE_DOUBLE,
1611
- BOX_LINE_MAP
1612
- };