From f4efc4d6db43b6742a199b48c2ac26ead3198086 Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 21 Jul 2025 23:11:10 +0200 Subject: [PATCH] Mon 21 Jul 22:43:21 CEST 2025 --- js/term/widgets/bigtext.js | 185 +++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 js/term/widgets/bigtext.js diff --git a/js/term/widgets/bigtext.js b/js/term/widgets/bigtext.js new file mode 100644 index 0000000..ff5f62f --- /dev/null +++ b/js/term/widgets/bigtext.js @@ -0,0 +1,185 @@ +/** + ** ============================== + ** O O O OOOO + ** O O O O O O + ** O O O O O O + ** OOOO OOOO O OOO OOOO + ** O O O O O O O + ** O O O O O O O + ** OOOO OOOO O O OOOO + ** ============================== + ** Dr. Stefan Bosse http://www.bsslab.de + ** + ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED + ** BY THE AUTHOR(S). + ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, + ** MODIFIED, OR OTHERWISE USED IN A CONTEXT + ** OUTSIDE OF THE SOFTWARE SYSTEM. + ** + ** $AUTHORS: Christopher Jeffrey, Stefan Bosse + ** $INITIAL: (C) 2013-2015, Christopher Jeffrey and contributors + ** $MODIFIED: by sbosse + ** $REVESIO: 1.2.1 + ** + ** $INFO: + ** + ** bigtext.js - bigtext element for blessed + ** + ** $ENDOFINFO + */ + +/** + * Modules + */ +var Comp = Require('com/compat'); + +var fs = require('fs'); + +var Node = Require('term/widgets/node'); +var Box = Require('term/widgets/box'); + +/** + * BigText + */ + +function BigText(options) { + if (!instanceOf(this instanceof Node)) { + return new BigText(options); + } + options = options || {}; + options.font = options.font + || __dirname + '/../../usr/fonts/ter-u14n.json'; + options.fontBold = options.font + || __dirname + '/../../usr/fonts/ter-u14b.json'; + this.fch = options.fch; + this.ratio = {}; + this.font = this.loadFont(options.font); + this.fontBold = this.loadFont(options.font); + Box.call(this, options); + if (this.style.bold) { + this.font = this.fontBold; + } +} + +//BigText.prototype.__proto__ = Box.prototype; +inheritPrototype(BigText,Box); + +BigText.prototype.type = 'bigtext'; + +BigText.prototype.loadFont = function(filename) { + var self = this + , data + , font; + + data = JSON.parse(fs.readFileSync(filename, 'utf8')); + + this.ratio.width = data.width; + this.ratio.height = data.height; + + function convertLetter(ch, lines) { + var line, i; + + while (lines.length > self.ratio.height) { + lines.shift(); + lines.pop(); + } + + lines = lines.map(function(line) { + var chs = line.split(''); + chs = chs.map(function(ch) { + return ch === ' ' ? 0 : 1; + }); + while (chs.length < self.ratio.width) { + chs.push(0); + } + return chs; + }); + + while (lines.length < self.ratio.height) { + line = []; + for (i = 0; i < self.ratio.width; i++) { + line.push(0); + } + lines.push(line); + } + + return lines; + } + + font = Object.keys(data.glyphs).reduce(function(out, ch) { + var lines = data.glyphs[ch].map; + out[ch] = convertLetter(ch, lines); + return out; + }, {}); + + delete font[' ']; + + return font; +}; + +BigText.prototype.setContent = function(content) { + this.content = ''; + this.text = content || ''; +}; + +BigText.prototype.render = function() { + if (this.position.width == null || this._shrinkWidth) { + // if (this.width - this.iwidth < this.ratio.width * this.text.length + 1) { + this.position.width = this.ratio.width * this.text.length + 1; + this._shrinkWidth = true; + // } + } + if (this.position.height == null || this._shrinkHeight) { + // if (this.height - this.iheight < this.ratio.height + 0) { + this.position.height = this.ratio.height + 0; + this._shrinkHeight = true; + // } + } + + var coords = this._render(); + if (!coords) return; + + var lines = this.screen.lines + , left = coords.xi + this.ileft + , top = coords.yi + this.itop + , right = coords.xl - this.iright + , bottom = coords.yl - this.ibottom; + + var dattr = this.sattr(this.style) + , bg = dattr & 0x1ff + , fg = (dattr >> 9) & 0x1ff + , flags = (dattr >> 18) & 0x1ff + , attr = (flags << 18) | (bg << 9) | fg; + + for (var x = left, i = 0; x < right; x += this.ratio.width, i++) { + var ch = this.text[i]; + if (!ch) break; + var map = this.font[ch]; + if (!map) continue; + for (var y = top; y < Math.min(bottom, top + this.ratio.height); y++) { + if (!lines[y]) continue; + var mline = map[y - top]; + if (!mline) continue; + for (var mx = 0; mx < this.ratio.width; mx++) { + var mcell = mline[mx]; + if (mcell == null) break; + if (this.fch && this.fch !== ' ') { + lines[y][x + mx][0] = dattr; + lines[y][x + mx][1] = mcell === 1 ? this.fch : this.ch; + } else { + lines[y][x + mx][0] = mcell === 1 ? attr : dattr; + lines[y][x + mx][1] = mcell === 1 ? ' ' : this.ch; + } + } + lines[y].dirty = true; + } + } + + return coords; +}; + +/** + * Expose + */ + +module.exports = BigText;