Lua: CUSTOMFONT: Allow painting with halo

Conflicts:

	manual.txt
	src/lua/gui-text-cf.cpp
This commit is contained in:
Ilari Liusvaara 2013-03-29 17:15:28 +02:00
parent 3e1836453b
commit e27a06f7c3
6 changed files with 87 additions and 30 deletions

View file

@ -33,9 +33,10 @@ struct font_glyph_data
unsigned height;
unsigned stride;
std::vector<uint32_t> glyph; //Bitpacked, element breaks between rows.
void render(framebuffer<false>& fb, int32_t x, int32_t y, premultiplied_color fg, premultiplied_color bg)
const;
void render(framebuffer<true>& fb, int32_t x, int32_t y, premultiplied_color fg, premultiplied_color bg) const;
void render(framebuffer<false>& fb, int32_t x, int32_t y, premultiplied_color fg, premultiplied_color bg,
premultiplied_color hl) const;
void render(framebuffer<true>& fb, int32_t x, int32_t y, premultiplied_color fg, premultiplied_color bg,
premultiplied_color hl) const;
};
struct custom_font

View file

@ -392,6 +392,9 @@ struct premultiplied_color
uint16_t inv;
uint32_t invHI;
operator bool() const throw() { return (origa != 0); }
bool operator!() const throw() { return (origa == 0); }
premultiplied_color() throw()
{
hi = lo = 0;

View file

@ -2837,12 +2837,15 @@ Loads font from specified file (CUSTOMFONT object).
\end_layout
\begin_layout Subsubsection
CUSTOMFONT(number x, number y, string text[, number fgc[, number bgc]])
CUSTOMFONT(number x, number y, string text[, number fgc[, number bgc[, number
hlc]]])
\end_layout
\begin_layout Standard
Draw string with custom font to screen.
The parameters are the same as in gui.text.
The parameters are the same as in gui.text, except hlc is the halo color
(default is no halo).
\end_layout
\begin_layout Subsection

View file

@ -1427,10 +1427,11 @@ Saves a screenshot into specified file.
Loads font from specified file (CUSTOMFONT object).
8.3.30 CUSTOMFONT(number x, number y, string text[, number fgc[,
number bgc]])
number bgc[, number hlc]]])
Draw string with custom font to screen. The parameters are the
same as in gui.text.
same as in gui.text, except hlc is the halo color (default is no
halo).
8.4 table input

View file

@ -49,24 +49,63 @@ namespace
size = dim - dc;
}
inline bool readfont(const font_glyph_data& glyph, uint32_t xp1, uint32_t yp1)
{
if(xp1 < 1 || xp1 > glyph.width || yp1 < 1 || yp1 > glyph.height)
return false;
xp1--;
yp1--;
size_t ge = yp1 * glyph.stride + (xp1 / 32);
size_t gb = 31 - xp1 % 32;
return ((glyph.glyph[ge] >> gb) & 1);
}
template<bool T> void _render(const font_glyph_data& glyph, framebuffer<T>& fb, int32_t x, int32_t y,
premultiplied_color fg, premultiplied_color bg)
premultiplied_color fg, premultiplied_color bg, premultiplied_color hl)
{
uint32_t xdc, xoff, xsize;
uint32_t ydc, yoff, ysize;
bound(x, glyph.width, fb.get_width(), xdc, xoff, xsize);
bound(y, glyph.height, fb.get_height(), ydc, yoff, ysize);
if(!xsize || !ysize)
return;
for(unsigned i = 0; i < ysize; i++) {
auto p = fb.rowptr(i + ydc);
for(unsigned j = 0; j < xsize; j++) {
size_t ge = (i + yoff) * glyph.stride + ((j + xoff) / 32);
size_t gb = 31 - (j + xoff) % 32;
if((glyph.glyph[ge] >> gb) & 1)
fg.apply(p[j + xdc]);
else
bg.apply(p[j + xdc]);
if(hl) {
bound(x - 1, glyph.width + 2, fb.get_width(), xdc, xoff, xsize);
bound(y - 1, glyph.height + 2, fb.get_height(), ydc, yoff, ysize);
if(!xsize || !ysize)
return;
for(unsigned i = 0; i < ysize; i++) {
auto p = fb.rowptr(i + ydc) + xdc;
for(unsigned j = 0; j < xsize; j++) {
bool in_halo = false;
in_halo |= readfont(glyph, j + xoff - 1, i + yoff - 1);
in_halo |= readfont(glyph, j + xoff, i + yoff - 1);
in_halo |= readfont(glyph, j + xoff + 1, i + yoff - 1);
in_halo |= readfont(glyph, j + xoff - 1, i + yoff);
in_halo |= readfont(glyph, j + xoff + 1, i + yoff);
in_halo |= readfont(glyph, j + xoff - 1, i + yoff + 1);
in_halo |= readfont(glyph, j + xoff, i + yoff + 1);
in_halo |= readfont(glyph, j + xoff + 1, i + yoff + 1);
if(readfont(glyph, j + xoff, i + yoff))
fg.apply(p[j]);
else if(in_halo)
hl.apply(p[j]);
else
bg.apply(p[j]);
}
}
} else {
bound(x, glyph.width, fb.get_width(), xdc, xoff, xsize);
bound(y, glyph.height, fb.get_height(), ydc, yoff, ysize);
if(!xsize || !ysize)
return;
for(unsigned i = 0; i < ysize; i++) {
auto p = fb.rowptr(i + ydc) + xdc;
for(unsigned j = 0; j < xsize; j++) {
size_t ge = (i + yoff) * glyph.stride + ((j + xoff) / 32);
size_t gb = 31 - (j + xoff) % 32;
if((glyph.glyph[ge] >> gb) & 1)
fg.apply(p[j]);
else
bg.apply(p[j]);
}
}
}
}
@ -157,15 +196,15 @@ font_glyph_data::font_glyph_data(std::istream& s)
}
void font_glyph_data::render(framebuffer<false>& fb, int32_t x, int32_t y, premultiplied_color fg,
premultiplied_color bg) const
premultiplied_color bg, premultiplied_color hl) const
{
_render(*this, fb, x, y, fg, bg);
_render(*this, fb, x, y, fg, bg, hl);
}
void font_glyph_data::render(framebuffer<true>& fb, int32_t x, int32_t y, premultiplied_color fg,
premultiplied_color bg) const
premultiplied_color bg, premultiplied_color hl) const
{
_render(*this, fb, x, y, fg, bg);
_render(*this, fb, x, y, fg, bg, hl);
}

View file

@ -41,8 +41,8 @@ namespace
struct render_object_text_cf : public render_object
{
render_object_text_cf(int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg,
premultiplied_color _bg, lua_obj_pin<lua_customfont>* _font) throw()
: x(_x), y(_y), text(_text), fg(_fg), bg(_bg), font(_font) {}
premultiplied_color _bg, premultiplied_color _hl, lua_obj_pin<lua_customfont>* _font) throw()
: x(_x), y(_y), text(_text), fg(_fg), bg(_bg), hl(_hl), font(_font) {}
~render_object_text_cf() throw()
{
delete font;
@ -51,11 +51,18 @@ namespace
{
fg.set_palette(scr);
bg.set_palette(scr);
hl.set_palette(scr);
const custom_font& fdata = font->object()->get_font();
std::vector<uint32_t> _text = decode_utf8(text);
int32_t orig_x = x;
int32_t drawx = x;
int32_t drawy = y;
if(hl) {
//Adjust for halo.
drawx++;
orig_x++;
drawy++;
}
for(size_t i = 0; i < _text.size();) {
uint32_t cp = _text[i];
ligature_key k = fdata.best_ligature_match(_text, i);
@ -70,7 +77,7 @@ namespace
drawx = orig_x;
drawy += fdata.get_rowadvance();
} else {
glyph.render(scr, drawx, drawy, fg, bg);
glyph.render(scr, drawx, drawy, fg, bg, hl);
drawx += glyph.width;
}
}
@ -87,6 +94,7 @@ namespace
int32_t y;
premultiplied_color fg;
premultiplied_color bg;
premultiplied_color hl;
std::string text;
lua_obj_pin<lua_customfont>* font;
};
@ -112,15 +120,18 @@ namespace
return 0;
int64_t fgc = 0xFFFFFFU;
int64_t bgc = -1;
int64_t hlc = -1;
int32_t _x = get_numeric_argument<int32_t>(LS, 2, fname.c_str());
int32_t _y = get_numeric_argument<int32_t>(LS, 3, fname.c_str());
get_numeric_argument<int64_t>(LS, 5, fgc, fname.c_str());
get_numeric_argument<int64_t>(LS, 6, bgc, fname.c_str());
get_numeric_argument<int64_t>(LS, 7, hlc, fname.c_str());
std::string text = get_string_argument(LS, 4, fname.c_str());
auto f = lua_class<lua_customfont>::pin(LS, 1, fname.c_str());
premultiplied_color fg(fgc);
premultiplied_color bg(bgc);
lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, f);
premultiplied_color hl(hlc);
lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, hl, f);
return 0;
}
@ -137,4 +148,3 @@ namespace
});
}