mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge branch 'txt'
* txt: use font metric to better display help page (to exted to other pages in future) draft commit, test implementation
This commit is contained in:
22
ft.c
22
ft.c
@@ -141,6 +141,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;
|
||||
}
|
||||
@@ -168,6 +170,25 @@ static int getKerning(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getHeightAndAscender(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) {
|
||||
@@ -184,6 +205,7 @@ static const struct luaL_Reg ft_face_meth[] = {
|
||||
{"renderGlyph", renderGlyph},
|
||||
{"hasKerning", hasKerning},
|
||||
{"getKerning", getKerning},
|
||||
{"getHeightAndAscender", getHeightAndAscender},
|
||||
{"done", doneFace},
|
||||
{"__gc", doneFace},
|
||||
{NULL, NULL}
|
||||
|
||||
37
helppage.lua
37
helppage.lua
@@ -7,11 +7,6 @@ require "selectmenu"
|
||||
require "commands"
|
||||
|
||||
HelpPage = {
|
||||
-- Other Class vars:
|
||||
|
||||
-- spacing between lines
|
||||
spacing = 25,
|
||||
|
||||
-- state buffer
|
||||
commands = nil,
|
||||
items = 0,
|
||||
@@ -21,16 +16,13 @@ HelpPage = {
|
||||
-- Other Class vars:
|
||||
|
||||
-- font for displaying keys
|
||||
HelpPage.fsize = 20
|
||||
HelpPage.face, HelpPage.fhash = Font:getFaceAndHash(HelpPage.fsize, "mono")
|
||||
HelpPage.mFace, HelpPage.mHash = Font:getFaceAndHash(20, "mono")
|
||||
-- font for displaying help messages
|
||||
HelpPage.hfsize = 20
|
||||
HelpPage.hface, HelpPage.hfhash = Font:getFaceAndHash(HelpPage.hfsize, "sans")
|
||||
HelpPage.sFace, HelpPage.sHash = Font:getFaceAndHash(20, "sans")
|
||||
-- font for paging display
|
||||
HelpPage.ffsize = 15
|
||||
HelpPage.fface, HelpPage.ffhash = Font:getFaceAndHash(HelpPage.ffsize, "sans")
|
||||
HelpPage.fFace, HelpPage.fHash = Font:getFaceAndHash(15, "sans")
|
||||
|
||||
function HelpPage:show(ypos, height,commands)
|
||||
function HelpPage:show(ypos,height,commands)
|
||||
self.commands = {}
|
||||
self.items = 0
|
||||
local keys = {}
|
||||
@@ -44,28 +36,39 @@ function HelpPage:show(ypos, height,commands)
|
||||
end
|
||||
end
|
||||
table.sort(self.commands,function(w1,w2) return w1.order<w2.order end)
|
||||
local perpage = math.floor( (height - 1 * (self.ffsize + 5)) / self.spacing )
|
||||
|
||||
local mFaceHeight, mFaceAscender = self.mFace:getHeightAndAscender();
|
||||
local fFaceHeight, fFaceAscender = self.fFace:getHeightAndAscender();
|
||||
print(mFaceHeight.."-"..mFaceAscender)
|
||||
print(fFaceHeight.."-"..fFaceAscender)
|
||||
mFaceHeight = math.ceil(mFaceHeight)
|
||||
mFaceAscender = math.ceil(mFaceAscender)
|
||||
fFaceHeight = math.ceil(fFaceHeight)
|
||||
fFaceAscender = math.ceil(fFaceAscender)
|
||||
local spacing = mFaceHeight + 5
|
||||
|
||||
local perpage = math.floor( (height - ypos - 1 * (fFaceHeight + 5)) / spacing )
|
||||
local pagedirty = true
|
||||
|
||||
while true do
|
||||
if pagedirty then
|
||||
fb.bb:paintRect(0, ypos, fb.bb:getWidth(), height, 0)
|
||||
fb.bb:paintRect(0, 0, fb.bb:getWidth(), height, 0)
|
||||
local c
|
||||
local max_x = 0
|
||||
for c = 1, perpage do
|
||||
local i = (self.page - 1) * perpage + c
|
||||
if i <= self.items then
|
||||
local pen_x = renderUtf8Text(fb.bb, 5, ypos + self.spacing*c, self.face, self.fhash, self.commands[i].shortcut, true)
|
||||
local pen_x = renderUtf8Text(fb.bb, 5, ypos + spacing*c, self.mFace, self.mHash, self.commands[i].shortcut, true)
|
||||
max_x = math.max(max_x, pen_x)
|
||||
end
|
||||
end
|
||||
for c = 1, perpage do
|
||||
local i = (self.page - 1) * perpage + c
|
||||
if i <= self.items then
|
||||
renderUtf8Text(fb.bb, max_x + 20, ypos + self.spacing*c, self.hface, self.hfhash, self.commands[i].help, true)
|
||||
renderUtf8Text(fb.bb, max_x + 20, ypos + spacing*c, self.sFace, self.sHash, self.commands[i].help, true)
|
||||
end
|
||||
end
|
||||
renderUtf8Text(fb.bb, 5, height - math.floor(self.ffsize * 0.4), self.fface, self.ffhash,
|
||||
renderUtf8Text(fb.bb, 5, height - fFaceHeight + fFaceAscender - 5, self.fFace, self.fHash,
|
||||
"Page "..self.page.." of "..math.ceil(self.items / perpage).." - click Back to close this page", true)
|
||||
markerdirty = true
|
||||
end
|
||||
|
||||
@@ -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:"..string.char(prevcharcode).." curr:"..string.char(charcode).." pen_x:"..pen_x.." 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
|
||||
|
||||
@@ -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);
|
||||
width, height = fb:getSize()
|
||||
fb.bb:paintRect(5,5,width-5,height-5,4);
|
||||
|
||||
renderUtf8Text(fb.bb, 100, 100, face, "h", "AV T.T: gxyt!", true)
|
||||
renderUtf8Text(fb.bb, 100, 200, face, "h", "AV T.T: gxyt!", false)
|
||||
faceHeight, faceAscender = face:getHeightAndAscender();
|
||||
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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user