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/frontend/ui/widget/config.lua b/frontend/ui/widget/config.lua index a04934d9a..e7a2a52a6 100644 --- a/frontend/ui/widget/config.lua +++ b/frontend/ui/widget/config.lua @@ -143,14 +143,6 @@ function RectSpan:getSize() return {w = self.width, h = self.height} end -ToggleLabel = TextWidget:new{} -function ToggleLabel:paintTo(bb, x, y) - if self.color == 0 then - return - end - renderUtf8Text(bb, x, y+self._height*0.75, self.face, self.text, true) -end - ConfigOption = CenterContainer:new{} function ConfigOption:init() local default_name_font_size = 20 diff --git a/frontend/ui/widget/toggleswitch.lua b/frontend/ui/widget/toggleswitch.lua index 9625a9677..f6cb431b1 100644 --- a/frontend/ui/widget/toggleswitch.lua +++ b/frontend/ui/widget/toggleswitch.lua @@ -1,11 +1,20 @@ -ToggleSwitch = InputContainer:new{} + +ToggleLabel = TextWidget:new{ + bgcolor = 0, + fgcolor = 1, +} + +function ToggleLabel:paintTo(bb, x, y) + renderUtf8Text(bb, x, y+self._height*0.75, self.face, self.text, true, self.bgcolor, self.fgcolor) +end + +ToggleSwitch = InputContainer:new{ + width = scaleByDPI(204), + height = scaleByDPI(30), +} function ToggleSwitch:init() self.n_pos = #self.toggle - if self.n_pos ~= 2 and self.n_pos ~= 3 then - -- currently only support options with two or three items. - error("items number not supported") - end self.position = nil local label_font_face = "cfont" @@ -14,55 +23,27 @@ function ToggleSwitch:init() self.toggle_frame = FrameContainer:new{background = 0, color = 7, radius = 7, bordersize = 1, padding = 2,} self.toggle_content = HorizontalGroup:new{} - self.left_label = ToggleLabel:new{ - align = "center", - color = 0, - text = self.toggle[self.n_pos], - face = Font:getFace(label_font_face, label_font_size), - } - self.left_button = FrameContainer:new{ - background = 0, - color = 7, - margin = 0, - radius = 5, - bordersize = 1, - padding = 2, - self.left_label, - } - self.middle_label = ToggleLabel:new{ - align = "center", - color = 0, - text = self.n_pos > 2 and self.toggle[2] or "", - face = Font:getFace(label_font_face, label_font_size), - } - self.middle_button = FrameContainer:new{ - background = 0, - color = 7, - margin = 0, - radius = 5, - bordersize = 1, - padding = 2, - self.middle_label, - } - self.right_label = ToggleLabel:new{ - align = "center", - color = 0, - text = self.toggle[1], - face = Font:getFace(label_font_face, label_font_size), - } - self.right_button = FrameContainer:new{ - background = 0, - color = 7, - margin = 0, - radius = 5, - bordersize = 1, - padding = 2, - self.right_label, - } - - table.insert(self.toggle_content, self.left_button) - table.insert(self.toggle_content, self.middle_button) - table.insert(self.toggle_content, self.right_button) + for i=1,#self.toggle do + local label = ToggleLabel:new{ + align = "center", + text = self.toggle[i], + face = Font:getFace(label_font_face, label_font_size), + } + local content = CenterContainer:new{ + dimen = Geom:new{w = self.width/self.n_pos, h = self.height}, + label, + } + local button = FrameContainer:new{ + background = 0, + color = 7, + margin = 0, + radius = 5, + bordersize = 1, + padding = 0, + content, + } + table.insert(self.toggle_content, button) + end self.toggle_frame[1] = self.toggle_content self[1] = self.toggle_frame @@ -81,18 +62,20 @@ function ToggleSwitch:init() end function ToggleSwitch:update() - local left_pos = self.position == 1 - local right_pos = self.position == self.n_pos - local middle_pos = not left_pos and not right_pos - self.left_label.color = right_pos and 15 or 0 - self.left_button.color = left_pos and 7 or 0 - self.left_button.background = left_pos and 7 or 0 - self.middle_label.color = middle_pos and 15 or 0 - self.middle_button.color = middle_pos and 0 or 0 - self.middle_button.background = middle_pos and 0 or 0 - self.right_label.color = left_pos and 15 or 0 - self.right_button.color = right_pos and 7 or 0 - self.right_button.background = right_pos and 7 or 0 + local pos = self.position + for i=1,#self.toggle_content do + if pos == i then + self.toggle_content[i].color = 7 + self.toggle_content[i].background = 7 + self.toggle_content[i][1][1].bgcolor = 0.5 + self.toggle_content[i][1][1].fgcolor = 0.0 + else + self.toggle_content[i].color = 0 + self.toggle_content[i].background = 0 + self.toggle_content[i][1][1].bgcolor = 0.0 + self.toggle_content[i][1][1].fgcolor = 1.0 + end + end end function ToggleSwitch:setPosition(position) 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++; } }