Instancefy framebuffer stuff
[lsnes.git] / src / lua / gui-text-cf.cpp
blob214faf092452fc202607ab11a2cde5edf6b7c5b8
1 #include "lua/internal.hpp"
2 #include "lua/bitmap.hpp"
3 #include "fonts/wrapper.hpp"
4 #include "core/framebuffer.hpp"
5 #include "core/instance.hpp"
6 #include "library/framebuffer-font2.hpp"
7 #include "library/utf8.hpp"
8 #include "library/lua-framebuffer.hpp"
9 #include "library/zip.hpp"
10 #include <algorithm>
13 namespace
15 struct lua_customfont
17 public:
18 struct empty_font_tag {};
19 lua_customfont(lua::state& L, const std::string& filename, const std::string& filename2);
20 lua_customfont(lua::state& L);
21 lua_customfont(lua::state& L, empty_font_tag tag);
22 static size_t overcommit() { return 0; }
23 static size_t overcommit(const std::string& filename, const std::string& filename2) { return 0; }
24 static size_t overcommit(empty_font_tag tag) { return 0; }
25 ~lua_customfont() throw();
26 static int create(lua::state& L, lua::parameters& P);
27 static int load(lua::state& L, lua::parameters& P);
28 int draw(lua::state& L, lua::parameters& P);
29 int edit(lua::state& L, lua::parameters& P);
30 const framebuffer::font2& get_font() { return font; }
31 std::string print()
33 return orig_filename;
35 private:
36 std::string orig_filename;
37 framebuffer::font2 font;
40 lua::_class<lua_customfont> class_customfont(lua_class_gui, "CUSTOMFONT", {
41 {"new", lua_customfont::create},
42 {"load", lua_customfont::load},
43 }, {
44 {"__call", &lua_customfont::draw},
45 {"edit", &lua_customfont::edit},
46 }, &lua_customfont::print);
48 struct render_object_text_cf : public framebuffer::object
50 render_object_text_cf(int32_t _x, int32_t _y, const std::string& _text, framebuffer::color _fg,
51 framebuffer::color _bg, framebuffer::color _hl, lua::objpin<lua_customfont> _font) throw()
52 : x(_x), y(_y), text(_text), fg(_fg), bg(_bg), hl(_hl), font(_font) {}
53 ~render_object_text_cf() throw()
56 template<bool X> void op(struct framebuffer::fb<X>& scr) throw()
58 const framebuffer::font2& fdata = font->get_font();
59 std::u32string _text = utf8::to32(text);
60 int32_t orig_x = x;
61 int32_t drawx = x;
62 int32_t drawy = y;
63 if(hl) {
64 //Adjust for halo.
65 drawx++;
66 orig_x++;
67 drawy++;
69 for(size_t i = 0; i < _text.size();) {
70 uint32_t cp = _text[i];
71 std::u32string k = fdata.best_ligature_match(_text, i);
72 const framebuffer::font2::glyph& glyph = fdata.lookup_glyph(k);
73 if(k.length())
74 i += k.length();
75 else
76 i++;
77 if(cp == 9) {
78 drawx = (drawx + 64) >> 6 << 6;
79 } else if(cp == 10) {
80 drawx = orig_x;
81 drawy += fdata.get_rowadvance();
82 } else {
83 glyph.render(scr, drawx, drawy, fg, bg, hl);
84 drawx += glyph.width;
88 bool kill_request(void* obj) throw()
90 return kill_request_ifeq(font.object(), obj);
92 void operator()(struct framebuffer::fb<true>& scr) throw() { op(scr); }
93 void operator()(struct framebuffer::fb<false>& scr) throw() { op(scr); }
94 void clone(framebuffer::queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
95 private:
96 int32_t x;
97 int32_t y;
98 std::string text;
99 framebuffer::color fg;
100 framebuffer::color bg;
101 framebuffer::color hl;
102 lua::objpin<lua_customfont> font;
105 lua_customfont::lua_customfont(lua::state& L, const std::string& filename, const std::string& filename2)
106 : orig_filename(zip::resolverel(filename, filename2)), font(orig_filename)
110 lua_customfont::lua_customfont(lua::state& L)
111 : font(main_font)
113 orig_filename = "<builtin>";
116 lua_customfont::~lua_customfont() throw()
118 CORE().fbuf.render_kill_request(this);
121 int lua_customfont::draw(lua::state& L, lua::parameters& P)
123 int32_t _x, _y;
124 framebuffer::color fg, bg, hl;
125 std::string text;
126 lua::objpin<lua_customfont> f;
128 if(!lua_render_ctx)
129 return 0;
131 P(f, _x, _y, text, P.optional(fg, 0xFFFFFFU), P.optional(bg, -1), P.optional(hl, -1));
133 lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, hl, f);
134 return 0;
137 lua_customfont::lua_customfont(lua::state& L, lua_customfont::empty_font_tag tag)
139 orig_filename = "<empty>";
142 int lua_customfont::edit(lua::state& L, lua::parameters& P)
144 std::string text;
145 lua_bitmap* _glyph;
147 P(P.skipped(), text, _glyph);
149 framebuffer::font2::glyph glyph;
150 glyph.width = _glyph->width;
151 glyph.height = _glyph->height;
152 glyph.stride = (glyph.width + 31) / 32;
153 glyph.fglyph.resize(glyph.stride * glyph.height);
154 memset(&glyph.fglyph[0], 0, sizeof(uint32_t) * glyph.fglyph.size());
155 for(size_t y = 0; y < glyph.height; y++) {
156 size_t bpos = y * glyph.stride * 32;
157 for(size_t x = 0; x < glyph.width; x++) {
158 size_t e = (bpos + x) / 32;
159 size_t b = 31 - (bpos + x) % 32;
160 if(_glyph->pixels[y * _glyph->width + x])
161 glyph.fglyph[e] |= (1UL << b);
164 font.add(utf8::to32(text), glyph);
165 return 0;
168 int lua_customfont::create(lua::state& L, lua::parameters& P)
170 lua::_class<lua_customfont>::create(L, lua_customfont::empty_font_tag());
171 return 1;
174 int lua_customfont::load(lua::state& L, lua::parameters& P)
176 std::string filename, filename2;
177 if(P.is_novalue()) {
178 lua::_class<lua_customfont>::create(L);
179 return 1;
182 P(filename, P.optional(filename2, ""));
184 lua::_class<lua_customfont>::create(L, filename, filename2);
185 return 1;