censored/fonts.lua
Alexander Yakovlev 888c54f43b Модуль fonts
Поддержка цветного текста
2015-08-19 20:44:59 +07:00

133 lines
3 KiB
Lua

-- example module
require "sprites"
require "theme"
function font(name, size, scale)
if scale == nil then
scale = true
end
local v = obj {
nam = 'styler';
fname = name;
size = size;
cache = { };
list = { };
scaled = scale;
cache_get = function(s, w, color, t)
local k = w..color..tostring(t)
if s.cache[k].time ~= -1 then
s.cache[k].time = stead.time()
end
return s.cache[k]
end;
cache_clear = function(self, age)
local k, v
local new_list = {}
if not age then
age = 0
end
for k,v in ipairs(self.list) do
local key = v.word..v.color..tostring(v.t)
if v.time ~= -1 and stead.time() - v.time >= age then
sprite.free(v.img);
self.cache[key] = nil
else
stead.table.insert(new_list, v)
if v.time ~= -1 then
self:cache_add(v.word, v.color, v.t, v.img, nil) -- renew time
else
self:cache_add(v.word, v.color, v.t, v.img, -1)
end
end
end
self.list = new_list
end;
life = function(s)
if player_moved() then
s:cache_clear(2)
end
end;
txt = function(st, txt, color, t)
local s, e;
local ss = 1
local res = ''
if not color then
color = theme.get 'win.col.fg'
end
if not t then
t = 0
end
while true do
local start = ss
while true do
s, e = txt:find("[ \\\t\n^]+", ss);
if s and txt:sub(s, s) == '\\' then
ss = s + 2
else
break
end
end
ss = start
local w
if s then s = s - 1 end
w = txt:sub(ss, s);
local c
if w then
if s then
c = txt:sub(s + 1, e)
end
w = w:gsub("\\([^\\])", "%1")
w = w:gsub("[ \t\n]+$", "");
end
if w and w ~= '' and w ~= '\n' then
st:cache_add(w, color, t)
res = res .. img(st:cache_get(w, color, t).img);
end
if not e then break end
ss = e + 1
if not c then c = '' end
res = res .. c;
end
return res;
end;
cache_add = function(s, w, color, t, key, time)
local k = w..color..tostring(t)
if not s.cache[k] then
s.cache[k] = {}
s.cache[k].img = sprite.text(s.font, w, color, t);
if key and key ~= s.cache[k].img then
stead.sprite_dup(s.cache[k].img, key);
sprite.free(s.cache[k].img);
s.cache[k].img = key
end
s.cache[k].word = w;
s.cache[k].color = color;
s.cache[k].t = t;
s.cache[k].time = stead.time();
stead.table.insert(s.list, s.cache[k]);
end
if not stead.started and not time then
time = -1
end
if time then
s.cache[k].time = time
else
s.cache[k].time = stead.time(); -- renew time
end
end;
save = function(self, name, h, need)
h:write(stead.string.format("%s = font(%q, %d, %s);\n", name, self.fname, self.size, stead.tostring(self.scaled)))
local k, v
for k,v in ipairs(self.list) do
h:write(stead.string.format("%s:cache_add(%q, %q, %d, %q, %d);\n", name, v.word, v.color, v.t, v.img, v.time))
end
end;
}
if v.scaled then
size = sprite.font_scaled_size(size)
end
v.font = sprite.font(name, size);
lifeon(v);
return v;
end