Lua: Add gui.textH, gui.textV, gui.textHV
This commit is contained in:
parent
7f8b57b7ad
commit
9e3b7c82d4
3 changed files with 58 additions and 36 deletions
|
@ -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<uint32_t, const uint32_t*> 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<uint32_t, const uint32_t*> 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
|
||||
|
|
|
@ -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<uint32_t, const uint32_t*> 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<uint32_t, const uint32_t*>(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<uint32_t>(static_cast<int32_t>(scr.originx) + x);
|
||||
uint32_t cy = static_cast<uint32_t>(static_cast<int32_t>(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.
|
||||
} else {
|
||||
for(uint32_t j = 0; j < dh; j++) {
|
||||
uint32_t dataword = p.second[(dy + j) >> 1];
|
||||
uint32_t dataword = p.second[(dy + j) >> rshift];
|
||||
uint32_t* base = scr.rowptr(cy + j) + cx;
|
||||
uint32_t rbit = (~((dy + j) << 4) & 0x1F) - dx;
|
||||
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]);
|
||||
}
|
||||
} else {
|
||||
//narrow glyph.
|
||||
for(uint32_t j = 0; j < dh; j++) {
|
||||
uint32_t dataword = p.second[(dy + j) >> 2];
|
||||
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]);
|
||||
}
|
||||
}
|
||||
x = next_x;
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue