wraithterm 0.0.0-stage → 0.2.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 (210) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +313 -2
  3. package/css/xterm.css +285 -0
  4. package/dist/index.d.ts +88 -0
  5. package/dist/index.js +707 -0
  6. package/dist/keycodes.d.ts +1 -0
  7. package/dist/keycodes.js +179 -0
  8. package/dist/protocol.d.ts +117 -0
  9. package/dist/protocol.js +1 -0
  10. package/dist/types.d.ts +66 -0
  11. package/dist/types.js +19 -0
  12. package/dist/vite.d.ts +11 -0
  13. package/dist/vite.js +11 -0
  14. package/dist/worker.d.ts +1 -0
  15. package/dist/worker.js +302 -0
  16. package/dist/xterm-api.d.ts +1956 -0
  17. package/dist/xterm-atlas.d.ts +39 -0
  18. package/dist/xterm-atlas.js +176 -0
  19. package/dist/xterm-internals.d.ts +120 -0
  20. package/dist/xterm-internals.js +19 -0
  21. package/dist/xterm-renderer.d.ts +77 -0
  22. package/dist/xterm-renderer.js +540 -0
  23. package/dist/xterm.d.ts +17 -0
  24. package/dist/xterm.js +35 -0
  25. package/docs/ARCHITECTURE.md +179 -0
  26. package/docs/COMPATIBILITY.md +66 -0
  27. package/docs/PERFORMANCE.md +122 -0
  28. package/docs/TOP_TIER.md +124 -0
  29. package/docs/XTERM_API.md +163 -0
  30. package/docs/compatibility/xterm-chrome.json +34 -0
  31. package/licenses/Ghostty-MIT.txt +21 -0
  32. package/licenses/JetBrainsMono-OFL.txt +93 -0
  33. package/licenses/NOTICE.md +93 -0
  34. package/licenses/Zig-MIT.txt +21 -0
  35. package/licenses/rust/arrayvec-0.7.8/LICENSE-APACHE +201 -0
  36. package/licenses/rust/arrayvec-0.7.8/LICENSE-MIT +25 -0
  37. package/licenses/rust/autocfg-1.5.1/LICENSE-APACHE +201 -0
  38. package/licenses/rust/autocfg-1.5.1/LICENSE-MIT +25 -0
  39. package/licenses/rust/bit-set-0.10.0/LICENSE-APACHE +201 -0
  40. package/licenses/rust/bit-set-0.10.0/LICENSE-MIT +25 -0
  41. package/licenses/rust/bit-vec-0.9.1/LICENSE-APACHE +201 -0
  42. package/licenses/rust/bit-vec-0.9.1/LICENSE-MIT +25 -0
  43. package/licenses/rust/bitflags-2.13.2/LICENSE-APACHE +201 -0
  44. package/licenses/rust/bitflags-2.13.2/LICENSE-MIT +25 -0
  45. package/licenses/rust/bumpalo-3.20.3/LICENSE-APACHE +201 -0
  46. package/licenses/rust/bumpalo-3.20.3/LICENSE-MIT +25 -0
  47. package/licenses/rust/bytemuck-1.25.2/LICENSE-APACHE +61 -0
  48. package/licenses/rust/bytemuck-1.25.2/LICENSE-MIT +9 -0
  49. package/licenses/rust/bytemuck-1.25.2/LICENSE-ZLIB +11 -0
  50. package/licenses/rust/bytemuck_derive-1.12.1/LICENSE-APACHE +61 -0
  51. package/licenses/rust/bytemuck_derive-1.12.1/LICENSE-MIT +9 -0
  52. package/licenses/rust/bytemuck_derive-1.12.1/LICENSE-ZLIB +11 -0
  53. package/licenses/rust/cfg-if-1.0.5/LICENSE-APACHE +201 -0
  54. package/licenses/rust/cfg-if-1.0.5/LICENSE-MIT +25 -0
  55. package/licenses/rust/cfg_aliases-0.2.2/LICENSE +9 -0
  56. package/licenses/rust/codespan-reporting-0.13.1/LICENSE +201 -0
  57. package/licenses/rust/crunchy-0.2.4/LICENSE +21 -0
  58. package/licenses/rust/document-features-0.2.12/LICENSE-APACHE +73 -0
  59. package/licenses/rust/document-features-0.2.12/LICENSE-MIT +19 -0
  60. package/licenses/rust/equivalent-1.0.2/LICENSE-APACHE +201 -0
  61. package/licenses/rust/equivalent-1.0.2/LICENSE-MIT +25 -0
  62. package/licenses/rust/foldhash-0.2.0/LICENSE +19 -0
  63. package/licenses/rust/font-types-0.12.6/LICENSE-APACHE +67 -0
  64. package/licenses/rust/font-types-0.12.6/LICENSE-MIT +25 -0
  65. package/licenses/rust/futures-core-0.3.34/LICENSE-APACHE +202 -0
  66. package/licenses/rust/futures-core-0.3.34/LICENSE-MIT +26 -0
  67. package/licenses/rust/futures-task-0.3.34/LICENSE-APACHE +202 -0
  68. package/licenses/rust/futures-task-0.3.34/LICENSE-MIT +26 -0
  69. package/licenses/rust/futures-util-0.3.34/LICENSE-APACHE +202 -0
  70. package/licenses/rust/futures-util-0.3.34/LICENSE-MIT +26 -0
  71. package/licenses/rust/half-2.7.1/LICENSE-APACHE +176 -0
  72. package/licenses/rust/half-2.7.1/LICENSE-MIT +19 -0
  73. package/licenses/rust/harfrust-0.13.3/LICENSE +22 -0
  74. package/licenses/rust/hashbrown-0.17.1/LICENSE-APACHE +201 -0
  75. package/licenses/rust/hashbrown-0.17.1/LICENSE-MIT +25 -0
  76. package/licenses/rust/indexmap-2.14.2/LICENSE-APACHE +201 -0
  77. package/licenses/rust/indexmap-2.14.2/LICENSE-MIT +25 -0
  78. package/licenses/rust/js-sys-0.3.106/LICENSE-APACHE +201 -0
  79. package/licenses/rust/js-sys-0.3.106/LICENSE-MIT +25 -0
  80. package/licenses/rust/libc-0.2.190/LICENSE-APACHE +176 -0
  81. package/licenses/rust/libc-0.2.190/LICENSE-MIT +25 -0
  82. package/licenses/rust/libloading-0.8.9/LICENSE +12 -0
  83. package/licenses/rust/libm-0.2.16/LICENSE.txt +258 -0
  84. package/licenses/rust/litrs-1.0.0/LICENSE-APACHE +176 -0
  85. package/licenses/rust/litrs-1.0.0/LICENSE-MIT +25 -0
  86. package/licenses/rust/lock_api-0.4.14/LICENSE-APACHE +201 -0
  87. package/licenses/rust/lock_api-0.4.14/LICENSE-MIT +25 -0
  88. package/licenses/rust/log-0.4.34/LICENSE-APACHE +201 -0
  89. package/licenses/rust/log-0.4.34/LICENSE-MIT +25 -0
  90. package/licenses/rust/naga-30.0.1/LICENSE.APACHE +176 -0
  91. package/licenses/rust/naga-30.0.1/LICENSE.MIT +21 -0
  92. package/licenses/rust/naga-types-30.0.1/LICENSE.APACHE +176 -0
  93. package/licenses/rust/naga-types-30.0.1/LICENSE.MIT +21 -0
  94. package/licenses/rust/num-traits-0.2.19/LICENSE-APACHE +201 -0
  95. package/licenses/rust/num-traits-0.2.19/LICENSE-MIT +25 -0
  96. package/licenses/rust/once_cell-1.21.4/LICENSE-APACHE +201 -0
  97. package/licenses/rust/once_cell-1.21.4/LICENSE-MIT +23 -0
  98. package/licenses/rust/parking_lot-0.12.5/LICENSE-APACHE +201 -0
  99. package/licenses/rust/parking_lot-0.12.5/LICENSE-MIT +25 -0
  100. package/licenses/rust/parking_lot_core-0.9.12/LICENSE-APACHE +201 -0
  101. package/licenses/rust/parking_lot_core-0.9.12/LICENSE-MIT +25 -0
  102. package/licenses/rust/pin-project-lite-0.2.17/LICENSE-APACHE +177 -0
  103. package/licenses/rust/pin-project-lite-0.2.17/LICENSE-MIT +23 -0
  104. package/licenses/rust/portable-atomic-1.15.0/LICENSE-APACHE +177 -0
  105. package/licenses/rust/portable-atomic-1.15.0/LICENSE-MIT +23 -0
  106. package/licenses/rust/portable-atomic-util-0.2.8/LICENSE-APACHE +177 -0
  107. package/licenses/rust/portable-atomic-util-0.2.8/LICENSE-MIT +23 -0
  108. package/licenses/rust/proc-macro2-1.0.107/LICENSE-APACHE +176 -0
  109. package/licenses/rust/proc-macro2-1.0.107/LICENSE-MIT +23 -0
  110. package/licenses/rust/quote-1.0.47/LICENSE-APACHE +176 -0
  111. package/licenses/rust/quote-1.0.47/LICENSE-MIT +23 -0
  112. package/licenses/rust/raw-window-handle-0.6.2/LICENSE-APACHE.md +177 -0
  113. package/licenses/rust/raw-window-handle-0.6.2/LICENSE-MIT.md +21 -0
  114. package/licenses/rust/raw-window-handle-0.6.2/LICENSE-ZLIB.md +11 -0
  115. package/licenses/rust/read-fonts-0.41.0/LICENSE-APACHE +67 -0
  116. package/licenses/rust/read-fonts-0.41.0/LICENSE-MIT +25 -0
  117. package/licenses/rust/read-fonts-0.43.3/LICENSE-APACHE +67 -0
  118. package/licenses/rust/read-fonts-0.43.3/LICENSE-MIT +25 -0
  119. package/licenses/rust/redox_syscall-0.5.18/LICENSE +22 -0
  120. package/licenses/rust/renderdoc-sys-1.1.0/LICENSE-APACHE +201 -0
  121. package/licenses/rust/renderdoc-sys-1.1.0/LICENSE-MIT +25 -0
  122. package/licenses/rust/rustc-hash-1.1.0/LICENSE-APACHE +201 -0
  123. package/licenses/rust/rustc-hash-1.1.0/LICENSE-MIT +23 -0
  124. package/licenses/rust/rustversion-1.0.23/LICENSE-APACHE +176 -0
  125. package/licenses/rust/rustversion-1.0.23/LICENSE-MIT +23 -0
  126. package/licenses/rust/scopeguard-1.2.0/LICENSE-APACHE +201 -0
  127. package/licenses/rust/scopeguard-1.2.0/LICENSE-MIT +25 -0
  128. package/licenses/rust/serde-1.0.229/LICENSE-APACHE +176 -0
  129. package/licenses/rust/serde-1.0.229/LICENSE-MIT +23 -0
  130. package/licenses/rust/serde_core-1.0.229/LICENSE-APACHE +176 -0
  131. package/licenses/rust/serde_core-1.0.229/LICENSE-MIT +23 -0
  132. package/licenses/rust/serde_derive-1.0.229/LICENSE-APACHE +176 -0
  133. package/licenses/rust/serde_derive-1.0.229/LICENSE-MIT +23 -0
  134. package/licenses/rust/skrifa-0.44.0/LICENSE-APACHE +67 -0
  135. package/licenses/rust/skrifa-0.44.0/LICENSE-MIT +25 -0
  136. package/licenses/rust/slab-0.4.12/LICENSE +25 -0
  137. package/licenses/rust/smallvec-1.16.2/LICENSE-APACHE +201 -0
  138. package/licenses/rust/smallvec-1.16.2/LICENSE-MIT +25 -0
  139. package/licenses/rust/static_assertions-1.1.0/LICENSE-APACHE +202 -0
  140. package/licenses/rust/static_assertions-1.1.0/LICENSE-MIT +21 -0
  141. package/licenses/rust/swash-0.2.10/LICENSE-APACHE +201 -0
  142. package/licenses/rust/swash-0.2.10/LICENSE-MIT +25 -0
  143. package/licenses/rust/syn-2.0.119/LICENSE-APACHE +176 -0
  144. package/licenses/rust/syn-2.0.119/LICENSE-MIT +23 -0
  145. package/licenses/rust/syn-3.0.6/LICENSE-APACHE +176 -0
  146. package/licenses/rust/syn-3.0.6/LICENSE-MIT +23 -0
  147. package/licenses/rust/termcolor-1.4.1/COPYING +3 -0
  148. package/licenses/rust/termcolor-1.4.1/LICENSE-MIT +21 -0
  149. package/licenses/rust/termcolor-1.4.1/UNLICENSE +24 -0
  150. package/licenses/rust/thiserror-2.0.21/LICENSE-APACHE +176 -0
  151. package/licenses/rust/thiserror-2.0.21/LICENSE-MIT +23 -0
  152. package/licenses/rust/thiserror-impl-2.0.21/LICENSE-APACHE +176 -0
  153. package/licenses/rust/thiserror-impl-2.0.21/LICENSE-MIT +23 -0
  154. package/licenses/rust/tokio-1.53.2/LICENSE +21 -0
  155. package/licenses/rust/unicode-ident-1.0.26/LICENSE-APACHE +176 -0
  156. package/licenses/rust/unicode-ident-1.0.26/LICENSE-MIT +23 -0
  157. package/licenses/rust/unicode-ident-1.0.26/LICENSE-UNICODE +39 -0
  158. package/licenses/rust/unicode-width-0.2.2/LICENSE-APACHE +201 -0
  159. package/licenses/rust/unicode-width-0.2.2/LICENSE-MIT +25 -0
  160. package/licenses/rust/wasm-bindgen-0.2.129/LICENSE-APACHE +201 -0
  161. package/licenses/rust/wasm-bindgen-0.2.129/LICENSE-MIT +25 -0
  162. package/licenses/rust/wasm-bindgen-futures-0.4.79/LICENSE-APACHE +201 -0
  163. package/licenses/rust/wasm-bindgen-futures-0.4.79/LICENSE-MIT +25 -0
  164. package/licenses/rust/wasm-bindgen-macro-0.2.129/LICENSE-APACHE +201 -0
  165. package/licenses/rust/wasm-bindgen-macro-0.2.129/LICENSE-MIT +25 -0
  166. package/licenses/rust/wasm-bindgen-macro-support-0.2.129/LICENSE-APACHE +201 -0
  167. package/licenses/rust/wasm-bindgen-macro-support-0.2.129/LICENSE-MIT +25 -0
  168. package/licenses/rust/wasm-bindgen-shared-0.2.129/LICENSE-APACHE +201 -0
  169. package/licenses/rust/wasm-bindgen-shared-0.2.129/LICENSE-MIT +25 -0
  170. package/licenses/rust/web-sys-0.3.106/LICENSE-APACHE +201 -0
  171. package/licenses/rust/web-sys-0.3.106/LICENSE-MIT +25 -0
  172. package/licenses/rust/wgpu-30.0.1/LICENSE.APACHE +176 -0
  173. package/licenses/rust/wgpu-30.0.1/LICENSE.MIT +21 -0
  174. package/licenses/rust/wgpu-core-30.0.1/LICENSE.APACHE +176 -0
  175. package/licenses/rust/wgpu-core-30.0.1/LICENSE.MIT +21 -0
  176. package/licenses/rust/wgpu-core-deps-windows-linux-android-30.0.1/LICENSE.APACHE +176 -0
  177. package/licenses/rust/wgpu-core-deps-windows-linux-android-30.0.1/LICENSE.MIT +21 -0
  178. package/licenses/rust/wgpu-hal-30.0.1/LICENSE.APACHE +176 -0
  179. package/licenses/rust/wgpu-hal-30.0.1/LICENSE.MIT +21 -0
  180. package/licenses/rust/wgpu-naga-bridge-30.0.1/LICENSE.APACHE +176 -0
  181. package/licenses/rust/wgpu-naga-bridge-30.0.1/LICENSE.MIT +21 -0
  182. package/licenses/rust/wgpu-types-30.0.1/LICENSE.APACHE +176 -0
  183. package/licenses/rust/wgpu-types-30.0.1/LICENSE.MIT +21 -0
  184. package/licenses/rust/winapi-util-0.1.11/COPYING +3 -0
  185. package/licenses/rust/winapi-util-0.1.11/LICENSE-MIT +21 -0
  186. package/licenses/rust/winapi-util-0.1.11/UNLICENSE +24 -0
  187. package/licenses/rust/windows-link-0.2.1/license-apache-2.0 +201 -0
  188. package/licenses/rust/windows-link-0.2.1/license-mit +21 -0
  189. package/licenses/rust/windows-sys-0.61.2/license-apache-2.0 +201 -0
  190. package/licenses/rust/windows-sys-0.61.2/license-mit +21 -0
  191. package/licenses/rust/yazi-0.2.1/LICENSE-APACHE +201 -0
  192. package/licenses/rust/yazi-0.2.1/LICENSE-MIT +19 -0
  193. package/licenses/rust/zeno-0.3.3/LICENSE-APACHE +201 -0
  194. package/licenses/rust/zeno-0.3.3/LICENSE-MIT +25 -0
  195. package/licenses/rust/zerocopy-0.8.62/LICENSE-APACHE +202 -0
  196. package/licenses/rust/zerocopy-0.8.62/LICENSE-BSD +24 -0
  197. package/licenses/rust/zerocopy-0.8.62/LICENSE-MIT +26 -0
  198. package/licenses/rust/zerocopy-derive-0.8.62/LICENSE-APACHE +202 -0
  199. package/licenses/rust/zerocopy-derive-0.8.62/LICENSE-BSD +24 -0
  200. package/licenses/rust/zerocopy-derive-0.8.62/LICENSE-MIT +26 -0
  201. package/licenses/xterm-MIT.txt +21 -0
  202. package/package.json +69 -4
  203. package/wasm/Ghostty-MIT.txt +21 -0
  204. package/wasm/JetBrainsMono-Regular.ttf +0 -0
  205. package/wasm/OFL.txt +93 -0
  206. package/wasm/optimization.json +6 -0
  207. package/wasm/wraith_engine.d.ts +176 -0
  208. package/wasm/wraith_engine.js +2057 -0
  209. package/wasm/wraith_engine_bg.wasm +0 -0
  210. package/wasm/wraith_engine_bg.wasm.d.ts +71 -0
@@ -0,0 +1,39 @@
1
+ import type { ITerminalOptions } from './xterm-api.js';
2
+ import type { Compositor } from '../wasm/wraith_engine.js';
3
+ export declare const ATLAS_SIZE = 2048;
4
+ export declare class AtlasFull extends Error {
5
+ }
6
+ /** GPU glyph word: atlas slot + 1 (bits 0..20), ink width in pixels (20..31),
7
+ * color glyph (31). Zero draws no glyph. Matches terminal.wgsl. */
8
+ export type Glyph = number;
9
+ /** CSS fonts are rasterized once per glyph/style. Warm frames never touch
10
+ * Canvas2D; Rust owns the GPU texture, cell buffer and render pipeline. */
11
+ export declare class BrowserAtlas {
12
+ private readonly gpu;
13
+ private readonly options;
14
+ private readonly dpr;
15
+ private readonly cache;
16
+ /** Warm scalar lookups index this table directly; zero marks a miss. */
17
+ readonly scalars: Uint32Array<ArrayBuffer>;
18
+ private readonly wide;
19
+ private readonly context;
20
+ private next;
21
+ readonly width: number;
22
+ readonly height: number;
23
+ private readonly columns;
24
+ private readonly capacity;
25
+ private readonly baseline;
26
+ private readonly cellWidth;
27
+ private readonly cellHeight;
28
+ constructor(document: Document, gpu: Compositor, options: Required<ITerminalOptions>, dpr: number, cellWidth: number, cellHeight: number);
29
+ private font;
30
+ reset(): void;
31
+ /** Avoid reconstructing and hashing a Unicode string on every warm cell.
32
+ * Misses fall through to the string cache, which owns rasterization. */
33
+ scalar(codepoint: number, style: number): Glyph;
34
+ private miss;
35
+ /** Block elements and braille are geometry, not type: draw them to fill the cell exactly so
36
+ * neighbours tile without seams at any line height, as the native atlas does. */
37
+ private procedural;
38
+ tile(text: string, style: number): Glyph;
39
+ }
@@ -0,0 +1,176 @@
1
+ export const ATLAS_SIZE = 2048;
2
+ /** Scalars below this bound resolve through a flat `scalar * 4 + style` table. */
3
+ const SCALAR_TABLE = 0x3000;
4
+ const MAX_SLOTS = 0xffffe;
5
+ export class AtlasFull extends Error {
6
+ }
7
+ /** CSS fonts are rasterized once per glyph/style. Warm frames never touch
8
+ * Canvas2D; Rust owns the GPU texture, cell buffer and render pipeline. */
9
+ export class BrowserAtlas {
10
+ gpu;
11
+ options;
12
+ dpr;
13
+ cache = new Map();
14
+ /** Warm scalar lookups index this table directly; zero marks a miss. */
15
+ scalars = new Uint32Array(SCALAR_TABLE * 4);
16
+ wide = new Map();
17
+ context;
18
+ next = 0;
19
+ width;
20
+ height;
21
+ columns;
22
+ capacity;
23
+ baseline;
24
+ cellWidth;
25
+ cellHeight;
26
+ constructor(document, gpu, options, dpr, cellWidth, cellHeight) {
27
+ this.gpu = gpu;
28
+ this.options = options;
29
+ this.dpr = dpr;
30
+ this.cellWidth = cellWidth;
31
+ this.cellHeight = cellHeight;
32
+ this.width = Math.ceil(cellWidth * 2 + 4);
33
+ this.height = Math.ceil(cellHeight);
34
+ this.columns = Math.floor(ATLAS_SIZE / this.width);
35
+ this.capacity = Math.min(MAX_SLOTS, this.columns * Math.floor(ATLAS_SIZE / this.height));
36
+ const canvas = document.createElement('canvas');
37
+ canvas.width = this.width;
38
+ canvas.height = this.height;
39
+ const context = canvas.getContext('2d', { willReadFrequently: true });
40
+ if (!context || !this.capacity)
41
+ throw new Error('Glyph atlas dimensions are unsupported');
42
+ this.context = context;
43
+ context.font = this.font(false, false);
44
+ const m = context.measureText('M');
45
+ const ascent = m.fontBoundingBoxAscent ?? m.actualBoundingBoxAscent;
46
+ const descent = m.fontBoundingBoxDescent ?? m.actualBoundingBoxDescent;
47
+ this.baseline = Math.round((cellHeight - ascent - descent) / 2 + ascent);
48
+ }
49
+ font(bold, italic) {
50
+ return `${italic ? 'italic' : 'normal'} ${bold ? this.options.fontWeightBold : this.options.fontWeight} ${this.options.fontSize * this.dpr}px ${this.options.fontFamily}`;
51
+ }
52
+ reset() {
53
+ this.next = 0;
54
+ this.cache.clear();
55
+ this.scalars.fill(0);
56
+ this.wide.clear();
57
+ }
58
+ /** Avoid reconstructing and hashing a Unicode string on every warm cell.
59
+ * Misses fall through to the string cache, which owns rasterization. */
60
+ scalar(codepoint, style) {
61
+ if (!codepoint || codepoint === 32)
62
+ return 0;
63
+ if (codepoint < SCALAR_TABLE) {
64
+ const index = codepoint * 4 + style;
65
+ return this.scalars[index] || (this.scalars[index] = this.miss(codepoint, style));
66
+ }
67
+ let variants = this.wide.get(codepoint);
68
+ if (!variants)
69
+ this.wide.set(codepoint, (variants = [0, 0, 0, 0]));
70
+ return variants[style] || (variants[style] = this.miss(codepoint, style));
71
+ }
72
+ miss(codepoint, style) {
73
+ return this.tile(String.fromCodePoint(codepoint), style);
74
+ }
75
+ /** Block elements and braille are geometry, not type: draw them to fill the cell exactly so
76
+ * neighbours tile without seams at any line height, as the native atlas does. */
77
+ procedural(text) {
78
+ const c = text.codePointAt(0);
79
+ if (text.length !== 1 || !((c >= 0x2580 && c <= 0x259f) || (c >= 0x2800 && c <= 0x28ff)))
80
+ return false;
81
+ const g = this.context, w = Math.round(this.cellWidth), h = Math.round(this.cellHeight);
82
+ // [x0, x1) × [y0, y1) in eighths of the cell, split points rounded once so neighbours meet.
83
+ const fill = (x0, y0, x1, y1, alpha = 1) => {
84
+ const px0 = Math.floor((x0 * w + 4) / 8), px1 = Math.floor((x1 * w + 4) / 8);
85
+ const py0 = Math.floor((y0 * h + 4) / 8), py1 = Math.floor((y1 * h + 4) / 8);
86
+ g.globalAlpha = alpha;
87
+ g.fillRect(px0, py0, px1 - px0, py1 - py0);
88
+ g.globalAlpha = 1;
89
+ };
90
+ if (c === 0x2580)
91
+ fill(0, 0, 8, 4);
92
+ else if (c <= 0x2587)
93
+ fill(0, 8 - (c - 0x2580), 8, 8);
94
+ else if (c === 0x2588)
95
+ fill(0, 0, 8, 8);
96
+ else if (c <= 0x258f)
97
+ fill(0, 0, 8 - (c - 0x2588), 8);
98
+ else if (c === 0x2590)
99
+ fill(4, 0, 8, 8);
100
+ else if (c <= 0x2593)
101
+ fill(0, 0, 8, 8, [64, 128, 191][c - 0x2591] / 255);
102
+ else if (c === 0x2594)
103
+ fill(0, 0, 8, 1);
104
+ else if (c === 0x2595)
105
+ fill(7, 0, 8, 8);
106
+ else if (c <= 0x259f) {
107
+ // Quadrants as bits: 1 upper-left, 2 upper-right, 4 lower-left, 8 lower-right.
108
+ const q = [4, 8, 1, 13, 9, 7, 11, 2, 6, 14][c - 0x2596];
109
+ if (q & 1)
110
+ fill(0, 0, 4, 4);
111
+ if (q & 2)
112
+ fill(4, 0, 8, 4);
113
+ if (q & 4)
114
+ fill(0, 4, 4, 8);
115
+ if (q & 8)
116
+ fill(4, 4, 8, 8);
117
+ }
118
+ else {
119
+ // Braille: dots 1-3 and 7 down the left column, 4-6 and 8 down the right.
120
+ const dots = [
121
+ [0, 0],
122
+ [0, 1],
123
+ [0, 2],
124
+ [1, 0],
125
+ [1, 1],
126
+ [1, 2],
127
+ [0, 3],
128
+ [1, 3],
129
+ ];
130
+ const sw = w / 2, sh = h / 4, r = Math.max(1, Math.min(sw, sh) * 0.34);
131
+ dots.forEach(([dx, dy], k) => {
132
+ if (!((c - 0x2800) & (1 << k)))
133
+ return;
134
+ const cx = (dx + 0.5) * sw, cy = (dy + 0.5) * sh;
135
+ const x0 = Math.max(0, Math.round(cx - r)), x1 = Math.min(w, Math.round(cx + r));
136
+ const y0 = Math.max(0, Math.round(cy - r)), y1 = Math.min(h, Math.round(cy + r));
137
+ g.fillRect(x0, y0, x1 - x0, y1 - y0);
138
+ });
139
+ }
140
+ return true;
141
+ }
142
+ tile(text, style) {
143
+ if (!text || text === ' ')
144
+ return 0;
145
+ const variants = this.cache.get(text);
146
+ const previous = variants?.[style];
147
+ if (previous)
148
+ return previous;
149
+ if (this.next >= this.capacity)
150
+ throw new AtlasFull();
151
+ const c = this.context;
152
+ c.clearRect(0, 0, this.width, this.height);
153
+ c.font = this.font(!!(style & 1), !!(style & 2));
154
+ c.textBaseline = 'alphabetic';
155
+ c.fillStyle = '#fff';
156
+ if (!this.procedural(text))
157
+ c.fillText(text, 0, this.baseline);
158
+ const pixels = c.getImageData(0, 0, this.width, this.height).data;
159
+ let colored = false, ink = 0;
160
+ for (let i = 0; i < pixels.length; i += 4) {
161
+ if (!pixels[i + 3])
162
+ continue;
163
+ ink = Math.max(ink, ((i >> 2) % this.width) + 1);
164
+ if (pixels[i] !== 255 || pixels[i + 1] !== 255 || pixels[i + 2] !== 255)
165
+ colored = true;
166
+ }
167
+ const slot = this.next++;
168
+ this.gpu.upload((slot % this.columns) * this.width, Math.floor(slot / this.columns) * this.height, this.width, this.height, new Uint8Array(pixels.buffer, pixels.byteOffset, pixels.byteLength));
169
+ const glyph = ((slot + 1) | (Math.min(ink, 2047) << 20) | (+colored << 31)) >>> 0;
170
+ const stored = variants ?? [0, 0, 0, 0];
171
+ stored[style] = glyph;
172
+ if (!variants)
173
+ this.cache.set(text, stored);
174
+ return glyph;
175
+ }
176
+ }
@@ -0,0 +1,120 @@
1
+ /** The only private xterm 6.0 renderer integration surface. Keep the runtime
2
+ * dependency pinned and test this boundary before upgrading it. Public API
3
+ * compatibility is inherited from upstream, not implemented with these types. */
4
+ import type { IDisposable, IEvent, Terminal, IBufferCell, IBufferLine } from './xterm-api.js';
5
+ export interface Dimensions {
6
+ css: {
7
+ canvas: {
8
+ width: number;
9
+ height: number;
10
+ };
11
+ cell: {
12
+ width: number;
13
+ height: number;
14
+ };
15
+ };
16
+ device: {
17
+ canvas: {
18
+ width: number;
19
+ height: number;
20
+ };
21
+ cell: {
22
+ width: number;
23
+ height: number;
24
+ };
25
+ char: {
26
+ width: number;
27
+ height: number;
28
+ top: number;
29
+ left: number;
30
+ };
31
+ };
32
+ }
33
+ export interface Renderer extends IDisposable {
34
+ readonly dimensions: Dimensions;
35
+ readonly onRequestRedraw: IEvent<{
36
+ start: number;
37
+ end: number;
38
+ }>;
39
+ handleDevicePixelRatioChange(): void;
40
+ handleResize(cols: number, rows: number): void;
41
+ handleCharSizeChanged(): void;
42
+ handleBlur(): void;
43
+ handleFocus(): void;
44
+ handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, column: boolean): void;
45
+ handleCursorMove(): void;
46
+ clear(): void;
47
+ renderRows(start: number, end: number): void;
48
+ clearTextureAtlas?(): void;
49
+ }
50
+ export interface Color {
51
+ rgba: number;
52
+ css: string;
53
+ }
54
+ export interface Colors {
55
+ foreground: Color;
56
+ background: Color;
57
+ cursor: Color;
58
+ cursorAccent: Color;
59
+ ansi: Color[];
60
+ selectionForeground?: Color;
61
+ selectionBackgroundOpaque: Color;
62
+ selectionInactiveBackgroundOpaque: Color;
63
+ }
64
+ export interface Cell extends IBufferCell {
65
+ readonly fg?: number;
66
+ readonly bg?: number;
67
+ readonly content?: number;
68
+ getUnderlineStyle(): number;
69
+ getUnderlineColor(): number;
70
+ isUnderlineColorDefault(): boolean;
71
+ isUnderlineColorRGB(): boolean;
72
+ isUnderlineColorPalette(): boolean;
73
+ }
74
+ export declare const CELL_HAS_EXTENDED = 268435456;
75
+ export declare const CELL_IS_COMBINED = 2097152;
76
+ export declare const CELL_CODEPOINT_MASK = 2097151;
77
+ /** BufferLineApiView and BufferLine storage in the pinned xterm 6 runtime.
78
+ * Reject unfamiliar layouts once per row; its public getters remain usable. */
79
+ export declare function packedRow(line: IBufferLine | undefined, cols: number): Uint32Array | undefined;
80
+ export interface Core {
81
+ screenElement: HTMLElement;
82
+ _renderService: {
83
+ _renderer: {
84
+ value?: Renderer;
85
+ clearAndLeak(): Renderer | undefined;
86
+ };
87
+ setRenderer(renderer: Renderer): void;
88
+ refreshRows(start: number, end: number, redraw?: boolean): void;
89
+ };
90
+ _themeService: {
91
+ colors: Colors;
92
+ onChangeColors: IEvent<Colors>;
93
+ };
94
+ optionsService: {
95
+ onOptionChange: IEvent<string>;
96
+ };
97
+ _coreBrowserService: {
98
+ dpr: number;
99
+ isFocused: boolean;
100
+ };
101
+ coreService: {
102
+ isCursorHidden: boolean;
103
+ isCursorInitialized: boolean;
104
+ decPrivateModes: {
105
+ cursorStyle?: string;
106
+ cursorBlink?: boolean;
107
+ };
108
+ };
109
+ _decorationService: {
110
+ decorations: IterableIterator<unknown>;
111
+ };
112
+ _characterJoinerService: {
113
+ _characterJoiners: unknown[];
114
+ };
115
+ linkifier: {
116
+ onShowLinkUnderline: IEvent<unknown>;
117
+ onHideLinkUnderline: IEvent<unknown>;
118
+ };
119
+ }
120
+ export declare function internals(terminal: Terminal): Core | undefined;
@@ -0,0 +1,19 @@
1
+ export const CELL_HAS_EXTENDED = 0x10000000;
2
+ export const CELL_IS_COMBINED = 0x200000;
3
+ export const CELL_CODEPOINT_MASK = 0x1fffff;
4
+ /** BufferLineApiView and BufferLine storage in the pinned xterm 6 runtime.
5
+ * Reject unfamiliar layouts once per row; its public getters remain usable. */
6
+ export function packedRow(line, cols) {
7
+ const raw = line?._line;
8
+ const words = raw?._data;
9
+ return words instanceof Uint32Array &&
10
+ raw?.length === line?.length &&
11
+ line.length >= cols &&
12
+ words.length === line.length * 3
13
+ ? words
14
+ : undefined;
15
+ }
16
+ export function internals(terminal) {
17
+ const core = terminal._core;
18
+ return core?._renderService?._renderer?.clearAndLeak && core.screenElement ? core : undefined;
19
+ }
@@ -0,0 +1,77 @@
1
+ import type { Terminal } from './xterm-api.js';
2
+ import { type Renderer } from './xterm-internals.js';
3
+ export type RendererState = 'initializing' | 'webgpu' | 'dom' | 'external';
4
+ /** u32 words per packed GPU cell: fg, bg, underline, flags, glyph. */
5
+ export declare const CELL_WORDS = 5;
6
+ /** Renderer replacement only: xterm keeps input, parser, scrollback and addons.
7
+ * A retained DOM renderer provides metrics and loss/feature fallback. */
8
+ export declare class XtermRenderer implements Renderer {
9
+ private readonly terminal;
10
+ private readonly core;
11
+ private readonly fallback;
12
+ state: RendererState;
13
+ reason: string | undefined;
14
+ private gpu;
15
+ private memory;
16
+ private atlas;
17
+ private readonly canvas;
18
+ private readonly rows;
19
+ private readonly subscriptions;
20
+ private geometry;
21
+ private font;
22
+ private full;
23
+ private staging;
24
+ /** Raw xterm words (3 per cell) that produced each staged row. Staging
25
+ * mirrors the GPU cell buffer, so a row whose words recur needs no packing:
26
+ * in place it is skipped, after scrolling it is copied within staging. */
27
+ private rowWords;
28
+ /** 1 while staging row y is exactly the packing of rowWords row y. */
29
+ private rowCached;
30
+ /** Frame stamp of the last write to each staging row this frame. */
31
+ private rowStamp;
32
+ private stamp;
33
+ private shift;
34
+ private lastViewportY;
35
+ private readonly cell;
36
+ private view;
37
+ private frame;
38
+ private disposed;
39
+ private fatal;
40
+ private hovering;
41
+ private blink;
42
+ private readonly timer;
43
+ private selectedStart;
44
+ private selectedEnd;
45
+ private columnSelection;
46
+ readonly ready: Promise<boolean>;
47
+ get active(): boolean;
48
+ get dimensions(): import("./xterm-internals.js").Dimensions;
49
+ get onRequestRedraw(): import("./xterm-api.js").IEvent<{
50
+ start: number;
51
+ end: number;
52
+ }, void>;
53
+ private constructor();
54
+ static install(terminal: Terminal): XtermRenderer | undefined;
55
+ private initialize;
56
+ private invalidate;
57
+ private fail;
58
+ private show;
59
+ private fallbackReason;
60
+ renderRows(start: number, end: number): void;
61
+ private refreshStaging;
62
+ private selected;
63
+ /** Bring staging rows start..end up to date with the buffer. Returns the
64
+ * first and last rows whose staging changed, or undefined when none did. */
65
+ private pack;
66
+ private rowSelected;
67
+ handleDevicePixelRatioChange(): void;
68
+ handleResize(cols: number, rows: number): void;
69
+ handleCharSizeChanged(): void;
70
+ handleBlur(): void;
71
+ handleFocus(): void;
72
+ handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, column: boolean): void;
73
+ handleCursorMove(): void;
74
+ clear(): void;
75
+ clearTextureAtlas(): void;
76
+ dispose(): void;
77
+ }