Fix bug causing ext0...ext3 to sometimes appear pressed on 12btn gamepad
[lsnes.git] / src / lua / gui-text-cf.cpp
blobec24064afe27b8740f9920603e55e2c605cdb967
1 #include "lua/internal.hpp"
2 #include "fonts/wrapper.hpp"
3 #include "core/framebuffer.hpp"
4 #include "library/framebuffer.hpp"
5 #include "library/customfont.hpp"
6 #include "library/utf8.hpp"
7 #include <algorithm>
10 namespace
12 struct lua_customfont
14 public:
15 lua_customfont(lua_state* L, const std::string& filename);
16 ~lua_customfont() throw();
17 int draw(lua_state& L);
18 const custom_font& get_font() { return font; }
19 private:
20 custom_font font;
24 DECLARE_LUACLASS(lua_customfont, "CUSTOMFONT");
26 namespace
28 struct render_object_text_cf : public render_object
30 render_object_text_cf(int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg,
31 premultiplied_color _bg, premultiplied_color _hl, lua_obj_pin<lua_customfont>* _font) throw()
32 : x(_x), y(_y), text(_text), fg(_fg), bg(_bg), hl(_hl), font(_font) {}
33 ~render_object_text_cf() throw()
35 delete font;
37 template<bool X> void op(struct framebuffer<X>& scr) throw()
39 fg.set_palette(scr);
40 bg.set_palette(scr);
41 hl.set_palette(scr);
42 const custom_font& fdata = font->object()->get_font();
43 std::u32string _text = to_u32string(text);
44 int32_t orig_x = x;
45 int32_t drawx = x;
46 int32_t drawy = y;
47 if(hl) {
48 //Adjust for halo.
49 drawx++;
50 orig_x++;
51 drawy++;
53 for(size_t i = 0; i < _text.size();) {
54 uint32_t cp = _text[i];
55 std::u32string k = fdata.best_ligature_match(_text, i);
56 const font_glyph_data& glyph = fdata.lookup_glyph(k);
57 if(k.length())
58 i += k.length();
59 else
60 i++;
61 if(cp == 9) {
62 drawx = (drawx + 64) >> 6 << 6;
63 } else if(cp == 10) {
64 drawx = orig_x;
65 drawy += fdata.get_rowadvance();
66 } else {
67 glyph.render(scr, drawx, drawy, fg, bg, hl);
68 drawx += glyph.width;
72 bool kill_request(void* obj) throw()
74 return kill_request_ifeq(unbox_any_pin(font), obj);
76 void operator()(struct framebuffer<true>& scr) throw() { op(scr); }
77 void operator()(struct framebuffer<false>& scr) throw() { op(scr); }
78 void clone(render_queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
79 private:
80 int32_t x;
81 int32_t y;
82 std::string text;
83 premultiplied_color fg;
84 premultiplied_color bg;
85 premultiplied_color hl;
86 lua_obj_pin<lua_customfont>* font;
89 lua_customfont::lua_customfont(lua_state* L, const std::string& filename)
90 : font(filename)
92 static char done_key;
93 if(L->do_once(&done_key)) {
94 objclass<lua_customfont>().bind(*L, "__call", &lua_customfont::draw);
98 lua_customfont::~lua_customfont() throw()
100 render_kill_request(this);
103 int lua_customfont::draw(lua_state& L)
105 std::string fname = "CUSTOMFONT::__call";
106 if(!lua_render_ctx)
107 return 0;
108 int64_t fgc = 0xFFFFFFU;
109 int64_t bgc = -1;
110 int64_t hlc = -1;
111 int32_t _x = L.get_numeric_argument<int32_t>(2, fname.c_str());
112 int32_t _y = L.get_numeric_argument<int32_t>(3, fname.c_str());
113 L.get_numeric_argument<int64_t>(5, fgc, fname.c_str());
114 L.get_numeric_argument<int64_t>(6, bgc, fname.c_str());
115 L.get_numeric_argument<int64_t>(7, hlc, fname.c_str());
116 std::string text = L.get_string(4, fname.c_str());
117 auto f = lua_class<lua_customfont>::pin(L, 1, fname.c_str());
118 premultiplied_color fg(fgc);
119 premultiplied_color bg(bgc);
120 premultiplied_color hl(hlc);
121 lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, hl, f);
122 return 0;
125 function_ptr_luafun gui_text_cf(LS, "gui.loadfont", [](lua_state& L, const std::string& fname) -> int {
126 std::string filename = L.get_string(1, fname.c_str());
127 try {
128 lua_class<lua_customfont>::create(L, &L, filename);
129 return 1;
130 } catch(std::exception& e) {
131 L.pushstring(e.what());
132 L.error();
133 return 0;