From 9e3b7c82d43d4780ca14dcfd07fdeb81d0119a5b Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sun, 25 Dec 2011 00:26:25 +0200 Subject: [PATCH] Lua: Add gui.textH, gui.textV, gui.textHV --- include/core/render.hpp | 6 +++-- src/core/render.cpp | 59 +++++++++++++++++++++++++------------------------ src/lua/gui-text.cpp | 29 +++++++++++++++++++----- 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/include/core/render.hpp b/include/core/render.hpp index a2badad8..2c1600f9 100644 --- a/include/core/render.hpp +++ b/include/core/render.hpp @@ -368,7 +368,7 @@ void do_init_font(); * returns: Two components: First is width of character, second is pointer to font data (NULL if blank glyph). */ std::pair find_glyph(uint32_t codepoint, int32_t x, int32_t y, int32_t orig_x, - int32_t& next_x, int32_t& next_y) throw(); + int32_t& next_x, int32_t& next_y, bool hdbl = false, bool vdbl = false) throw(); /** * Render text into screen. @@ -378,9 +378,11 @@ std::pair find_glyph(uint32_t codepoint, int32_t x, i * parameter _text: The text to render (UTF-8). * parameter _fg: Foreground color. * parameter _bg: Background color. + * parameter _hdbl: If true, draw text using double width. + * parameter _vdbl: If true, draw text using double height. * throws std::bad_alloc: Not enough memory. */ void render_text(struct screen& scr, int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg, - premultiplied_color _bg) throw(std::bad_alloc); + premultiplied_color _bg, bool _hdbl = false, bool _vdbl = false) throw(std::bad_alloc); #endif diff --git a/src/core/render.cpp b/src/core/render.cpp index e1944c0b..a75b71b7 100644 --- a/src/core/render.cpp +++ b/src/core/render.cpp @@ -136,7 +136,7 @@ skip_line: return font_glyph_offsets.count(cp) ? font_glyph_offsets[cp] : 0; } - inline uint32_t process_tag(uint32_t tag, int32_t& x, int32_t& y, int32_t orig_x) + inline uint32_t process_tag(uint32_t tag, int32_t& x, int32_t& y, int32_t orig_x, bool hdbl, bool vdbl) { uint32_t dwidth; switch(tag & TAG_WIDTH_MASK) { @@ -153,9 +153,9 @@ skip_line: dwidth = 0x40 - (x & 0x3F); break; } - x += dwidth; + x += dwidth * (hdbl ? 2 : 1); if(tag & TAG_LINECHANGE) { - y += 16; + y += 16 * (vdbl ? 2 : 1); x = orig_x; } return dwidth; @@ -174,14 +174,14 @@ void do_init_font() } std::pair find_glyph(uint32_t codepoint, int32_t x, int32_t y, int32_t orig_x, - int32_t& next_x, int32_t& next_y) throw() + int32_t& next_x, int32_t& next_y, bool hdbl, bool vdbl) throw() { init_font(); next_x = x; next_y = y; uint32_t offset = find_font_glyph_offset(codepoint); uint32_t tag = font_glyph_data[offset]; - uint32_t dwidth = process_tag(tag, next_x, next_y, orig_x); + uint32_t dwidth = process_tag(tag, next_x, next_y, orig_x, hdbl, vdbl); bool visible = is_visible(tag); return std::pair(dwidth, visible ? &font_glyph_data[offset + 1] : NULL); } @@ -191,7 +191,7 @@ render_object::~render_object() throw() } void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& text, premultiplied_color fg, - premultiplied_color bg) throw(std::bad_alloc) + premultiplied_color bg, bool hdbl, bool vdbl) throw(std::bad_alloc) { int32_t orig_x = x; uint32_t unicode_code = 0; @@ -221,11 +221,11 @@ void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& te } else continue; int32_t next_x, next_y; - auto p = find_glyph(unicode_code, x, y, orig_x, next_x, next_y); + auto p = find_glyph(unicode_code, x, y, orig_x, next_x, next_y, hdbl, vdbl); uint32_t dx = 0; - uint32_t dw = p.first; + uint32_t dw = p.first * (hdbl ? 2 : 1); uint32_t dy = 0; - uint32_t dh = 16; + uint32_t dh = 16 * (vdbl ? 2 : 1); uint32_t cx = static_cast(static_cast(scr.originx) + x); uint32_t cy = static_cast(static_cast(scr.originy) + y); while(cx > scr.width && dw > 0) { @@ -245,6 +245,12 @@ void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& te if(!dw || !dh) continue; //Outside screen. + uint32_t rshift = (p.first == 16) ? (vdbl ? 2 : 1) : (vdbl ? 3 : 2); + uint32_t rishift = (p.first == 16) ? 4 : 3; + uint32_t xshift = hdbl ? 1 : 0; + uint32_t yshift = vdbl ? 1 : 0; + uint32_t b = dx & 1; + if(p.second == NULL) { //Blank glyph. for(uint32_t j = 0; j < dh; j++) { @@ -252,29 +258,24 @@ void render_text(struct screen& scr, int32_t x, int32_t y, const std::string& te for(uint32_t i = 0; i < dw; i++) bg.apply(base[i]); } - } else if(p.first == 16) { - //Wide glyph. - for(uint32_t j = 0; j < dh; j++) { - uint32_t dataword = p.second[(dy + j) >> 1]; - uint32_t* base = scr.rowptr(cy + j) + cx; - uint32_t rbit = (~((dy + j) << 4) & 0x1F) - dx; - for(uint32_t i = 0; i < dw; i++) - if((dataword >> (rbit - i)) & 1) - fg.apply(base[i]); - else - bg.apply(base[i]); - } } else { - //narrow glyph. for(uint32_t j = 0; j < dh; j++) { - uint32_t dataword = p.second[(dy + j) >> 2]; + uint32_t dataword = p.second[(dy + j) >> rshift]; uint32_t* base = scr.rowptr(cy + j) + cx; - uint32_t rbit = (~((dy + j) << 3) & 0x1F) - dx; - for(uint32_t i = 0; i < dw; i++) - if((dataword >> (rbit - i)) & 1) - fg.apply(base[i]); - else - bg.apply(base[i]); + uint32_t rbit = (~((dy + j) >> yshift << rishift) & 31) - (dx >> xshift); + if(hdbl) { + for(uint32_t i = 0; i < dw; i++) + if((dataword >> (rbit - ((i + b) >> 1))) & 1) + fg.apply(base[i]); + else + bg.apply(base[i]); + } else { + for(uint32_t i = 0; i < dw; i++) + if((dataword >> (rbit - i)) & 1) + fg.apply(base[i]); + else + bg.apply(base[i]); + } } } x = next_x; diff --git a/src/lua/gui-text.cpp b/src/lua/gui-text.cpp index cd5820ef..73f6ffcd 100644 --- a/src/lua/gui-text.cpp +++ b/src/lua/gui-text.cpp @@ -6,12 +6,12 @@ namespace struct render_object_text : public render_object { render_object_text(int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg, - premultiplied_color _bg) throw() - : x(_x), y(_y), text(_text), fg(_fg), bg(_bg) {} + premultiplied_color _bg, bool _hdbl = false, bool _vdbl = false) throw() + : x(_x), y(_y), text(_text), fg(_fg), bg(_bg), hdbl(_hdbl), vdbl(_vdbl) {} ~render_object_text() throw() {} void operator()(struct screen& scr) throw() { - render_text(scr, x, y, text, fg, bg); + render_text(scr, x, y, text, fg, bg, hdbl, vdbl); } private: int32_t x; @@ -19,9 +19,12 @@ namespace premultiplied_color fg; premultiplied_color bg; std::string text; + bool hdbl; + bool vdbl; }; - function_ptr_luafun gui_text("gui.text", [](lua_State* LS, const std::string& fname) -> int { + int internal_gui_text(lua_State* LS, const std::string& fname, bool hdbl, bool vdbl) + { if(!lua_render_ctx) return 0; int64_t fgc = 0xFFFFFFU; @@ -33,7 +36,23 @@ namespace std::string text = get_string_argument(LS, 3, fname.c_str()); premultiplied_color fg(fgc); premultiplied_color bg(bgc); - lua_render_ctx->queue->add(*new render_object_text(_x, _y, text, fg, bg)); + lua_render_ctx->queue->add(*new render_object_text(_x, _y, text, fg, bg, hdbl, vdbl)); return 0; + } + + function_ptr_luafun gui_text("gui.text", [](lua_State* LS, const std::string& fname) -> int { + internal_gui_text(LS, fname, false, false); + }); + + function_ptr_luafun gui_textH("gui.textH", [](lua_State* LS, const std::string& fname) -> int { + internal_gui_text(LS, fname, true, false); + }); + + function_ptr_luafun gui_textV("gui.textV", [](lua_State* LS, const std::string& fname) -> int { + internal_gui_text(LS, fname, false, true); + }); + + function_ptr_luafun gui_textHV("gui.textHV", [](lua_State* LS, const std::string& fname) -> int { + internal_gui_text(LS, fname, true, true); }); } -- 2.11.4.GIT