diff --git a/ft.c b/ft.c index 5cfc9b69b..1b3682545 100644 --- a/ft.c +++ b/ft.c @@ -142,6 +142,8 @@ static int renderGlyph(lua_State *L) { lua_setfield(L, -2, "t"); lua_pushinteger(L, (*face)->glyph->advance.x >> 6); lua_setfield(L, -2, "ax"); + lua_pushinteger(L, (*face)->glyph->advance.y >> 6); + lua_setfield(L, -2, "ay"); return 1; } @@ -169,6 +171,25 @@ static int getKerning(lua_State *L) { return 1; } +static int getHeight(lua_State *L) { + FT_Face *face = (FT_Face*) luaL_checkudata(L, 1, "ft_face"); + + double pixels_height,pixels_ascender; + double em_size, y_scale; + + /* compute floating point scale factors */ + em_size = 1.0 * (*face)->units_per_EM; + y_scale = (*face)->size->metrics.y_ppem / em_size; + + /* convert design distances to floating point pixels */ + pixels_height = (*face)->height * y_scale; + pixels_ascender = (*face)->ascender * y_scale; + + lua_pushnumber(L, pixels_height); + lua_pushnumber(L, pixels_ascender); + return 2; +} + static int doneFace(lua_State *L) { FT_Face *face = (FT_Face*) luaL_checkudata(L, 1, "ft_face"); if(*face != NULL) { @@ -185,6 +206,7 @@ static const struct luaL_reg ft_face_meth[] = { {"renderGlyph", renderGlyph}, {"hasKerning", hasKerning}, {"getKerning", getKerning}, + {"getHeight", getHeight}, {"done", doneFace}, {"__gc", doneFace}, {NULL, NULL} diff --git a/rendertext.lua b/rendertext.lua index 0096b84b7..e194ea14b 100644 --- a/rendertext.lua +++ b/rendertext.lua @@ -43,6 +43,35 @@ function clearglyphcache() glyphcache = {} end +function sizeUtf8Text(face, facehash, text, kerning) + if text == nil then + print("# sizeUtf8Text called without text"); + return + end + -- may still need more adaptive pen placement when kerning, + -- see: http://freetype.org/freetype2/docs/glyphs/glyphs-4.html + local pen_x = 0 + local prevcharcode = 0 + for uchar in string.gfind(text, "([%z\1-\127\194-\244][\128-\191]*)") do + if pen_x < buffer:getWidth() then + local charcode = util.utf8charcode(uchar) + local glyph = getglyph(face, facehash, charcode) + if kerning and prevcharcode then + local kern = face:getKerning(prevcharcode, charcode) + pen_x = pen_x + kern + print("prev:"..string.char(prevcharcode+10).." curr:"..string.char(charcode).." kern:"..kern) + buffer:addblitFrom(glyph.bb, x + pen_x + glyph.l, y - glyph.t, 0, 0, glyph.bb:getWidth(), glyph.bb:getHeight()) + else + print("curr:"..string.char(charcode)) + buffer:blitFrom(glyph.bb, x + pen_x + glyph.l, y - glyph.t, 0, 0, glyph.bb:getWidth(), glyph.bb:getHeight()) + end + pen_x = pen_x + glyph.ax + prevcharcode = charcode + end + end + return pen_x +end + function renderUtf8Text(buffer, x, y, face, facehash, text, kerning) if text == nil then print("# renderUtf8Text called without text"); @@ -59,8 +88,10 @@ function renderUtf8Text(buffer, x, y, face, facehash, text, kerning) if kerning and prevcharcode then local kern = face:getKerning(prevcharcode, charcode) pen_x = pen_x + kern + --print("prev:"..prevcharcode.." curr:"..charcode.." kern:"..kern) buffer:addblitFrom(glyph.bb, x + pen_x + glyph.l, y - glyph.t, 0, 0, glyph.bb:getWidth(), glyph.bb:getHeight()) else + --print(" curr:"..charcode) buffer:blitFrom(glyph.bb, x + pen_x + glyph.l, y - glyph.t, 0, 0, glyph.bb:getWidth(), glyph.bb:getHeight()) end pen_x = pen_x + glyph.ax @@ -69,4 +100,3 @@ function renderUtf8Text(buffer, x, y, face, facehash, text, kerning) end return pen_x end - diff --git a/rendertext_example.lua b/rendertext_example.lua index 12dbf524d..8b8a24bdf 100755 --- a/rendertext_example.lua +++ b/rendertext_example.lua @@ -6,19 +6,28 @@ fb = einkfb.open("/dev/fb0") width, height = fb:getSize() print("open") - -face = freetype.newBuiltinFace("sans", 64) ---face = freetype.newFace("test.ttf", 64) +size = 50 +--face = freetype.newBuiltinFace("sans", 64) +face = freetype.newFace("/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf", size) print("got face") if face:hasKerning() then print("has kerning") end -fb.bb:paintRect(1,1,599,300,7); - -renderUtf8Text(fb.bb, 100, 100, face, "h", "AV T.T: gxyt!", true) -renderUtf8Text(fb.bb, 100, 200, face, "h", "AV T.T: gxyt!", false) +width, height = fb:getSize() +fb.bb:paintRect(5,5,width-5,height-5,4); + +faceHeight, faceAscender = face:getHeight(); +print("face height:"..tostring(faceHeight).." - ascender:"..faceAscender) +faceHeight = math.ceil(faceHeight) +faceAscender = math.ceil(faceAscender) +print("face height:"..tostring(faceHeight).." - ascender:"..faceAscender) + +posY = 5 + faceAscender +renderUtf8Text(fb.bb, 5, posY, face, "h", "AV T.T: gxyt!", true) +posY = posY + faceHeight +renderUtf8Text(fb.bb, 5, posY, face, "h2", "AV T.T: gxyt!", false) fb:refresh()