mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge pull request #309 from dpavlin/pdf-links
show pdf links using L key
This commit is contained in:
58
pdf.c
58
pdf.c
@@ -492,9 +492,9 @@ static int getUsedBBox(lua_State *L) {
|
||||
return luaL_error(L, "cannot calculate bbox for page");
|
||||
}
|
||||
|
||||
lua_pushnumber(L, ((double)result.x0)/100);
|
||||
lua_pushnumber(L, ((double)result.x0)/100);
|
||||
lua_pushnumber(L, ((double)result.y0)/100);
|
||||
lua_pushnumber(L, ((double)result.x1)/100);
|
||||
lua_pushnumber(L, ((double)result.x1)/100);
|
||||
lua_pushnumber(L, ((double)result.y1)/100);
|
||||
|
||||
return 4;
|
||||
@@ -577,6 +577,59 @@ static int cleanCache(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int getPageLinks(lua_State *L) {
|
||||
fz_link *page_links;
|
||||
fz_link *link;
|
||||
|
||||
int link_count;
|
||||
|
||||
PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage");
|
||||
|
||||
page_links = fz_load_links(page->doc->xref, page->page); // page->doc->xref?
|
||||
|
||||
lua_newtable(L); // all links
|
||||
|
||||
link_count = 0;
|
||||
|
||||
for (link = page_links; link; link = link->next) {
|
||||
lua_newtable(L); // new link
|
||||
|
||||
lua_pushstring(L, "x0");
|
||||
lua_pushinteger(L, link->rect.x0);
|
||||
lua_settable(L, -3);
|
||||
lua_pushstring(L, "y0");
|
||||
lua_pushinteger(L, link->rect.y0);
|
||||
lua_settable(L, -3);
|
||||
lua_pushstring(L, "x1");
|
||||
lua_pushinteger(L, link->rect.x1);
|
||||
lua_settable(L, -3);
|
||||
lua_pushstring(L, "y1");
|
||||
lua_pushinteger(L, link->rect.y1);
|
||||
lua_settable(L, -3);
|
||||
|
||||
if (link->dest.kind == FZ_LINK_URI) {
|
||||
lua_pushstring(L, "uri");
|
||||
lua_pushstring(L, link->dest.ld.uri.uri);
|
||||
lua_settable(L, -3);
|
||||
} else if (link->dest.kind == FZ_LINK_GOTO) {
|
||||
lua_pushstring(L, "page");
|
||||
lua_pushinteger(L, link->dest.ld.gotor.page); // FIXME page+1?
|
||||
lua_settable(L, -3);
|
||||
} else {
|
||||
printf("ERROR: unkown link kind: %x", link->dest.kind);
|
||||
}
|
||||
|
||||
lua_rawseti(L, -2, ++link_count);
|
||||
}
|
||||
|
||||
printf("## getPageLinks found %d links in document\n", link_count);
|
||||
|
||||
fz_drop_link(page->doc->context, page_links);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg pdf_func[] = {
|
||||
{"openDocument", openDocument},
|
||||
{NULL, NULL}
|
||||
@@ -599,6 +652,7 @@ static const struct luaL_Reg pdfpage_meth[] = {
|
||||
{"getSize", getPageSize},
|
||||
{"getUsedBBox", getUsedBBox},
|
||||
{"getPageText", getPageText},
|
||||
{"getPageLinks", getPageLinks},
|
||||
{"close", closePage},
|
||||
{"__gc", closePage},
|
||||
{"draw", drawPage},
|
||||
|
||||
@@ -45,3 +45,16 @@ function PDFReader:getText(pageno)
|
||||
page:close()
|
||||
return text
|
||||
end
|
||||
|
||||
function PDFReader:getPageLinks(pageno)
|
||||
local ok, page = pcall(self.doc.openPage, self.doc, pageno)
|
||||
if not ok then
|
||||
-- TODO: error handling
|
||||
return nil
|
||||
end
|
||||
local links = page:getPageLinks()
|
||||
Debug("## page:getPageLinks ", links)
|
||||
page:close()
|
||||
return links
|
||||
end
|
||||
|
||||
|
||||
127
unireader.lua
127
unireader.lua
@@ -1389,6 +1389,17 @@ function UniReader:show(no)
|
||||
self:toggleTextHighLight(self.highlight[no])
|
||||
end
|
||||
|
||||
-- draw links on page
|
||||
local links = self:getPageLinks( no )
|
||||
if links ~= nil then
|
||||
for i, link in ipairs(links) do
|
||||
if link.page then -- skip non-page links
|
||||
local x,y,w,h = self:zoomedRectCoordTransform( link.x0,link.y0, link.x1,link.y1 )
|
||||
fb.bb:invertRect(x,y+h-2, w,1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.rcount >= self.rcountmax then
|
||||
Debug("full refresh")
|
||||
self.rcount = 0
|
||||
@@ -2070,6 +2081,11 @@ function UniReader:searchHighLight(search)
|
||||
end
|
||||
|
||||
|
||||
function UniReader:getPageLinks(pageno)
|
||||
Debug("getPageLinks not supported in this format")
|
||||
return nil
|
||||
end
|
||||
|
||||
-- used in UniReader:showMenu()
|
||||
function UniReader:_drawReadingInfo()
|
||||
local width, height = G_width, G_height
|
||||
@@ -2865,6 +2881,117 @@ function UniReader:addAllCommands()
|
||||
end
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_L, nil, "L",
|
||||
"page links",
|
||||
function(unireader)
|
||||
local links = unireader:getPageLinks( unireader.pageno )
|
||||
if links == nil or next(links) == nil then
|
||||
showInfoMsgWithDelay("No links on this page", 2000, 1)
|
||||
else
|
||||
local font_size = math.ceil( (links[1].y1 - links[1].y0 - 2) * unireader.globalzoom )
|
||||
Debug("font_size",font_size)
|
||||
Debug("shortcuts",SelectMenu.item_shortcuts)
|
||||
local face = Font:getFace("rifont", font_size)
|
||||
|
||||
local page_links = 0
|
||||
|
||||
for i, link in ipairs(links) do
|
||||
if link.page then
|
||||
local x,y,w,h = self:zoomedRectCoordTransform( link.x0,link.y0, link.x1,link.y1 )
|
||||
fb.bb:dimRect(x,y,w,h) -- black 50%
|
||||
fb.bb:dimRect(x,y,w,h) -- black 25%
|
||||
page_links = page_links + 1
|
||||
end
|
||||
end
|
||||
|
||||
if page_links == 0 then
|
||||
showInfoMsgWithDelay("No links on this page", 2000, 1)
|
||||
return
|
||||
end
|
||||
|
||||
Screen:saveCurrentBB() -- save dimmed links
|
||||
|
||||
local shortcut_offset = 0
|
||||
local shortcut_map
|
||||
|
||||
local render_shortcuts = function()
|
||||
Screen:restoreFromSavedBB()
|
||||
|
||||
local shortcut_nr = 1
|
||||
shortcut_map = {}
|
||||
|
||||
for i = 1, #SelectMenu.item_shortcuts, 1 do
|
||||
local link = links[ i + shortcut_offset ]
|
||||
if link == nil then break end
|
||||
Debug("link", i, shortcut_offset, link)
|
||||
if link.page then
|
||||
local x,y,w,h = self:zoomedRectCoordTransform( link.x0,link.y0, link.x1,link.y1 )
|
||||
renderUtf8Text(fb.bb, x, y + font_size - 1, face, SelectMenu.item_shortcuts[shortcut_nr])
|
||||
shortcut_map[shortcut_nr] = i + shortcut_offset
|
||||
shortcut_nr = shortcut_nr + 1
|
||||
end
|
||||
end
|
||||
|
||||
Debug("shortcut_map", shortcut_map)
|
||||
|
||||
fb:refresh(1)
|
||||
end
|
||||
|
||||
render_shortcuts()
|
||||
|
||||
local goto_page = nil
|
||||
|
||||
while not goto_page do
|
||||
|
||||
local ev = input.saveWaitForEvent()
|
||||
ev.code = adjustKeyEvents(ev)
|
||||
Debug("ev",ev)
|
||||
|
||||
local link = nil
|
||||
|
||||
if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then
|
||||
if ev.code >= KEY_Q and ev.code <= KEY_P then
|
||||
link = ev.code - KEY_Q + 1
|
||||
elseif ev.code >= KEY_A and ev.code <= KEY_L then
|
||||
link = ev.code - KEY_A + 11
|
||||
elseif ev.code == KEY_SLASH then
|
||||
link = 20
|
||||
elseif ev.code >= KEY_Z and ev.code <= KEY_M then
|
||||
link = ev.code - KEY_Z + 21
|
||||
elseif ev.code == KEY_DOT then
|
||||
link = 28
|
||||
elseif ev.code == KEY_SYM then
|
||||
link = 29
|
||||
elseif ev.code == KEY_ENTER then
|
||||
link = 30
|
||||
elseif ev.code == KEY_BACK then
|
||||
goto_page = unireader.pageno
|
||||
elseif ( ev.code == KEY_FW_RIGHT or ev.code == KEY_FW_DOWN ) and shortcut_offset <= #links - 30 then
|
||||
shortcut_offset = shortcut_offset + 30
|
||||
render_shortcuts()
|
||||
elseif ( ev.code == KEY_FW_LEFT or ev.code == KEY_FW_UP ) and shortcut_offset >= 30 then
|
||||
shortcut_offset = shortcut_offset - 30
|
||||
render_shortcuts()
|
||||
end
|
||||
end
|
||||
|
||||
if link then
|
||||
link = shortcut_map[link]
|
||||
if links[link] ~= nil and links[link].page ~= nil then
|
||||
goto_page = links[link].page + 1
|
||||
else
|
||||
Debug("missing link", link)
|
||||
end
|
||||
end
|
||||
|
||||
Debug("goto_page", goto_page, "now on", unireader.pageno, "link", link)
|
||||
end
|
||||
|
||||
unireader:goto(goto_page)
|
||||
|
||||
end
|
||||
end
|
||||
)
|
||||
self.commands:add(KEY_BACK,MOD_ALT,"Back",
|
||||
"close document",
|
||||
function(unireader)
|
||||
|
||||
Reference in New Issue
Block a user