@thi.ng/text-canvas 2.6.22 → 2.6.23
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.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api.js +95 -79
- package/bars.js +37 -31
- package/canvas.js +164 -135
- package/circle.js +55 -66
- package/format.js +14 -20
- package/hvline.js +64 -61
- package/image.js +231 -310
- package/line.js +66 -73
- package/package.json +15 -12
- package/rect.js +66 -88
- package/style.js +30 -26
- package/table.js +133 -118
- package/text.js +86 -108
- package/utils.js +13 -8
package/line.js
CHANGED
|
@@ -8,81 +8,74 @@ import { min as $min } from "@thi.ng/transducers/min";
|
|
|
8
8
|
import { Canvas } from "./canvas.js";
|
|
9
9
|
import { formatCanvas } from "./format.js";
|
|
10
10
|
import { charCode } from "./utils.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
char = charCode(char !== undefined ? char : peek(canvas.styles).dot, format);
|
|
39
|
-
while (true) {
|
|
40
|
-
canvas.data[ax + ay * w] = char;
|
|
41
|
-
if (ax === bx && ay === by)
|
|
42
|
-
return;
|
|
43
|
-
let t = err << 1;
|
|
44
|
-
if (t < dx) {
|
|
45
|
-
err += dx;
|
|
46
|
-
ay += sy;
|
|
47
|
-
}
|
|
48
|
-
if (t > dy) {
|
|
49
|
-
err += dy;
|
|
50
|
-
ax += sx;
|
|
51
|
-
}
|
|
11
|
+
const line = (canvas, ax, ay, bx, by, char, format = canvas.format) => {
|
|
12
|
+
const { x1, y1, x2, y2 } = peek(canvas.clipRects);
|
|
13
|
+
const clipped = liangBarsky2Raw(ax, ay, bx, by, x1, y1, x2, y2);
|
|
14
|
+
if (!clipped)
|
|
15
|
+
return;
|
|
16
|
+
ax = clipped[0] | 0;
|
|
17
|
+
ay = clipped[1] | 0;
|
|
18
|
+
bx = clipped[2] | 0;
|
|
19
|
+
by = clipped[3] | 0;
|
|
20
|
+
const dx = Math.abs(bx - ax);
|
|
21
|
+
const dy = -Math.abs(by - ay);
|
|
22
|
+
const w = canvas.width;
|
|
23
|
+
let sx = ax < bx ? 1 : -1;
|
|
24
|
+
let sy = ay < by ? 1 : -1;
|
|
25
|
+
let err = dx + dy;
|
|
26
|
+
char = charCode(
|
|
27
|
+
char !== void 0 ? char : peek(canvas.styles).dot,
|
|
28
|
+
format
|
|
29
|
+
);
|
|
30
|
+
while (true) {
|
|
31
|
+
canvas.data[ax + ay * w] = char;
|
|
32
|
+
if (ax === bx && ay === by)
|
|
33
|
+
return;
|
|
34
|
+
let t = err << 1;
|
|
35
|
+
if (t < dx) {
|
|
36
|
+
err += dx;
|
|
37
|
+
ay += sy;
|
|
52
38
|
}
|
|
39
|
+
if (t > dy) {
|
|
40
|
+
err += dy;
|
|
41
|
+
ax += sx;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
53
44
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// end points
|
|
78
|
-
canvas.setAt(xx, ya, (ya < yb ? 0x256e : 0x256f) | format); // ╮ ╯
|
|
79
|
-
canvas.setAt(xx, yb, (ya < yb ? 0x2570 : 0x256d) | format); // ╰ ╭
|
|
80
|
-
}
|
|
45
|
+
const lineChart = (canvas, x, y, height, vals, min, max, format = canvas.format) => {
|
|
46
|
+
const $vals = ensureArray(vals);
|
|
47
|
+
min = min !== void 0 ? min : $min($vals);
|
|
48
|
+
max = max !== void 0 ? max : $max($vals);
|
|
49
|
+
height--;
|
|
50
|
+
format <<= 16;
|
|
51
|
+
const { x1, x2 } = peek(canvas.clipRects);
|
|
52
|
+
for (let i = 0, n = $vals.length - 1; i < n; i++) {
|
|
53
|
+
const xx = x + i;
|
|
54
|
+
if (xx < x1)
|
|
55
|
+
continue;
|
|
56
|
+
if (xx > x2)
|
|
57
|
+
break;
|
|
58
|
+
const ya = Math.round(fitClamped($vals[i], min, max, height, 0)) + y;
|
|
59
|
+
const yb = Math.round(fitClamped($vals[i + 1], min, max, height, 0)) + y;
|
|
60
|
+
if (ya === yb) {
|
|
61
|
+
canvas.setAt(xx, ya, 9472 | format);
|
|
62
|
+
} else {
|
|
63
|
+
let [y1, y2] = minMax(ya, yb);
|
|
64
|
+
while (++y1 < y2)
|
|
65
|
+
canvas.setAt(xx, y1, 9474 | format);
|
|
66
|
+
canvas.setAt(xx, ya, (ya < yb ? 9582 : 9583) | format);
|
|
67
|
+
canvas.setAt(xx, yb, (ya < yb ? 9584 : 9581) | format);
|
|
81
68
|
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const lineChartStr = (height, vals, min, max) => {
|
|
72
|
+
const $vals = ensureArray(vals);
|
|
73
|
+
const surf = new Canvas($vals.length, height);
|
|
74
|
+
lineChart(surf, 0, 0, height, $vals, min, max);
|
|
75
|
+
return formatCanvas(surf);
|
|
82
76
|
};
|
|
83
|
-
export
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return formatCanvas(surf);
|
|
77
|
+
export {
|
|
78
|
+
line,
|
|
79
|
+
lineChart,
|
|
80
|
+
lineChartStr
|
|
88
81
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/text-canvas",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.23",
|
|
4
4
|
"description": "Text based canvas, drawing, tables with arbitrary formatting (incl. ANSI/HTML)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,18 +35,19 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/api": "^8.9.
|
|
37
|
-
"@thi.ng/arrays": "^2.7.
|
|
38
|
-
"@thi.ng/checks": "^3.4.
|
|
39
|
-
"@thi.ng/errors": "^2.4.
|
|
40
|
-
"@thi.ng/geom-clip-line": "^2.3.
|
|
41
|
-
"@thi.ng/math": "^5.7.
|
|
42
|
-
"@thi.ng/strings": "^3.7.
|
|
43
|
-
"@thi.ng/text-format": "^1.4.
|
|
44
|
-
"@thi.ng/transducers": "^8.8.
|
|
38
|
+
"@thi.ng/api": "^8.9.12",
|
|
39
|
+
"@thi.ng/arrays": "^2.7.8",
|
|
40
|
+
"@thi.ng/checks": "^3.4.12",
|
|
41
|
+
"@thi.ng/errors": "^2.4.6",
|
|
42
|
+
"@thi.ng/geom-clip-line": "^2.3.50",
|
|
43
|
+
"@thi.ng/math": "^5.7.7",
|
|
44
|
+
"@thi.ng/strings": "^3.7.3",
|
|
45
|
+
"@thi.ng/text-format": "^1.4.21",
|
|
46
|
+
"@thi.ng/transducers": "^8.8.15"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
49
|
"@microsoft/api-extractor": "^7.38.3",
|
|
50
|
+
"esbuild": "^0.19.8",
|
|
48
51
|
"rimraf": "^5.0.5",
|
|
49
52
|
"tools": "^0.0.1",
|
|
50
53
|
"tslib": "^2.6.2",
|
|
@@ -137,5 +140,5 @@
|
|
|
137
140
|
],
|
|
138
141
|
"year": 2020
|
|
139
142
|
},
|
|
140
|
-
"gitHead": "
|
|
143
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
141
144
|
}
|
package/rect.js
CHANGED
|
@@ -2,95 +2,73 @@ import { peek } from "@thi.ng/arrays/peek";
|
|
|
2
2
|
import { NONE } from "@thi.ng/text-format/api";
|
|
3
3
|
import { hline, vline } from "./hvline.js";
|
|
4
4
|
import { charCode } from "./utils.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
canvas.format = canvas.defaultFormat;
|
|
19
|
-
}
|
|
20
|
-
code = charCode(code, canvas.format);
|
|
21
|
-
if (rects.length > 1) {
|
|
22
|
-
const { x1, y1, w, h } = peek(rects);
|
|
23
|
-
fillRect(canvas, x1, y1, w, h, code);
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
canvas.data.fill(code);
|
|
27
|
-
}
|
|
5
|
+
const clear = (canvas, reset = false, code = 32) => {
|
|
6
|
+
const rects = canvas.clipRects;
|
|
7
|
+
if (reset) {
|
|
8
|
+
rects.length = canvas.styles.length = 1;
|
|
9
|
+
canvas.format = canvas.defaultFormat;
|
|
10
|
+
}
|
|
11
|
+
code = charCode(code, canvas.format);
|
|
12
|
+
if (rects.length > 1) {
|
|
13
|
+
const { x1, y1, w, h } = peek(rects);
|
|
14
|
+
fillRect(canvas, x1, y1, w, h, code);
|
|
15
|
+
} else {
|
|
16
|
+
canvas.data.fill(code);
|
|
17
|
+
}
|
|
28
18
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* @param format -
|
|
34
|
-
*/
|
|
35
|
-
export const clearFormat = ({ data }, format = NONE) => {
|
|
36
|
-
format <<= 16;
|
|
37
|
-
for (let i = data.length; i-- > 0;)
|
|
38
|
-
data[i] = (data[i] & 0xffff) | format;
|
|
19
|
+
const clearFormat = ({ data }, format = NONE) => {
|
|
20
|
+
format <<= 16;
|
|
21
|
+
for (let i = data.length; i-- > 0; )
|
|
22
|
+
data[i] = data[i] & 65535 | format;
|
|
39
23
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
const { data, width } = canvas;
|
|
66
|
-
if (w < 1 || h < 1 || x >= x2 || y >= y2)
|
|
67
|
-
return;
|
|
68
|
-
w = Math.min(w, x2 - x);
|
|
69
|
-
h = Math.min(h, y2 - y);
|
|
70
|
-
char = charCode(char, format);
|
|
71
|
-
for (; h-- > 0; y++) {
|
|
72
|
-
const idx = x + y * width;
|
|
73
|
-
data.fill(char, idx, idx + w);
|
|
74
|
-
}
|
|
24
|
+
const fillRect = (canvas, x, y, w, h, char, format = canvas.format) => {
|
|
25
|
+
x |= 0;
|
|
26
|
+
y |= 0;
|
|
27
|
+
w |= 0;
|
|
28
|
+
h |= 0;
|
|
29
|
+
const { x1, y1, x2, y2 } = peek(canvas.clipRects);
|
|
30
|
+
if (x < x1) {
|
|
31
|
+
w += x - x1;
|
|
32
|
+
x = x1;
|
|
33
|
+
}
|
|
34
|
+
if (y < y1) {
|
|
35
|
+
h += y - y1;
|
|
36
|
+
y = y1;
|
|
37
|
+
}
|
|
38
|
+
const { data, width } = canvas;
|
|
39
|
+
if (w < 1 || h < 1 || x >= x2 || y >= y2)
|
|
40
|
+
return;
|
|
41
|
+
w = Math.min(w, x2 - x);
|
|
42
|
+
h = Math.min(h, y2 - y);
|
|
43
|
+
char = charCode(char, format);
|
|
44
|
+
for (; h-- > 0; y++) {
|
|
45
|
+
const idx = x + y * width;
|
|
46
|
+
data.fill(char, idx, idx + w);
|
|
47
|
+
}
|
|
75
48
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
w
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
49
|
+
const strokeRect = (canvas, x, y, w, h, format = canvas.format) => {
|
|
50
|
+
w |= 0;
|
|
51
|
+
h |= 0;
|
|
52
|
+
if (w < 2 || h < 2)
|
|
53
|
+
return;
|
|
54
|
+
const style = peek(canvas.styles);
|
|
55
|
+
hline(canvas, x, y, w, style.tl, style.tr, style.hl, format);
|
|
56
|
+
hline(canvas, x, y + h - 1, w, style.bl, style.br, style.hl, format);
|
|
57
|
+
vline(canvas, x, y + 1, h - 2, void 0, void 0, void 0, format);
|
|
58
|
+
vline(
|
|
59
|
+
canvas,
|
|
60
|
+
x + w - 1,
|
|
61
|
+
y + 1,
|
|
62
|
+
h - 2,
|
|
63
|
+
void 0,
|
|
64
|
+
void 0,
|
|
65
|
+
void 0,
|
|
66
|
+
format
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
export {
|
|
70
|
+
clear,
|
|
71
|
+
clearFormat,
|
|
72
|
+
fillRect,
|
|
73
|
+
strokeRect
|
|
96
74
|
};
|
package/style.js
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
const horizontalOnly = ({ hl, dot }) => ({
|
|
2
|
+
hl,
|
|
3
|
+
vl: " ",
|
|
4
|
+
tl: hl,
|
|
5
|
+
tr: hl,
|
|
6
|
+
bl: hl,
|
|
7
|
+
br: hl,
|
|
8
|
+
tjl: hl,
|
|
9
|
+
tjr: hl,
|
|
10
|
+
tjt: hl,
|
|
11
|
+
tjb: hl,
|
|
12
|
+
jct: hl,
|
|
13
|
+
dot
|
|
14
14
|
});
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
const verticalOnly = ({ vl, dot }) => ({
|
|
16
|
+
hl: " ",
|
|
17
|
+
vl,
|
|
18
|
+
tl: vl,
|
|
19
|
+
tr: vl,
|
|
20
|
+
bl: vl,
|
|
21
|
+
br: vl,
|
|
22
|
+
tjl: vl,
|
|
23
|
+
tjr: vl,
|
|
24
|
+
tjt: vl,
|
|
25
|
+
tjb: vl,
|
|
26
|
+
jct: vl,
|
|
27
|
+
dot
|
|
28
28
|
});
|
|
29
|
+
export {
|
|
30
|
+
horizontalOnly,
|
|
31
|
+
verticalOnly
|
|
32
|
+
};
|