@xterm/addon-webgl 0.20.0-beta.2 → 0.20.0-beta.21

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.
@@ -1,839 +0,0 @@
1
- /**
2
- * Copyright (c) 2021 The xterm.js authors. All rights reserved.
3
- * @license MIT
4
- */
5
-
6
- import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
7
-
8
- interface IBlockVector {
9
- x: number;
10
- y: number;
11
- w: number;
12
- h: number;
13
- }
14
-
15
- export const blockElementDefinitions: { [index: string]: IBlockVector[] | undefined } = {
16
- // Block elements (0x2580-0x2590)
17
- '▀': [{ x: 0, y: 0, w: 8, h: 4 }], // UPPER HALF BLOCK
18
- '▁': [{ x: 0, y: 7, w: 8, h: 1 }], // LOWER ONE EIGHTH BLOCK
19
- '▂': [{ x: 0, y: 6, w: 8, h: 2 }], // LOWER ONE QUARTER BLOCK
20
- '▃': [{ x: 0, y: 5, w: 8, h: 3 }], // LOWER THREE EIGHTHS BLOCK
21
- '▄': [{ x: 0, y: 4, w: 8, h: 4 }], // LOWER HALF BLOCK
22
- '▅': [{ x: 0, y: 3, w: 8, h: 5 }], // LOWER FIVE EIGHTHS BLOCK
23
- '▆': [{ x: 0, y: 2, w: 8, h: 6 }], // LOWER THREE QUARTERS BLOCK
24
- '▇': [{ x: 0, y: 1, w: 8, h: 7 }], // LOWER SEVEN EIGHTHS BLOCK
25
- '█': [{ x: 0, y: 0, w: 8, h: 8 }], // FULL BLOCK
26
- '▉': [{ x: 0, y: 0, w: 7, h: 8 }], // LEFT SEVEN EIGHTHS BLOCK
27
- '▊': [{ x: 0, y: 0, w: 6, h: 8 }], // LEFT THREE QUARTERS BLOCK
28
- '▋': [{ x: 0, y: 0, w: 5, h: 8 }], // LEFT FIVE EIGHTHS BLOCK
29
- '▌': [{ x: 0, y: 0, w: 4, h: 8 }], // LEFT HALF BLOCK
30
- '▍': [{ x: 0, y: 0, w: 3, h: 8 }], // LEFT THREE EIGHTHS BLOCK
31
- '▎': [{ x: 0, y: 0, w: 2, h: 8 }], // LEFT ONE QUARTER BLOCK
32
- '▏': [{ x: 0, y: 0, w: 1, h: 8 }], // LEFT ONE EIGHTH BLOCK
33
- '▐': [{ x: 4, y: 0, w: 4, h: 8 }], // RIGHT HALF BLOCK
34
-
35
- // Block elements (0x2594-0x2595)
36
- '▔': [{ x: 0, y: 0, w: 8, h: 1 }], // UPPER ONE EIGHTH BLOCK
37
- '▕': [{ x: 7, y: 0, w: 1, h: 8 }], // RIGHT ONE EIGHTH BLOCK
38
-
39
- // Terminal graphic characters (0x2596-0x259F)
40
- '▖': [{ x: 0, y: 4, w: 4, h: 4 }], // QUADRANT LOWER LEFT
41
- '▗': [{ x: 4, y: 4, w: 4, h: 4 }], // QUADRANT LOWER RIGHT
42
- '▘': [{ x: 0, y: 0, w: 4, h: 4 }], // QUADRANT UPPER LEFT
43
- '▙': [{ x: 0, y: 0, w: 4, h: 8 }, { x: 0, y: 4, w: 8, h: 4 }], // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT
44
- '▚': [{ x: 0, y: 0, w: 4, h: 4 }, { x: 4, y: 4, w: 4, h: 4 }], // QUADRANT UPPER LEFT AND LOWER RIGHT
45
- '▛': [{ x: 0, y: 0, w: 4, h: 8 }, { x: 4, y: 0, w: 4, h: 4 }], // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT
46
- '▜': [{ x: 0, y: 0, w: 8, h: 4 }, { x: 4, y: 0, w: 4, h: 8 }], // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT
47
- '▝': [{ x: 4, y: 0, w: 4, h: 4 }], // QUADRANT UPPER RIGHT
48
- '▞': [{ x: 4, y: 0, w: 4, h: 4 }, { x: 0, y: 4, w: 4, h: 4 }], // QUADRANT UPPER RIGHT AND LOWER LEFT
49
- '▟': [{ x: 4, y: 0, w: 4, h: 8 }, { x: 0, y: 4, w: 8, h: 4 }], // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
50
-
51
- // VERTICAL ONE EIGHTH BLOCK-2 through VERTICAL ONE EIGHTH BLOCK-7
52
- '\u{1FB70}': [{ x: 1, y: 0, w: 1, h: 8 }],
53
- '\u{1FB71}': [{ x: 2, y: 0, w: 1, h: 8 }],
54
- '\u{1FB72}': [{ x: 3, y: 0, w: 1, h: 8 }],
55
- '\u{1FB73}': [{ x: 4, y: 0, w: 1, h: 8 }],
56
- '\u{1FB74}': [{ x: 5, y: 0, w: 1, h: 8 }],
57
- '\u{1FB75}': [{ x: 6, y: 0, w: 1, h: 8 }],
58
-
59
- // HORIZONTAL ONE EIGHTH BLOCK-2 through HORIZONTAL ONE EIGHTH BLOCK-7
60
- '\u{1FB76}': [{ x: 0, y: 1, w: 8, h: 1 }],
61
- '\u{1FB77}': [{ x: 0, y: 2, w: 8, h: 1 }],
62
- '\u{1FB78}': [{ x: 0, y: 3, w: 8, h: 1 }],
63
- '\u{1FB79}': [{ x: 0, y: 4, w: 8, h: 1 }],
64
- '\u{1FB7A}': [{ x: 0, y: 5, w: 8, h: 1 }],
65
- '\u{1FB7B}': [{ x: 0, y: 6, w: 8, h: 1 }],
66
-
67
- // LEFT AND LOWER ONE EIGHTH BLOCK
68
- '\u{1FB7C}': [{ x: 0, y: 0, w: 1, h: 8 }, { x: 0, y: 7, w: 8, h: 1 }],
69
- // LEFT AND UPPER ONE EIGHTH BLOCK
70
- '\u{1FB7D}': [{ x: 0, y: 0, w: 1, h: 8 }, { x: 0, y: 0, w: 8, h: 1 }],
71
- // RIGHT AND UPPER ONE EIGHTH BLOCK
72
- '\u{1FB7E}': [{ x: 7, y: 0, w: 1, h: 8 }, { x: 0, y: 0, w: 8, h: 1 }],
73
- // RIGHT AND LOWER ONE EIGHTH BLOCK
74
- '\u{1FB7F}': [{ x: 7, y: 0, w: 1, h: 8 }, { x: 0, y: 7, w: 8, h: 1 }],
75
- // UPPER AND LOWER ONE EIGHTH BLOCK
76
- '\u{1FB80}': [{ x: 0, y: 0, w: 8, h: 1 }, { x: 0, y: 7, w: 8, h: 1 }],
77
- // HORIZONTAL ONE EIGHTH BLOCK-1358
78
- '\u{1FB81}': [{ x: 0, y: 0, w: 8, h: 1 }, { x: 0, y: 2, w: 8, h: 1 }, { x: 0, y: 4, w: 8, h: 1 }, { x: 0, y: 7, w: 8, h: 1 }],
79
-
80
- // UPPER ONE QUARTER BLOCK
81
- '\u{1FB82}': [{ x: 0, y: 0, w: 8, h: 2 }],
82
- // UPPER THREE EIGHTHS BLOCK
83
- '\u{1FB83}': [{ x: 0, y: 0, w: 8, h: 3 }],
84
- // UPPER FIVE EIGHTHS BLOCK
85
- '\u{1FB84}': [{ x: 0, y: 0, w: 8, h: 5 }],
86
- // UPPER THREE QUARTERS BLOCK
87
- '\u{1FB85}': [{ x: 0, y: 0, w: 8, h: 6 }],
88
- // UPPER SEVEN EIGHTHS BLOCK
89
- '\u{1FB86}': [{ x: 0, y: 0, w: 8, h: 7 }],
90
-
91
- // RIGHT ONE QUARTER BLOCK
92
- '\u{1FB87}': [{ x: 6, y: 0, w: 2, h: 8 }],
93
- // RIGHT THREE EIGHTHS B0OCK
94
- '\u{1FB88}': [{ x: 5, y: 0, w: 3, h: 8 }],
95
- // RIGHT FIVE EIGHTHS BL0CK
96
- '\u{1FB89}': [{ x: 3, y: 0, w: 5, h: 8 }],
97
- // RIGHT THREE QUARTERS 0LOCK
98
- '\u{1FB8A}': [{ x: 2, y: 0, w: 6, h: 8 }],
99
- // RIGHT SEVEN EIGHTHS B0OCK
100
- '\u{1FB8B}': [{ x: 1, y: 0, w: 7, h: 8 }],
101
-
102
- // CHECKER BOARD FILL
103
- '\u{1FB95}': [
104
- { x: 0, y: 0, w: 2, h: 2 }, { x: 4, y: 0, w: 2, h: 2 },
105
- { x: 2, y: 2, w: 2, h: 2 }, { x: 6, y: 2, w: 2, h: 2 },
106
- { x: 0, y: 4, w: 2, h: 2 }, { x: 4, y: 4, w: 2, h: 2 },
107
- { x: 2, y: 6, w: 2, h: 2 }, { x: 6, y: 6, w: 2, h: 2 }
108
- ],
109
- // INVERSE CHECKER BOARD FILL
110
- '\u{1FB96}': [
111
- { x: 2, y: 0, w: 2, h: 2 }, { x: 6, y: 0, w: 2, h: 2 },
112
- { x: 0, y: 2, w: 2, h: 2 }, { x: 4, y: 2, w: 2, h: 2 },
113
- { x: 2, y: 4, w: 2, h: 2 }, { x: 6, y: 4, w: 2, h: 2 },
114
- { x: 0, y: 6, w: 2, h: 2 }, { x: 4, y: 6, w: 2, h: 2 }
115
- ],
116
- // HEAVY HORIZONTAL FILL (upper middle and lower one quarter block)
117
- '\u{1FB97}': [{ x: 0, y: 2, w: 8, h: 2 }, { x: 0, y: 6, w: 8, h: 2 }]
118
- };
119
-
120
- /**
121
- * Generates a drawing function for sextant characters. Sextants are a 2x3 grid where each cell
122
- * can be on or off.
123
- * @param pattern A 6-bit pattern where bit 0 = top-left, bit 1 = top-right, bit 2 = middle-left,
124
- * bit 3 = middle-right, bit 4 = bottom-left, bit 5 = bottom-right
125
- */
126
- function sextant(pattern: number): DrawFunctionDefinition {
127
- return () => {
128
- // Sextant grid: 2 columns, 3 rows
129
- // Row heights in 8ths: top=3, middle=2, bottom=3
130
- // Column widths: left=4, right=4
131
- const rects: string[] = [];
132
- const colW = 0.5; // Each column is half width
133
- const rowH = [3 / 8, 2 / 8, 3 / 8]; // Row heights as fractions
134
- const rowY = [0, 3 / 8, 5 / 8]; // Row Y positions
135
-
136
- for (let row = 0; row < 3; row++) {
137
- const leftBit = (pattern >> (row * 2)) & 1;
138
- const rightBit = (pattern >> (row * 2 + 1)) & 1;
139
-
140
- if (leftBit && rightBit) {
141
- // Full row
142
- rects.push(`M0,${rowY[row]} L1,${rowY[row]} L1,${rowY[row] + rowH[row]} L0,${rowY[row] + rowH[row]} Z`);
143
- } else if (leftBit) {
144
- rects.push(`M0,${rowY[row]} L${colW},${rowY[row]} L${colW},${rowY[row] + rowH[row]} L0,${rowY[row] + rowH[row]} Z`);
145
- } else if (rightBit) {
146
- rects.push(`M${colW},${rowY[row]} L1,${rowY[row]} L1,${rowY[row] + rowH[row]} L${colW},${rowY[row] + rowH[row]} Z`);
147
- }
148
- }
149
- return rects.join(' ');
150
- };
151
- }
152
-
153
- export const symbolsForLegacyComputingDefinitions: { [index: string]: DrawFunctionDefinition | undefined } = {
154
- // Block sextants (0x1FB00-0x1FB3B)
155
- // Each sextant is a 2x3 grid of cells in an 8x8 block
156
- // Cell positions: bit 0=top-left, bit 1=top-right, bit 2=middle-left, bit 3=middle-right,
157
- // bit 4=bottom-left, bit 5=bottom-right
158
- // Patterns 0 (empty), 21 (left half), 42 (right half), 63 (full) are excluded as they exist
159
- // elsewhere
160
- '\u{1FB00}': sextant(0b000001), // BLOCK SEXTANT-1
161
- '\u{1FB01}': sextant(0b000010), // BLOCK SEXTANT-2
162
- '\u{1FB02}': sextant(0b000011), // BLOCK SEXTANT-12 (upper one third block)
163
- '\u{1FB03}': sextant(0b000100), // BLOCK SEXTANT-3
164
- '\u{1FB04}': sextant(0b000101), // BLOCK SEXTANT-13
165
- '\u{1FB05}': sextant(0b000110), // BLOCK SEXTANT-23
166
- '\u{1FB06}': sextant(0b000111), // BLOCK SEXTANT-123
167
- '\u{1FB07}': sextant(0b001000), // BLOCK SEXTANT-4
168
- '\u{1FB08}': sextant(0b001001), // BLOCK SEXTANT-14
169
- '\u{1FB09}': sextant(0b001010), // BLOCK SEXTANT-24
170
- '\u{1FB0A}': sextant(0b001011), // BLOCK SEXTANT-124
171
- '\u{1FB0B}': sextant(0b001100), // BLOCK SEXTANT-34 (middle one third block)
172
- '\u{1FB0C}': sextant(0b001101), // BLOCK SEXTANT-134
173
- '\u{1FB0D}': sextant(0b001110), // BLOCK SEXTANT-234
174
- '\u{1FB0E}': sextant(0b001111), // BLOCK SEXTANT-1234 (upper two thirds block)
175
- '\u{1FB0F}': sextant(0b010000), // BLOCK SEXTANT-5
176
- '\u{1FB10}': sextant(0b010001), // BLOCK SEXTANT-15
177
- '\u{1FB11}': sextant(0b010010), // BLOCK SEXTANT-25
178
- '\u{1FB12}': sextant(0b010011), // BLOCK SEXTANT-125
179
- '\u{1FB13}': sextant(0b010100), // BLOCK SEXTANT-35
180
- // Pattern 21 (0x15 = 0b010101) = left half block, skipped (exists as U+258C)
181
- '\u{1FB14}': sextant(0b010110), // BLOCK SEXTANT-235
182
- '\u{1FB15}': sextant(0b010111), // BLOCK SEXTANT-1235
183
- '\u{1FB16}': sextant(0b011000), // BLOCK SEXTANT-45
184
- '\u{1FB17}': sextant(0b011001), // BLOCK SEXTANT-145
185
- '\u{1FB18}': sextant(0b011010), // BLOCK SEXTANT-245
186
- '\u{1FB19}': sextant(0b011011), // BLOCK SEXTANT-1245
187
- '\u{1FB1A}': sextant(0b011100), // BLOCK SEXTANT-345
188
- '\u{1FB1B}': sextant(0b011101), // BLOCK SEXTANT-1345
189
- '\u{1FB1C}': sextant(0b011110), // BLOCK SEXTANT-2345
190
- '\u{1FB1D}': sextant(0b011111), // BLOCK SEXTANT-12345
191
- '\u{1FB1E}': sextant(0b100000), // BLOCK SEXTANT-6
192
- '\u{1FB1F}': sextant(0b100001), // BLOCK SEXTANT-16
193
- '\u{1FB20}': sextant(0b100010), // BLOCK SEXTANT-26
194
- '\u{1FB21}': sextant(0b100011), // BLOCK SEXTANT-126
195
- '\u{1FB22}': sextant(0b100100), // BLOCK SEXTANT-36
196
- '\u{1FB23}': sextant(0b100101), // BLOCK SEXTANT-136
197
- '\u{1FB24}': sextant(0b100110), // BLOCK SEXTANT-236
198
- '\u{1FB25}': sextant(0b100111), // BLOCK SEXTANT-1236
199
- '\u{1FB26}': sextant(0b101000), // BLOCK SEXTANT-46
200
- '\u{1FB27}': sextant(0b101001), // BLOCK SEXTANT-146
201
- // Pattern 42 (0x2A = 0b101010) = right half block, skipped (exists as U+2590)
202
- '\u{1FB28}': sextant(0b101011), // BLOCK SEXTANT-1246
203
- '\u{1FB29}': sextant(0b101100), // BLOCK SEXTANT-346
204
- '\u{1FB2A}': sextant(0b101101), // BLOCK SEXTANT-1346
205
- '\u{1FB2B}': sextant(0b101110), // BLOCK SEXTANT-2346
206
- '\u{1FB2C}': sextant(0b101111), // BLOCK SEXTANT-12346
207
- '\u{1FB2D}': sextant(0b110000), // BLOCK SEXTANT-56 (lower one third block)
208
- '\u{1FB2E}': sextant(0b110001), // BLOCK SEXTANT-156
209
- '\u{1FB2F}': sextant(0b110010), // BLOCK SEXTANT-256
210
- '\u{1FB30}': sextant(0b110011), // BLOCK SEXTANT-1256 (upper and lower one
211
- // third block)
212
- '\u{1FB31}': sextant(0b110100), // BLOCK SEXTANT-356
213
- '\u{1FB32}': sextant(0b110101), // BLOCK SEXTANT-1356
214
- '\u{1FB33}': sextant(0b110110), // BLOCK SEXTANT-2356
215
- '\u{1FB34}': sextant(0b110111), // BLOCK SEXTANT-12356
216
- '\u{1FB35}': sextant(0b111000), // BLOCK SEXTANT-456
217
- '\u{1FB36}': sextant(0b111001), // BLOCK SEXTANT-1456
218
- '\u{1FB37}': sextant(0b111010), // BLOCK SEXTANT-2456
219
- '\u{1FB38}': sextant(0b111011), // BLOCK SEXTANT-12456
220
- '\u{1FB39}': sextant(0b111100), // BLOCK SEXTANT-3456 (lower two thirds block)
221
- '\u{1FB3A}': sextant(0b111101), // BLOCK SEXTANT-13456
222
- '\u{1FB3B}': sextant(0b111110) // BLOCK SEXTANT-23456
223
- // Pattern 63 (0x3F = 0b111111) = full block, skipped (exists as U+2588)
224
- };
225
-
226
- type PatternDefinition = number[][];
227
-
228
- /**
229
- * Defines the repeating pattern used by special characters, the pattern is made up of a 2d array of
230
- * pixel values to be filled (1) or not filled (0).
231
- */
232
- const patternCharacterDefinitions: { [key: string]: PatternDefinition | undefined } = {
233
- // Shade characters (0x2591-0x2593)
234
- '░': [ // LIGHT SHADE (25%)
235
- [1, 0, 0, 0],
236
- [0, 0, 0, 0],
237
- [0, 0, 1, 0],
238
- [0, 0, 0, 0]
239
- ],
240
- '▒': [ // MEDIUM SHADE (50%)
241
- [1, 0],
242
- [0, 0],
243
- [0, 1],
244
- [0, 0]
245
- ],
246
- '▓': [ // DARK SHADE (75%)
247
- [0, 1],
248
- [1, 1],
249
- [1, 0],
250
- [1, 1]
251
- ]
252
- };
253
-
254
- const enum Shapes {
255
- /** │ */ TOP_TO_BOTTOM = 'M.5,0 L.5,1',
256
- /** ─ */ LEFT_TO_RIGHT = 'M0,.5 L1,.5',
257
-
258
- /** └ */ TOP_TO_RIGHT = 'M.5,0 L.5,.5 L1,.5',
259
- /** ┘ */ TOP_TO_LEFT = 'M.5,0 L.5,.5 L0,.5',
260
- /** ┐ */ LEFT_TO_BOTTOM = 'M0,.5 L.5,.5 L.5,1',
261
- /** ┌ */ RIGHT_TO_BOTTOM = 'M0.5,1 L.5,.5 L1,.5',
262
-
263
- /** ╵ */ MIDDLE_TO_TOP = 'M.5,.5 L.5,0',
264
- /** ╴ */ MIDDLE_TO_LEFT = 'M.5,.5 L0,.5',
265
- /** ╶ */ MIDDLE_TO_RIGHT = 'M.5,.5 L1,.5',
266
- /** ╷ */ MIDDLE_TO_BOTTOM = 'M.5,.5 L.5,1',
267
-
268
- /** ┴ */ T_TOP = 'M0,.5 L1,.5 M.5,.5 L.5,0',
269
- /** ┤ */ T_LEFT = 'M.5,0 L.5,1 M.5,.5 L0,.5',
270
- /** ├ */ T_RIGHT = 'M.5,0 L.5,1 M.5,.5 L1,.5',
271
- /** ┬ */ T_BOTTOM = 'M0,.5 L1,.5 M.5,.5 L.5,1',
272
-
273
- /** ┼ */ CROSS = 'M0,.5 L1,.5 M.5,0 L.5,1',
274
-
275
- /** ╌ */ TWO_DASHES_HORIZONTAL = 'M.1,.5 L.4,.5 M.6,.5 L.9,.5', // .2 empty, .3 filled
276
- /** ┄ */ THREE_DASHES_HORIZONTAL = 'M.0667,.5 L.2667,.5 M.4,.5 L.6,.5 M.7333,.5 L.9333,.5', // .1333 empty, .2 filled
277
- /** ┉ */ FOUR_DASHES_HORIZONTAL = 'M.05,.5 L.2,.5 M.3,.5 L.45,.5 M.55,.5 L.7,.5 M.8,.5 L.95,.5', // .1 empty, .15 filled
278
- /** ╎ */ TWO_DASHES_VERTICAL = 'M.5,.1 L.5,.4 M.5,.6 L.5,.9',
279
- /** ┆ */ THREE_DASHES_VERTICAL = 'M.5,.0667 L.5,.2667 M.5,.4 L.5,.6 M.5,.7333 L.5,.9333',
280
- /** ┊ */ FOUR_DASHES_VERTICAL = 'M.5,.05 L.5,.2 M.5,.3 L.5,.45 L.5,.55 M.5,.7 L.5,.95',
281
- }
282
-
283
- const enum Style {
284
- NORMAL = 1,
285
- BOLD = 3
286
- }
287
-
288
- /**
289
- * @param xp The percentage of 15% of the x axis.
290
- * @param yp The percentage of 15% of the x axis on the y axis.
291
- */
292
- type DrawFunctionDefinition = (xp: number, yp: number) => string;
293
-
294
- /**
295
- * This contains the definitions of all box drawing characters in the format of SVG paths (ie. the
296
- * svg d attribute).
297
- */
298
- export const boxDrawingDefinitions: { [character: string]: { [fontWeight: number]: string | DrawFunctionDefinition } | undefined } = {
299
- // Uniform normal and bold
300
- '─': { [Style.NORMAL]: Shapes.LEFT_TO_RIGHT },
301
- '━': { [Style.BOLD]: Shapes.LEFT_TO_RIGHT },
302
- '│': { [Style.NORMAL]: Shapes.TOP_TO_BOTTOM },
303
- '┃': { [Style.BOLD]: Shapes.TOP_TO_BOTTOM },
304
- '┌': { [Style.NORMAL]: Shapes.RIGHT_TO_BOTTOM },
305
- '┏': { [Style.BOLD]: Shapes.RIGHT_TO_BOTTOM },
306
- '┐': { [Style.NORMAL]: Shapes.LEFT_TO_BOTTOM },
307
- '┓': { [Style.BOLD]: Shapes.LEFT_TO_BOTTOM },
308
- '└': { [Style.NORMAL]: Shapes.TOP_TO_RIGHT },
309
- '┗': { [Style.BOLD]: Shapes.TOP_TO_RIGHT },
310
- '┘': { [Style.NORMAL]: Shapes.TOP_TO_LEFT },
311
- '┛': { [Style.BOLD]: Shapes.TOP_TO_LEFT },
312
- '├': { [Style.NORMAL]: Shapes.T_RIGHT },
313
- '┣': { [Style.BOLD]: Shapes.T_RIGHT },
314
- '┤': { [Style.NORMAL]: Shapes.T_LEFT },
315
- '┫': { [Style.BOLD]: Shapes.T_LEFT },
316
- '┬': { [Style.NORMAL]: Shapes.T_BOTTOM },
317
- '┳': { [Style.BOLD]: Shapes.T_BOTTOM },
318
- '┴': { [Style.NORMAL]: Shapes.T_TOP },
319
- '┻': { [Style.BOLD]: Shapes.T_TOP },
320
- '┼': { [Style.NORMAL]: Shapes.CROSS },
321
- '╋': { [Style.BOLD]: Shapes.CROSS },
322
- '╴': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT },
323
- '╸': { [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
324
- '╵': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP },
325
- '╹': { [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
326
- '╶': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT },
327
- '╺': { [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
328
- '╷': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM },
329
- '╻': { [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
330
-
331
- // Double border
332
- '═': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` },
333
- '║': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` },
334
- '╒': { [Style.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}` },
335
- '╓': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},1 L${.5 - xp},.5 L1,.5 M${.5 + xp},.5 L${.5 + xp},1` },
336
- '╔': { [Style.NORMAL]: (xp, yp) => `M1,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1` },
337
- '╕': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L.5,${.5 - yp} L.5,1 M0,${.5 + yp} L.5,${.5 + yp}` },
338
- '╖': { [Style.NORMAL]: (xp, yp) => `M${.5 + xp},1 L${.5 + xp},.5 L0,.5 M${.5 - xp},.5 L${.5 - xp},1` },
339
- '╗': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},1` },
340
- '╘': { [Style.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 + yp} L1,${.5 + yp} M.5,${.5 - yp} L1,${.5 - yp}` },
341
- '╙': { [Style.NORMAL]: (xp, yp) => `M1,.5 L${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0` },
342
- '╚': { [Style.NORMAL]: (xp, yp) => `M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0 M1,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},0` },
343
- '╛': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L.5,${.5 + yp} L.5,0 M0,${.5 - yp} L.5,${.5 - yp}` },
344
- '╜': { [Style.NORMAL]: (xp, yp) => `M0,.5 L${.5 + xp},.5 L${.5 + xp},0 M${.5 - xp},.5 L${.5 - xp},0` },
345
- '╝': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M0,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},0` },
346
- '╞': { [Style.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M.5,${.5 - yp} L1,${.5 - yp} M.5,${.5 + yp} L1,${.5 + yp}` },
347
- '╟': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1 M${.5 + xp},.5 L1,.5` },
348
- '╠': { [Style.NORMAL]: (xp, yp) => `M${.5 - xp},0 L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` },
349
- '╡': { [Style.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L.5,${.5 - yp} M0,${.5 + yp} L.5,${.5 + yp}` },
350
- '╢': { [Style.NORMAL]: (xp, yp) => `M0,.5 L${.5 - xp},.5 M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` },
351
- '╣': { [Style.NORMAL]: (xp, yp) => `M${.5 + xp},0 L${.5 + xp},1 M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0` },
352
- '╤': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp} M.5,${.5 + yp} L.5,1` },
353
- '╥': { [Style.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},1 M${.5 + xp},.5 L${.5 + xp},1` },
354
- '╦': { [Style.NORMAL]: (xp, yp) => `M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1` },
355
- '╧': { [Style.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - yp} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` },
356
- '╨': { [Style.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},.5 L${.5 - xp},0 M${.5 + xp},.5 L${.5 + xp},0` },
357
- '╩': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L1,${.5 + yp} M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` },
358
- '╪': { [Style.NORMAL]: (xp, yp) => `${Shapes.TOP_TO_BOTTOM} M0,${.5 - yp} L1,${.5 - yp} M0,${.5 + yp} L1,${.5 + yp}` },
359
- '╫': { [Style.NORMAL]: (xp, yp) => `${Shapes.LEFT_TO_RIGHT} M${.5 - xp},0 L${.5 - xp},1 M${.5 + xp},0 L${.5 + xp},1` },
360
- '╬': { [Style.NORMAL]: (xp, yp) => `M0,${.5 + yp} L${.5 - xp},${.5 + yp} L${.5 - xp},1 M1,${.5 + yp} L${.5 + xp},${.5 + yp} L${.5 + xp},1 M0,${.5 - yp} L${.5 - xp},${.5 - yp} L${.5 - xp},0 M1,${.5 - yp} L${.5 + xp},${.5 - yp} L${.5 + xp},0` },
361
-
362
- // Diagonal
363
- '╱': { [Style.NORMAL]: 'M1,0 L0,1' },
364
- '╲': { [Style.NORMAL]: 'M0,0 L1,1' },
365
- '╳': { [Style.NORMAL]: 'M1,0 L0,1 M0,0 L1,1' },
366
-
367
- // Mixed weight
368
- '╼': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
369
- '╽': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
370
- '╾': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
371
- '╿': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
372
- '┍': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
373
- '┎': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
374
- '┑': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
375
- '┒': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
376
- '┕': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
377
- '┖': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
378
- '┙': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
379
- '┚': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
380
- '┝': { [Style.NORMAL]: Shapes.TOP_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
381
- '┞': { [Style.NORMAL]: Shapes.RIGHT_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
382
- '┟': { [Style.NORMAL]: Shapes.TOP_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
383
- '┠': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.TOP_TO_BOTTOM },
384
- '┡': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.TOP_TO_RIGHT },
385
- '┢': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: Shapes.RIGHT_TO_BOTTOM },
386
- '┥': { [Style.NORMAL]: Shapes.TOP_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
387
- '┦': { [Style.NORMAL]: Shapes.LEFT_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
388
- '┧': { [Style.NORMAL]: Shapes.TOP_TO_LEFT, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
389
- '┨': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: Shapes.TOP_TO_BOTTOM },
390
- '┩': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.TOP_TO_LEFT },
391
- '┪': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: Shapes.LEFT_TO_BOTTOM },
392
- '┭': { [Style.NORMAL]: Shapes.RIGHT_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
393
- '┮': { [Style.NORMAL]: Shapes.LEFT_TO_BOTTOM, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
394
- '┯': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: Shapes.LEFT_TO_RIGHT },
395
- '┰': { [Style.NORMAL]: Shapes.LEFT_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
396
- '┱': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.LEFT_TO_BOTTOM },
397
- '┲': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: Shapes.RIGHT_TO_BOTTOM },
398
- '┵': { [Style.NORMAL]: Shapes.TOP_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
399
- '┶': { [Style.NORMAL]: Shapes.TOP_TO_LEFT, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
400
- '┷': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: Shapes.LEFT_TO_RIGHT },
401
- '┸': { [Style.NORMAL]: Shapes.LEFT_TO_RIGHT, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
402
- '┹': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: Shapes.TOP_TO_LEFT },
403
- '┺': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: Shapes.TOP_TO_RIGHT },
404
- '┽': { [Style.NORMAL]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_RIGHT}`, [Style.BOLD]: Shapes.MIDDLE_TO_LEFT },
405
- '┾': { [Style.NORMAL]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_LEFT}`, [Style.BOLD]: Shapes.MIDDLE_TO_RIGHT },
406
- '┿': { [Style.NORMAL]: Shapes.TOP_TO_BOTTOM, [Style.BOLD]: Shapes.LEFT_TO_RIGHT },
407
- '╀': { [Style.NORMAL]: `${Shapes.LEFT_TO_RIGHT} ${Shapes.MIDDLE_TO_BOTTOM}`, [Style.BOLD]: Shapes.MIDDLE_TO_TOP },
408
- '╁': { [Style.NORMAL]: `${Shapes.MIDDLE_TO_TOP} ${Shapes.LEFT_TO_RIGHT}`, [Style.BOLD]: Shapes.MIDDLE_TO_BOTTOM },
409
- '╂': { [Style.NORMAL]: Shapes.LEFT_TO_RIGHT, [Style.BOLD]: Shapes.TOP_TO_BOTTOM },
410
- '╃': { [Style.NORMAL]: Shapes.RIGHT_TO_BOTTOM, [Style.BOLD]: Shapes.TOP_TO_LEFT },
411
- '╄': { [Style.NORMAL]: Shapes.LEFT_TO_BOTTOM, [Style.BOLD]: Shapes.TOP_TO_RIGHT },
412
- '╅': { [Style.NORMAL]: Shapes.TOP_TO_RIGHT, [Style.BOLD]: Shapes.LEFT_TO_BOTTOM },
413
- '╆': { [Style.NORMAL]: Shapes.TOP_TO_LEFT, [Style.BOLD]: Shapes.RIGHT_TO_BOTTOM },
414
- '╇': { [Style.NORMAL]: Shapes.MIDDLE_TO_BOTTOM, [Style.BOLD]: `${Shapes.MIDDLE_TO_TOP} ${Shapes.LEFT_TO_RIGHT}` },
415
- '╈': { [Style.NORMAL]: Shapes.MIDDLE_TO_TOP, [Style.BOLD]: `${Shapes.LEFT_TO_RIGHT} ${Shapes.MIDDLE_TO_BOTTOM}` },
416
- '╉': { [Style.NORMAL]: Shapes.MIDDLE_TO_RIGHT, [Style.BOLD]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_LEFT}` },
417
- '╊': { [Style.NORMAL]: Shapes.MIDDLE_TO_LEFT, [Style.BOLD]: `${Shapes.TOP_TO_BOTTOM} ${Shapes.MIDDLE_TO_RIGHT}` },
418
-
419
- // Dashed
420
- '╌': { [Style.NORMAL]: Shapes.TWO_DASHES_HORIZONTAL },
421
- '╍': { [Style.BOLD]: Shapes.TWO_DASHES_HORIZONTAL },
422
- '┄': { [Style.NORMAL]: Shapes.THREE_DASHES_HORIZONTAL },
423
- '┅': { [Style.BOLD]: Shapes.THREE_DASHES_HORIZONTAL },
424
- '┈': { [Style.NORMAL]: Shapes.FOUR_DASHES_HORIZONTAL },
425
- '┉': { [Style.BOLD]: Shapes.FOUR_DASHES_HORIZONTAL },
426
- '╎': { [Style.NORMAL]: Shapes.TWO_DASHES_VERTICAL },
427
- '╏': { [Style.BOLD]: Shapes.TWO_DASHES_VERTICAL },
428
- '┆': { [Style.NORMAL]: Shapes.THREE_DASHES_VERTICAL },
429
- '┇': { [Style.BOLD]: Shapes.THREE_DASHES_VERTICAL },
430
- '┊': { [Style.NORMAL]: Shapes.FOUR_DASHES_VERTICAL },
431
- '┋': { [Style.BOLD]: Shapes.FOUR_DASHES_VERTICAL },
432
-
433
- // Curved
434
- '╭': { [Style.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 + (yp / .15 * .5)} C.5,${.5 + (yp / .15 * .5)},.5,.5,1,.5` },
435
- '╮': { [Style.NORMAL]: (xp, yp) => `M.5,1 L.5,${.5 + (yp / .15 * .5)} C.5,${.5 + (yp / .15 * .5)},.5,.5,0,.5` },
436
- '╯': { [Style.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - (yp / .15 * .5)} C.5,${.5 - (yp / .15 * .5)},.5,.5,0,.5` },
437
- '╰': { [Style.NORMAL]: (xp, yp) => `M.5,0 L.5,${.5 - (yp / .15 * .5)} C.5,${.5 - (yp / .15 * .5)},.5,.5,1,.5` }
438
- };
439
-
440
- interface IVectorShape {
441
- d: string;
442
- type: VectorType;
443
- leftPadding?: number;
444
- rightPadding?: number;
445
- }
446
-
447
- const enum VectorType {
448
- FILL,
449
- STROKE
450
- }
451
-
452
- /**
453
- * This contains the definitions of the primarily used box drawing characters as vector shapes. The
454
- * reason these characters are defined specially is to avoid common problems if a user's font has
455
- * not been patched with powerline characters and also to get pixel perfect rendering as rendering
456
- * issues can occur around AA/SPAA.
457
- *
458
- * The line variants draw beyond the cell and get clipped to ensure the end of the line is not
459
- * visible.
460
- *
461
- * Original symbols defined in https://github.com/powerline/fontpatcher
462
- */
463
- export const powerlineDefinitions: { [index: string]: IVectorShape } = {
464
- // Git branch
465
- '\u{E0A0}': { d: 'M.3,1 L.03,1 L.03,.88 C.03,.82,.06,.78,.11,.73 C.15,.7,.2,.68,.28,.65 L.43,.6 C.49,.58,.53,.56,.56,.53 C.59,.5,.6,.47,.6,.43 L.6,.27 L.4,.27 L.69,.1 L.98,.27 L.78,.27 L.78,.46 C.78,.52,.76,.56,.72,.61 C.68,.66,.63,.67,.56,.7 L.48,.72 C.42,.74,.38,.76,.35,.78 C.32,.8,.31,.84,.31,.88 L.31,1 M.3,.5 L.03,.59 L.03,.09 L.3,.09 L.3,.655', type: VectorType.FILL },
466
- // L N
467
- '\u{E0A1}': { d: 'M.7,.4 L.7,.47 L.2,.47 L.2,.03 L.355,.03 L.355,.4 L.705,.4 M.7,.5 L.86,.5 L.86,.95 L.69,.95 L.44,.66 L.46,.86 L.46,.95 L.3,.95 L.3,.49 L.46,.49 L.71,.78 L.69,.565 L.69,.5', type: VectorType.FILL },
468
- // Lock
469
- '\u{E0A2}': { d: 'M.25,.94 C.16,.94,.11,.92,.11,.87 L.11,.53 C.11,.48,.15,.455,.23,.45 L.23,.3 C.23,.25,.26,.22,.31,.19 C.36,.16,.43,.15,.51,.15 C.59,.15,.66,.16,.71,.19 C.77,.22,.79,.26,.79,.3 L.79,.45 C.87,.45,.91,.48,.91,.53 L.91,.87 C.91,.92,.86,.94,.77,.94 L.24,.94 M.53,.2 C.49,.2,.45,.21,.42,.23 C.39,.25,.38,.27,.38,.3 L.38,.45 L.68,.45 L.68,.3 C.68,.27,.67,.25,.64,.23 C.61,.21,.58,.2,.53,.2 M.58,.82 L.58,.66 C.63,.65,.65,.63,.65,.6 C.65,.58,.64,.57,.61,.56 C.58,.55,.56,.54,.52,.54 C.48,.54,.46,.55,.43,.56 C.4,.57,.39,.59,.39,.6 C.39,.63,.41,.64,.46,.66 L.46,.82 L.57,.82', type: VectorType.FILL },
470
- // Right triangle solid
471
- '\u{E0B0}': { d: 'M0,0 L1,.5 L0,1', type: VectorType.FILL, rightPadding: 2 },
472
- // Right triangle line
473
- '\u{E0B1}': { d: 'M-1,-.5 L1,.5 L-1,1.5', type: VectorType.STROKE, leftPadding: 1, rightPadding: 1 },
474
- // Left triangle solid
475
- '\u{E0B2}': { d: 'M1,0 L0,.5 L1,1', type: VectorType.FILL, leftPadding: 2 },
476
- // Left triangle line
477
- '\u{E0B3}': { d: 'M2,-.5 L0,.5 L2,1.5', type: VectorType.STROKE, leftPadding: 1, rightPadding: 1 },
478
- // Right semi-circle solid
479
- '\u{E0B4}': { d: 'M0,0 L0,1 C0.552,1,1,0.776,1,.5 C1,0.224,0.552,0,0,0', type: VectorType.FILL, rightPadding: 1 },
480
- // Right semi-circle line
481
- '\u{E0B5}': { d: 'M.2,1 C.422,1,.8,.826,.78,.5 C.8,.174,0.422,0,.2,0', type: VectorType.STROKE, rightPadding: 1 },
482
- // Left semi-circle solid
483
- '\u{E0B6}': { d: 'M1,0 L1,1 C0.448,1,0,0.776,0,.5 C0,0.224,0.448,0,1,0', type: VectorType.FILL, leftPadding: 1 },
484
- // Left semi-circle line
485
- '\u{E0B7}': { d: 'M.8,1 C0.578,1,0.2,.826,.22,.5 C0.2,0.174,0.578,0,0.8,0', type: VectorType.STROKE, leftPadding: 1 },
486
- // Lower left triangle
487
- '\u{E0B8}': { d: 'M-.5,-.5 L1.5,1.5 L-.5,1.5', type: VectorType.FILL },
488
- // Backslash separator
489
- '\u{E0B9}': { d: 'M-.5,-.5 L1.5,1.5', type: VectorType.STROKE, leftPadding: 1, rightPadding: 1 },
490
- // Lower right triangle
491
- '\u{E0BA}': { d: 'M1.5,-.5 L-.5,1.5 L1.5,1.5', type: VectorType.FILL },
492
- // Upper left triangle
493
- '\u{E0BC}': { d: 'M1.5,-.5 L-.5,1.5 L-.5,-.5', type: VectorType.FILL },
494
- // Forward slash separator
495
- '\u{E0BD}': { d: 'M1.5,-.5 L-.5,1.5', type: VectorType.STROKE, leftPadding: 1, rightPadding: 1 },
496
- // Upper right triangle
497
- '\u{E0BE}': { d: 'M-.5,-.5 L1.5,1.5 L1.5,-.5', type: VectorType.FILL }
498
- };
499
- // Forward slash separator redundant
500
- powerlineDefinitions['\u{E0BB}'] = powerlineDefinitions['\u{E0BD}'];
501
- // Backslash separator redundant
502
- powerlineDefinitions['\u{E0BF}'] = powerlineDefinitions['\u{E0B9}'];
503
-
504
- /**
505
- * Try drawing a custom block element or box drawing character, returning whether it was
506
- * successfully drawn.
507
- */
508
- export function tryDrawCustomChar(
509
- ctx: CanvasRenderingContext2D,
510
- c: string,
511
- xOffset: number,
512
- yOffset: number,
513
- deviceCellWidth: number,
514
- deviceCellHeight: number,
515
- fontSize: number,
516
- devicePixelRatio: number
517
- ): boolean {
518
- const blockElementDefinition = blockElementDefinitions[c];
519
- if (blockElementDefinition) {
520
- drawBlockVectorChar(ctx, blockElementDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
521
- return true;
522
- }
523
-
524
- const symbolsForLegacyComputingDefinition = symbolsForLegacyComputingDefinitions[c];
525
- if (symbolsForLegacyComputingDefinition) {
526
- drawSextantChar(ctx, symbolsForLegacyComputingDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
527
- return true;
528
- }
529
-
530
- const patternDefinition = patternCharacterDefinitions[c];
531
- if (patternDefinition) {
532
- drawPatternChar(ctx, patternDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight);
533
- return true;
534
- }
535
-
536
- const boxDrawingDefinition = boxDrawingDefinitions[c];
537
- if (boxDrawingDefinition) {
538
- drawBoxDrawingChar(ctx, boxDrawingDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight, devicePixelRatio);
539
- return true;
540
- }
541
-
542
- const powerlineDefinition = powerlineDefinitions[c];
543
- if (powerlineDefinition) {
544
- drawPowerlineChar(ctx, powerlineDefinition, xOffset, yOffset, deviceCellWidth, deviceCellHeight, fontSize, devicePixelRatio);
545
- return true;
546
- }
547
-
548
- return false;
549
- }
550
-
551
- function drawBlockVectorChar(
552
- ctx: CanvasRenderingContext2D,
553
- charDefinition: IBlockVector[],
554
- xOffset: number,
555
- yOffset: number,
556
- deviceCellWidth: number,
557
- deviceCellHeight: number
558
- ): void {
559
- for (let i = 0; i < charDefinition.length; i++) {
560
- const box = charDefinition[i];
561
- const xEighth = deviceCellWidth / 8;
562
- const yEighth = deviceCellHeight / 8;
563
- ctx.fillRect(
564
- xOffset + box.x * xEighth,
565
- yOffset + box.y * yEighth,
566
- box.w * xEighth,
567
- box.h * yEighth
568
- );
569
- }
570
- }
571
-
572
- function drawSextantChar(
573
- ctx: CanvasRenderingContext2D,
574
- charDefinition: DrawFunctionDefinition,
575
- xOffset: number,
576
- yOffset: number,
577
- deviceCellWidth: number,
578
- deviceCellHeight: number
579
- ): void {
580
- const instructions = charDefinition(0, 0);
581
- ctx.beginPath();
582
- for (const instruction of instructions.split(' ')) {
583
- const type = instruction[0];
584
- const args: string[] = instruction.substring(1).split(',');
585
- if (!args[0] || !args[1]) {
586
- if (type === 'Z') {
587
- ctx.closePath();
588
- }
589
- continue;
590
- }
591
- const translatedArgs = args.map((e, i) => {
592
- const val = parseFloat(e);
593
- return i % 2 === 0
594
- ? xOffset + val * deviceCellWidth
595
- : yOffset + val * deviceCellHeight;
596
- });
597
- if (type === 'M') {
598
- ctx.moveTo(translatedArgs[0], translatedArgs[1]);
599
- } else if (type === 'L') {
600
- ctx.lineTo(translatedArgs[0], translatedArgs[1]);
601
- }
602
- }
603
- ctx.fill();
604
- }
605
-
606
- const cachedPatterns: Map<PatternDefinition, Map</* fillStyle */string, CanvasPattern>> = new Map();
607
-
608
- function drawPatternChar(
609
- ctx: CanvasRenderingContext2D,
610
- charDefinition: number[][],
611
- xOffset: number,
612
- yOffset: number,
613
- deviceCellWidth: number,
614
- deviceCellHeight: number
615
- ): void {
616
- let patternSet = cachedPatterns.get(charDefinition);
617
- if (!patternSet) {
618
- patternSet = new Map();
619
- cachedPatterns.set(charDefinition, patternSet);
620
- }
621
- const fillStyle = ctx.fillStyle;
622
- if (typeof fillStyle !== 'string') {
623
- throw new Error(`Unexpected fillStyle type "${fillStyle}"`);
624
- }
625
- let pattern = patternSet.get(fillStyle);
626
- if (!pattern) {
627
- const width = charDefinition[0].length;
628
- const height = charDefinition.length;
629
- const tmpCanvas = ctx.canvas.ownerDocument.createElement('canvas');
630
- tmpCanvas.width = width;
631
- tmpCanvas.height = height;
632
- const tmpCtx = throwIfFalsy(tmpCanvas.getContext('2d'));
633
- const imageData = new ImageData(width, height);
634
-
635
- // Extract rgba from fillStyle
636
- let r: number;
637
- let g: number;
638
- let b: number;
639
- let a: number;
640
- if (fillStyle.startsWith('#')) {
641
- r = parseInt(fillStyle.slice(1, 3), 16);
642
- g = parseInt(fillStyle.slice(3, 5), 16);
643
- b = parseInt(fillStyle.slice(5, 7), 16);
644
- a = fillStyle.length > 7 && parseInt(fillStyle.slice(7, 9), 16) || 1;
645
- } else if (fillStyle.startsWith('rgba')) {
646
- ([r, g, b, a] = fillStyle.substring(5, fillStyle.length - 1).split(',').map(e => parseFloat(e)));
647
- } else {
648
- throw new Error(`Unexpected fillStyle color format "${fillStyle}" when drawing pattern glyph`);
649
- }
650
-
651
- for (let y = 0; y < height; y++) {
652
- for (let x = 0; x < width; x++) {
653
- imageData.data[(y * width + x) * 4 ] = r;
654
- imageData.data[(y * width + x) * 4 + 1] = g;
655
- imageData.data[(y * width + x) * 4 + 2] = b;
656
- imageData.data[(y * width + x) * 4 + 3] = charDefinition[y][x] * (a * 255);
657
- }
658
- }
659
- tmpCtx.putImageData(imageData, 0, 0);
660
- pattern = throwIfFalsy(ctx.createPattern(tmpCanvas, null));
661
- patternSet.set(fillStyle, pattern);
662
- }
663
- ctx.fillStyle = pattern;
664
- ctx.fillRect(xOffset, yOffset, deviceCellWidth, deviceCellHeight);
665
- }
666
-
667
- /**
668
- * Draws the following box drawing characters by mapping a subset of SVG d attribute instructions to
669
- * canvas draw calls.
670
- *
671
- * Box styles: ┎┰┒┍┯┑╓╥╖╒╤╕ ┏┳┓┌┲┓┌┬┐┏┱┐
672
- * ┌─┬─┐ ┏━┳━┓ ╔═╦═╗ ┠╂┨┝┿┥╟╫╢╞╪╡ ┡╇┩├╊┫┢╈┪┣╉┤
673
- * │ │ │ ┃ ┃ ┃ ║ ║ ║ ┖┸┚┕┷┙╙╨╜╘╧╛ └┴┘└┺┛┗┻┛┗┹┘
674
- * ├─┼─┤ ┣━╋━┫ ╠═╬═╣ ┏┱┐┌┲┓┌┬┐┌┬┐ ┏┳┓┌┮┓┌┬┐┏┭┐
675
- * │ │ │ ┃ ┃ ┃ ║ ║ ║ ┡╃┤├╄┩├╆┪┢╅┤ ┞╀┦├┾┫┟╁┧┣┽┤
676
- * └─┴─┘ ┗━┻━┛ ╚═╩═╝ └┴┘└┴┘└┺┛┗┹┘ └┴┘└┶┛┗┻┛┗┵┘
677
- *
678
- * Other:
679
- * ╭─╮ ╲ ╱ ╷╻╎╏┆┇┊┋ ╺╾╴ ╌╌╌ ┄┄┄ ┈┈┈
680
- * │ │ ╳ ╽╿╎╏┆┇┊┋ ╶╼╸ ╍╍╍ ┅┅┅ ┉┉┉
681
- * ╰─╯ ╱ ╲ ╹╵╎╏┆┇┊┋
682
- *
683
- * All box drawing characters:
684
- * ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏
685
- * ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟
686
- * ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯
687
- * ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿
688
- * ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏
689
- * ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟
690
- * ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯
691
- * ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿
692
- *
693
- * ---
694
- *
695
- * Box drawing alignment tests: █
696
- * ▉
697
- * ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳
698
- * ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳
699
- * ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳
700
- * ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳
701
- * ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎
702
- * ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏
703
- * ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█
704
- *
705
- * Source: https://www.w3.org/2001/06/utf-8-test/UTF-8-demo.html
706
- */
707
- function drawBoxDrawingChar(
708
- ctx: CanvasRenderingContext2D,
709
- charDefinition: { [fontWeight: number]: string | ((xp: number, yp: number) => string) },
710
- xOffset: number,
711
- yOffset: number,
712
- deviceCellWidth: number,
713
- deviceCellHeight: number,
714
- devicePixelRatio: number
715
- ): void {
716
- ctx.strokeStyle = ctx.fillStyle;
717
- for (const [fontWeight, instructions] of Object.entries(charDefinition)) {
718
- ctx.beginPath();
719
- ctx.lineWidth = devicePixelRatio * Number.parseInt(fontWeight);
720
- let actualInstructions: string;
721
- if (typeof instructions === 'function') {
722
- const xp = .15;
723
- const yp = .15 / deviceCellHeight * deviceCellWidth;
724
- actualInstructions = instructions(xp, yp);
725
- } else {
726
- actualInstructions = instructions;
727
- }
728
- for (const instruction of actualInstructions.split(' ')) {
729
- const type = instruction[0];
730
- const f = svgToCanvasInstructionMap[type];
731
- if (!f) {
732
- console.error(`Could not find drawing instructions for "${type}"`);
733
- continue;
734
- }
735
- const args: string[] = instruction.substring(1).split(',');
736
- if (!args[0] || !args[1]) {
737
- continue;
738
- }
739
- f(ctx, translateArgs(args, deviceCellWidth, deviceCellHeight, xOffset, yOffset, true, devicePixelRatio));
740
- }
741
- ctx.stroke();
742
- ctx.closePath();
743
- }
744
- }
745
-
746
- function drawPowerlineChar(
747
- ctx: CanvasRenderingContext2D,
748
- charDefinition: IVectorShape,
749
- xOffset: number,
750
- yOffset: number,
751
- deviceCellWidth: number,
752
- deviceCellHeight: number,
753
- fontSize: number,
754
- devicePixelRatio: number
755
- ): void {
756
- // Clip the cell to make sure drawing doesn't occur beyond bounds
757
- const clipRegion = new Path2D();
758
- clipRegion.rect(xOffset, yOffset, deviceCellWidth, deviceCellHeight);
759
- ctx.clip(clipRegion);
760
-
761
- ctx.beginPath();
762
- // Scale the stroke with DPR and font size
763
- const cssLineWidth = fontSize / 12;
764
- ctx.lineWidth = devicePixelRatio * cssLineWidth;
765
- for (const instruction of charDefinition.d.split(' ')) {
766
- const type = instruction[0];
767
- const f = svgToCanvasInstructionMap[type];
768
- if (!f) {
769
- console.error(`Could not find drawing instructions for "${type}"`);
770
- continue;
771
- }
772
- const args: string[] = instruction.substring(1).split(',');
773
- if (!args[0] || !args[1]) {
774
- continue;
775
- }
776
- f(ctx, translateArgs(
777
- args,
778
- deviceCellWidth,
779
- deviceCellHeight,
780
- xOffset,
781
- yOffset,
782
- false,
783
- devicePixelRatio,
784
- (charDefinition.leftPadding ?? 0) * (cssLineWidth / 2),
785
- (charDefinition.rightPadding ?? 0) * (cssLineWidth / 2)
786
- ));
787
- }
788
- if (charDefinition.type === VectorType.STROKE) {
789
- ctx.strokeStyle = ctx.fillStyle;
790
- ctx.stroke();
791
- } else {
792
- ctx.fill();
793
- }
794
- ctx.closePath();
795
- }
796
-
797
- function clamp(value: number, max: number, min: number = 0): number {
798
- return Math.max(Math.min(value, max), min);
799
- }
800
-
801
- const svgToCanvasInstructionMap: { [index: string]: any } = {
802
- 'C': (ctx: CanvasRenderingContext2D, args: number[]) => ctx.bezierCurveTo(args[0], args[1], args[2], args[3], args[4], args[5]),
803
- 'L': (ctx: CanvasRenderingContext2D, args: number[]) => ctx.lineTo(args[0], args[1]),
804
- 'M': (ctx: CanvasRenderingContext2D, args: number[]) => ctx.moveTo(args[0], args[1])
805
- };
806
-
807
- function translateArgs(args: string[], cellWidth: number, cellHeight: number, xOffset: number, yOffset: number, doClamp: boolean, devicePixelRatio: number, leftPadding: number = 0, rightPadding: number = 0): number[] {
808
- const result = args.map(e => parseFloat(e) || parseInt(e));
809
-
810
- if (result.length < 2) {
811
- throw new Error('Too few arguments for instruction');
812
- }
813
-
814
- for (let x = 0; x < result.length; x += 2) {
815
- // Translate from 0-1 to 0-cellWidth
816
- result[x] *= cellWidth - (leftPadding * devicePixelRatio) - (rightPadding * devicePixelRatio);
817
- // Ensure coordinate doesn't escape cell bounds and round to the nearest 0.5 to ensure a crisp
818
- // line at 100% devicePixelRatio
819
- if (doClamp && result[x] !== 0) {
820
- result[x] = clamp(Math.round(result[x] + 0.5) - 0.5, cellWidth, 0);
821
- }
822
- // Apply the cell's offset (ie. x*cellWidth)
823
- result[x] += xOffset + (leftPadding * devicePixelRatio);
824
- }
825
-
826
- for (let y = 1; y < result.length; y += 2) {
827
- // Translate from 0-1 to 0-cellHeight
828
- result[y] *= cellHeight;
829
- // Ensure coordinate doesn't escape cell bounds and round to the nearest 0.5 to ensure a crisp
830
- // line at 100% devicePixelRatio
831
- if (doClamp && result[y] !== 0) {
832
- result[y] = clamp(Math.round(result[y] + 0.5) - 0.5, cellHeight, 0);
833
- }
834
- // Apply the cell's offset (ie. x*cellHeight)
835
- result[y] += yOffset;
836
- }
837
-
838
- return result;
839
- }