render text with background and foreground 'color'

pull/2/merge
chrox 11 years ago
parent 1f01537751
commit 26e2435fc6

@ -329,6 +329,7 @@ static int addblitToBuffer(lua_State *L) {
int yoffs = luaL_checkint(L, 6);
int w = luaL_checkint(L, 7);
int h = luaL_checkint(L, 8);
double p = luaL_checknumber(L, 9);
int x, y;
uint8_t *dstptr;
@ -349,7 +350,7 @@ static int addblitToBuffer(lua_State *L) {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint8_t v = (*dstptr & 0x0F) + (*srcptr & 0x0F);
uint8_t v = (int)((*dstptr & 0x0F)*(1-p) + (*srcptr & 0x0F)*p);
*dstptr = (*dstptr & 0xF0) | (v < 0x0F ? v : 0x0F);
dstptr += dst->pitch;
srcptr += src->pitch;
@ -358,7 +359,7 @@ static int addblitToBuffer(lua_State *L) {
for(y = 0; y < h; y++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint8_t v = (*dstptr & 0x0F) + (*srcptr >> 4);
uint8_t v = (int)((*dstptr & 0x0F)*(1-p) + (*srcptr >> 4)*p);
*dstptr = (*dstptr & 0xF0) | (v < 0x0F ? v : 0x0F);
dstptr += dst->pitch;
srcptr += src->pitch;
@ -381,14 +382,14 @@ static int addblitToBuffer(lua_State *L) {
for(x = 0; x < (w / 2); x++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + ((srcptr[x] & 0x0F) << 4);
uint8_t v2 = (dstptr[x] & 0x0F) + (srcptr[x+1] >> 4);
uint16_t v1 = (int)((dstptr[x] & 0xF0)*(1-p) + ((srcptr[x] & 0x0F) << 4)*p);
uint8_t v2 = (int)((dstptr[x] & 0x0F)*(1-p) + (srcptr[x+1] >> 4)*p);
dstptr[x] = (v1 < 0xF0 ? v1 : 0xF0) | (v2 < 0x0F ? v2 : 0x0F);
}
if(w & 1) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + ((srcptr[x] & 0x0F) << 4);
uint16_t v1 = (int)((dstptr[x] & 0xF0)*(1-p) + ((srcptr[x] & 0x0F) << 4)*p);
dstptr[x] = (dstptr[x] & 0x0F) | (v1 < 0xF0 ? v1 : 0xF0);
}
dstptr += dst->pitch;
@ -399,14 +400,14 @@ static int addblitToBuffer(lua_State *L) {
for(x = 0; x < (w / 2); x++) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + (srcptr[x] & 0xF0);
uint8_t v2 = (dstptr[x] & 0x0F) + (srcptr[x] & 0x0F);
uint16_t v1 = (int)((dstptr[x] & 0xF0)*(1-p) + (srcptr[x] & 0xF0)*p);
uint8_t v2 = (int)((dstptr[x] & 0x0F)*(1-p) + (srcptr[x] & 0x0F)*p);
dstptr[x] = (v1 < 0xF0 ? v1 : 0xF0) | (v2 < 0x0F ? v2 : 0x0F);
}
if(w & 1) {
ASSERT_BLITBUFFER_BOUNDARIES(dst, dstptr);
ASSERT_BLITBUFFER_BOUNDARIES(src, srcptr);
uint16_t v1 = (dstptr[x] & 0xF0) + (srcptr[x] & 0xF0);
uint16_t v1 = (int)((dstptr[x] & 0xF0)*(1-p) + (srcptr[x] & 0xF0)*p);
dstptr[x] = (dstptr[x] & 0x0F) | (v1 < 0xF0 ? v1 : 0xF0);
}
dstptr += dst->pitch;

@ -4,14 +4,16 @@ require "cache"
TODO: all these functions should probably be methods on Face objects
]]--
function getGlyph(face, charcode)
local hash = "glyph|"..face.hash.."|"..charcode
function getGlyph(face, charcode, bgcolor, fgcolor)
if bgcolor == nil then bgcolor = 0.0 end
if fgcolor == nil then fgcolor = 1.0 end
local hash = "glyph|"..face.hash.."|"..charcode.."|"..bgcolor.."|"..fgcolor
local glyph = Cache:check(hash)
if glyph then
-- cache hit
return glyph[1]
end
local rendered_glyph = face.ftface:renderGlyph(charcode)
local rendered_glyph = face.ftface:renderGlyph(charcode, bgcolor, fgcolor)
if not rendered_glyph then
DEBUG("error rendering glyph (charcode=", charcode, ") for face", face)
return
@ -75,7 +77,7 @@ function sizeUtf8Text(x, width, face, text, kerning)
return { x = pen_x, y_top = pen_y_top, y_bottom = pen_y_bottom}
end
function renderUtf8Text(buffer, x, y, face, text, kerning)
function renderUtf8Text(buffer, x, y, face, text, kerning, bgcolor, fgcolor)
if not text then
DEBUG("renderUtf8Text called without text");
return 0
@ -89,7 +91,7 @@ function renderUtf8Text(buffer, x, y, face, text, kerning)
for uchar in string.gfind(text, "([%z\1-\127\194-\244][\128-\191]*)") do
if pen_x < buffer_width then
local charcode = util.utf8charcode(uchar)
local glyph = getGlyph(face, charcode)
local glyph = getGlyph(face, charcode, bgcolor, fgcolor)
if kerning and (prevcharcode ~= 0) then
pen_x = pen_x + face.ftface:getKerning(prevcharcode, charcode)
end
@ -97,7 +99,7 @@ function renderUtf8Text(buffer, x, y, face, text, kerning)
glyph.bb,
x + pen_x + glyph.l, y - glyph.t,
0, 0,
glyph.bb:getWidth(), glyph.bb:getHeight())
glyph.bb:getWidth(), glyph.bb:getHeight(), 1)
pen_x = pen_x + glyph.ax
prevcharcode = charcode
end -- if pen_x < buffer_width

@ -67,6 +67,8 @@ static int newFace(lua_State *L) {
static int renderGlyph(lua_State *L) {
KPVFace *face = (KPVFace*) luaL_checkudata(L, 1, "ft_face");
int ch = luaL_checkint(L, 2);
double bg = luaL_checknumber(L, 3);
double fg = luaL_checknumber(L, 4);
FT_Error error = FT_Load_Char(face->face, ch, FT_LOAD_RENDER);
if(error) {
return luaL_error(L, "freetype error");
@ -91,12 +93,13 @@ static int renderGlyph(lua_State *L) {
for(y = 0; y < h; y++) {
uint8_t *src = face->face->glyph->bitmap.buffer + y * face->face->glyph->bitmap.pitch;
for(x = 0; x < (w/2); x++) {
*dst = (src[0] & 0xF0) | (src[1] >> 4);
*dst = (int)(0xFF * bg - src[0] * (bg - fg)) & 0xF0 |
(int)(0xFF * bg - src[1] * (bg - fg)) >> 4;
src+=2;
dst++;
}
if(w & 1) {
*dst = *src & 0xF0;
*dst = (int)(0xFF * bg - *src * (bg - fg)) & 0xF0;
dst++;
}
}

Loading…
Cancel
Save