UNPKG

@thi.ng/text-canvas

Version:

Text based canvas, drawing, plotting, tables with arbitrary formatting (incl. ANSI/HTML)

88 lines (87 loc) 2.18 kB
import { peek } from "@thi.ng/arrays/peek"; import { clamp0 } from "@thi.ng/math/interval"; import { wordWrapLines } from "@thi.ng/strings/word-wrap"; import { beginClip, beginStyle, endClip, endStyle } from "./canvas.js"; import { fillRect, strokeRect } from "./rect.js"; const textLine = (canvas, x, y, line, format = canvas.format) => { x |= 0; y |= 0; const { x1, y1, x2, y2 } = peek(canvas.clipRects); if (y < y1 || y >= y2 || x >= x2) return; let i = 0; if (x < x1) { i = x1 - x; x = x1; } const { data, width } = canvas; const n = line.length; format <<= 16; for (let idx = x + y * width; i < n && x < x2; i++, x++, idx++) { data[idx] = line.charCodeAt(i) | format; } }; const textLines = (canvas, x, y, lines, format = canvas.format) => { for (let line of lines) { textLine(canvas, x, y, line, format); y++; } return y; }; const textColumn = (canvas, x, y, width, txt, format = canvas.format, hard = false) => { x |= 0; y |= 0; width |= 0; const height = canvas.height; for (let line of wordWrapLines(txt, { width, hard })) { textLine(canvas, x, y, line.toString(), format); y++; if (y >= height) break; } return y; }; const textBox = (canvas, x, y, width, height, txt, opts = {}) => { const { format = canvas.format, hard = false, padding: [padX, padY] = [0, 0], style } = opts; const currFmt = canvas.format; canvas.format = format; style && beginStyle(canvas, style); x |= 0; y |= 0; width |= 0; let innerW = width - 2 - 2 * padX; let innerH = 0; const lines = wordWrapLines(txt, { width: innerW, hard }).map( (l) => l.toString() ); if (height < 0) { innerH = lines.length + 2; height = innerH + 2 * padY; } else { innerH = clamp0(height - 2); } strokeRect(canvas, x, y, width, height); fillRect(canvas, x + 1, y + 1, width - 2, height - 2, " "); x += 1 + padX; y += 1 + padY; beginClip(canvas, x, y, innerW, innerH); y = textLines(canvas, x, y, lines); endClip(canvas); style && endStyle(canvas); canvas.format = currFmt; return y + height; }; export { textBox, textColumn, textLine, textLines };