can now use named colors

This commit is contained in:
kepler155c@gmail.com
2020-04-21 22:32:12 -06:00
parent e703c7f7b6
commit 5933f8c40f
42 changed files with 308 additions and 400 deletions

View File

@@ -1,16 +1,91 @@
local class = require('opus.class')
local colors = _G.colors
local _rep = string.rep
local _sub = string.sub
local Blit = class()
local Blit = { }
function Blit:init(t, cs)
if type(t) == 'string' then
t = Blit.toblit(t, cs or { })
end
self.text = t.text
self.bg = t.bg
self.fg = t.fg
Blit.colorPalette = { }
Blit.grayscalePalette = { }
for n = 1, 16 do
Blit.colorPalette[2 ^ (n - 1)] = _sub("0123456789abcdef", n, n)
Blit.grayscalePalette[2 ^ (n - 1)] = _sub("088888878877787f", n, n)
end
-- default palette
Blit.palette = Blit.colorPalette
function Blit:init(t, args)
if args then
for k,v in pairs(args) do
self[k] = v
end
end
if type(t) == 'string' then
-- create a blit from a string
self.text, self.bg, self.fg = Blit.toblit(t, args or { })
elseif type(t) == 'number' then
-- create a fixed width blit
self.width = t
self.text = _rep(' ', self.width)
self.bg = _rep(self.palette[args.bg], self.width)
self.fg = _rep(self.palette[args.fg], self.width)
else
self.text = t.text
self.bg = t.bg
self.fg = t.fg
end
end
function Blit:write(x, text, bg, fg)
self:insert(x, text,
bg and _rep(self.palette[bg], #text),
fg and _rep(self.palette[fg], #text))
end
function Blit:insert(x, text, bg, fg)
if x <= self.width then
local width = #text
local tx, tex
if x < 1 then
tx = 2 - x
width = width + x - 1
x = 1
end
if x + width - 1 > self.width then
tex = self.width - x + (tx or 1)
width = tex - (tx or 1) + 1
end
if width > 0 then
local function replace(sstr, rstr)
if tx or tex then
rstr = _sub(rstr, tx or 1, tex)
end
if x == 1 and width == self.width then
return rstr
elseif x == 1 then
return rstr .. _sub(sstr, x + width)
elseif x + width > self.width then
return _sub(sstr, 1, x - 1) .. rstr
end
return _sub(sstr, 1, x - 1) .. rstr .. _sub(sstr, x + width)
end
self.text = replace(self.text, text)
if fg then
self.fg = replace(self.fg, fg)
end
if bg then
self.bg = replace(self.bg, bg)
end
end
end
end
function Blit:sub(s, e)
@@ -22,7 +97,6 @@ function Blit:sub(s, e)
end
function Blit:wrap(max)
local index = 1
local lines = { }
local data = self
@@ -31,7 +105,7 @@ function Blit:wrap(max)
table.insert(lines, data)
break
elseif data.text:sub(max+1, max+1) == ' ' then
table.insert(lines, data:sub(index, max))
table.insert(lines, data:sub(1, max))
data = data:sub(max + 2)
else
local x = data.text:sub(1, max)
@@ -56,18 +130,20 @@ function Blit.toblit(str, cs)
if not cs.cbg then
-- reset colors
cs.rbg = cs.palette[cs.bg or colors.black]
cs.rfg = cs.palette[cs.fg or colors.white]
cs.rbg = cs.bg or colors.black
cs.rfg = cs.fg or colors.white
-- current colors
cs.cbg = cs.rbg
cs.cfg = cs.rfg
cs.palette = cs.palette or Blit.palette
end
str = str:gsub('(.-)\027%[([%d;]+)m',
function(k, seq)
text = text .. k
bg = bg .. string.rep(cs.cbg, #k)
fg = fg .. string.rep(cs.cfg, #k)
bg = bg .. string.rep(cs.palette[cs.cbg], #k)
fg = fg .. string.rep(cs.palette[cs.cfg], #k)
for color in string.gmatch(seq, "%d+") do
color = tonumber(color)
if color == 0 then
@@ -75,20 +151,24 @@ function Blit.toblit(str, cs)
cs.cfg = cs.rfg
cs.cbg = cs.rbg
elseif color > 20 then
cs.cbg = string.sub("0123456789abcdef", color - 21, color - 21)
cs.cbg = 2 ^ (color - 21)
else
cs.cfg = string.sub("0123456789abcdef", color, color)
cs.cfg = 2 ^ (color - 1)
end
end
return k
end)
local k = str:sub(#text + 1)
return {
text = text .. k,
bg = bg .. string.rep(cs.cbg, #k),
fg = fg .. string.rep(cs.cfg, #k),
}
return text .. k,
bg .. string.rep(cs.palette[cs.cbg], #k),
fg .. string.rep(cs.palette[cs.cfg], #k)
end
return Blit
return setmetatable(Blit, {
__call = function(_, ...)
local obj = setmetatable({ }, { __index = Blit })
obj:init(...)
return obj
end
})