diff --git a/blitbuffer.c b/blitbuffer.c index 5fcc5d337..4e5284576 100644 --- a/blitbuffer.c +++ b/blitbuffer.c @@ -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; diff --git a/frontend/ui/rendertext.lua b/frontend/ui/rendertext.lua index 9b4b492a6..aefc1983c 100644 --- a/frontend/ui/rendertext.lua +++ b/frontend/ui/rendertext.lua @@ -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 diff --git a/ft.c b/ft.c index 385ebbecf..83c83c2a6 100644 --- a/ft.c +++ b/ft.c @@ -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++; } }