lsnes/src/lua/gui-text-cf.cpp

184 lines
4.9 KiB
C++
Raw Normal View History

2013-02-01 21:52:27 +02:00
#include "lua/internal.hpp"
#include "lua/bitmap.hpp"
2013-02-01 21:52:27 +02:00
#include "fonts/wrapper.hpp"
#include "core/framebuffer.hpp"
2013-02-01 21:52:27 +02:00
#include "library/framebuffer.hpp"
#include "library/framebuffer-font2.hpp"
2013-02-01 21:52:27 +02:00
#include "library/utf8.hpp"
#include "library/lua-framebuffer.hpp"
#include "library/zip.hpp"
2013-03-13 01:02:10 +02:00
#include <algorithm>
2013-02-01 21:52:27 +02:00
namespace
{
struct lua_customfont
{
public:
struct empty_font_tag {};
lua_customfont(lua::state& L, const std::string& filename, const std::string& filename2);
lua_customfont(lua::state& L);
lua_customfont(lua::state& L, empty_font_tag tag);
2013-02-01 21:52:27 +02:00
~lua_customfont() throw();
2014-01-26 17:42:22 +02:00
static int create(lua::state& L, lua::parameters& P);
static int load(lua::state& L, lua::parameters& P);
int draw(lua::state& L, lua::parameters& P);
int edit(lua::state& L, lua::parameters& P);
const framebuffer::font2& get_font() { return font; }
2013-09-27 10:36:19 +03:00
std::string print()
{
2013-12-11 21:12:34 +02:00
return orig_filename;
2013-09-27 10:36:19 +03:00
}
2013-02-01 21:52:27 +02:00
private:
2013-12-11 21:12:34 +02:00
std::string orig_filename;
framebuffer::font2 font;
2013-02-01 21:52:27 +02:00
};
2014-01-26 17:42:22 +02:00
lua::_class<lua_customfont> class_customfont(lua_class_gui, "CUSTOMFONT", {
{"new", lua_customfont::create},
{"load", lua_customfont::load},
}, {
{"__call", &lua_customfont::draw},
{"edit", &lua_customfont::edit},
}, &lua_customfont::print);
2013-02-01 21:52:27 +02:00
struct render_object_text_cf : public framebuffer::object
2013-02-01 21:52:27 +02:00
{
render_object_text_cf(int32_t _x, int32_t _y, const std::string& _text, framebuffer::color _fg,
framebuffer::color _bg, framebuffer::color _hl, lua::objpin<lua_customfont> _font) throw()
: x(_x), y(_y), text(_text), fg(_fg), bg(_bg), hl(_hl), font(_font) {}
~render_object_text_cf() throw()
{
}
template<bool X> void op(struct framebuffer::fb<X>& scr) throw()
2013-02-01 21:52:27 +02:00
{
const framebuffer::font2& fdata = font->get_font();
std::u32string _text = utf8::to32(text);
2013-02-01 21:52:27 +02:00
int32_t orig_x = x;
int32_t drawx = x;
int32_t drawy = y;
if(hl) {
//Adjust for halo.
drawx++;
orig_x++;
drawy++;
}
2013-02-01 21:52:27 +02:00
for(size_t i = 0; i < _text.size();) {
uint32_t cp = _text[i];
std::u32string k = fdata.best_ligature_match(_text, i);
const framebuffer::font2::glyph& glyph = fdata.lookup_glyph(k);
2013-02-01 21:52:27 +02:00
if(k.length())
i += k.length();
else
i++;
if(cp == 9) {
drawx = (drawx + 64) >> 6 << 6;
} else if(cp == 10) {
drawx = orig_x;
drawy += fdata.get_rowadvance();
} else {
glyph.render(scr, drawx, drawy, fg, bg, hl);
2013-02-01 21:52:27 +02:00
drawx += glyph.width;
}
}
}
bool kill_request(void* obj) throw()
{
2013-08-21 19:24:00 +03:00
return kill_request_ifeq(font.object(), obj);
}
void operator()(struct framebuffer::fb<true>& scr) throw() { op(scr); }
void operator()(struct framebuffer::fb<false>& scr) throw() { op(scr); }
void clone(framebuffer::queue& q) const throw(std::bad_alloc) { q.clone_helper(this); }
2013-02-01 21:52:27 +02:00
private:
int32_t x;
int32_t y;
2013-02-10 15:00:12 +02:00
std::string text;
framebuffer::color fg;
framebuffer::color bg;
framebuffer::color hl;
lua::objpin<lua_customfont> font;
2013-02-01 21:52:27 +02:00
};
lua_customfont::lua_customfont(lua::state& L, const std::string& filename, const std::string& filename2)
: orig_filename(zip::resolverel(filename, filename2)), font(orig_filename)
2013-12-11 21:12:34 +02:00
{
}
lua_customfont::lua_customfont(lua::state& L)
2013-12-11 21:12:34 +02:00
: font(main_font)
{
orig_filename = "<builtin>";
}
lua_customfont::~lua_customfont() throw()
{
render_kill_request(this);
}
2013-07-06 23:21:11 +03:00
int lua_customfont::draw(lua::state& L, lua::parameters& P)
2013-02-01 21:52:27 +02:00
{
int32_t _x, _y;
framebuffer::color fg, bg, hl;
std::string text;
lua::objpin<lua_customfont> f;
2013-02-01 21:52:27 +02:00
if(!lua_render_ctx)
return 0;
P(f, _x, _y, text, P.optional(fg, 0xFFFFFFU), P.optional(bg, -1), P.optional(hl, -1));
lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, hl, f);
2013-02-01 21:52:27 +02:00
return 0;
}
lua_customfont::lua_customfont(lua::state& L, lua_customfont::empty_font_tag tag)
{
orig_filename = "<empty>";
}
int lua_customfont::edit(lua::state& L, lua::parameters& P)
{
std::string text;
lua_bitmap* _glyph;
P(P.skipped(), text, _glyph);
framebuffer::font2::glyph glyph;
glyph.width = _glyph->width;
glyph.height = _glyph->height;
glyph.stride = (glyph.width + 31) / 32;
glyph.fglyph.resize(glyph.stride * glyph.height);
memset(&glyph.fglyph[0], 0, sizeof(uint32_t) * glyph.fglyph.size());
for(size_t y = 0; y < glyph.height; y++) {
size_t bpos = y * glyph.stride * 32;
for(size_t x = 0; x < glyph.width; x++) {
size_t e = (bpos + x) / 32;
size_t b = 31 - (bpos + x) % 32;
if(_glyph->pixels[y * _glyph->width + x])
glyph.fglyph[e] |= (1UL << b);
}
}
font.add(utf8::to32(text), glyph);
}
2014-01-26 17:42:22 +02:00
int lua_customfont::create(lua::state& L, lua::parameters& P)
{
lua::_class<lua_customfont>::create(L, lua_customfont::empty_font_tag());
return 1;
2014-01-26 17:42:22 +02:00
};
2014-01-26 17:42:22 +02:00
int lua_customfont::load(lua::state& L, lua::parameters& P)
{
std::string filename, filename2;
if(P.is_novalue()) {
lua::_class<lua_customfont>::create(L);
2013-12-11 21:12:34 +02:00
return 1;
}
P(filename, P.optional(filename2, ""));
lua::_class<lua_customfont>::create(L, filename, filename2);
return 1;
2014-01-26 17:42:22 +02:00
};
2013-02-01 21:52:27 +02:00
}