Refactoring: copy_from_utf8()
[lsnes.git] / src / lua / gui-text-cf.cpp
blobd3cc37fe2d627ca88112011e4223baec69513224
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, lua_obj_pin<lua_customfont>* _font) throw()
32 : x(_x), y(_y), text(_text), fg(_fg), bg(_bg), 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 const custom_font& fdata = font->object()->get_font();
42 std::vector<uint32_t> _text;
43 copy_from_utf8(text.begin(), text.end(), std::back_inserter(_text));
44 int32_t orig_x = x;
45 int32_t drawx = x;
46 int32_t drawy = y;
47 for(size_t i = 0; i < _text.size();) {
48 uint32_t cp = _text[i];
49 ligature_key k = fdata.best_ligature_match(_text, i);
50 const font_glyph_data& glyph = fdata.lookup_glyph(k);
51 if(k.length())
52 i += k.length();
53 else
54 i++;
55 if(cp == 9) {
56 drawx = (drawx + 64) >> 6 << 6;
57 } else if(cp == 10) {
58 drawx = orig_x;
59 drawy += fdata.get_rowadvance();
60 } else {
61 glyph.render(scr, drawx, drawy, fg, bg);
62 drawx += glyph.width;
66 bool kill_request(void* obj) throw()
68 return kill_request_ifeq(unbox_any_pin(font), obj);
70 void operator()(struct framebuffer<true>& scr) throw() { op(scr); }
71 void operator()(struct framebuffer<false>& scr) throw() { op(scr); }
72 void clone(render_queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
73 private:
74 int32_t x;
75 int32_t y;
76 std::string text;
77 premultiplied_color fg;
78 premultiplied_color bg;
79 lua_obj_pin<lua_customfont>* font;
82 lua_customfont::lua_customfont(lua_state* L, const std::string& filename)
83 : font(filename)
85 static char done_key;
86 if(L->do_once(&done_key)) {
87 objclass<lua_customfont>().bind(*L, "__call", &lua_customfont::draw);
91 lua_customfont::~lua_customfont() throw()
93 render_kill_request(this);
96 int lua_customfont::draw(lua_state& L)
98 std::string fname = "CUSTOMFONT::__call";
99 if(!lua_render_ctx)
100 return 0;
101 int64_t fgc = 0xFFFFFFU;
102 int64_t bgc = -1;
103 int32_t _x = L.get_numeric_argument<int32_t>(2, fname.c_str());
104 int32_t _y = L.get_numeric_argument<int32_t>(3, fname.c_str());
105 L.get_numeric_argument<int64_t>(5, fgc, fname.c_str());
106 L.get_numeric_argument<int64_t>(6, bgc, fname.c_str());
107 std::string text = L.get_string(4, fname.c_str());
108 auto f = lua_class<lua_customfont>::pin(L, 1, fname.c_str());
109 premultiplied_color fg(fgc);
110 premultiplied_color bg(bgc);
111 lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, f);
112 return 0;
115 function_ptr_luafun gui_text_cf(LS, "gui.loadfont", [](lua_state& L, const std::string& fname) -> int {
116 std::string filename = L.get_string(1, fname.c_str());
117 try {
118 lua_class<lua_customfont>::create(L, &L, filename);
119 return 1;
120 } catch(std::exception& e) {
121 L.pushstring(e.what());
122 L.error();
123 return 0;