ReaderLink: Minor logic simplification in onGoToPageLink (#9987)

Abort earlier if the nearest link is too far, instead of computing stuff and creating an object we'll never actually use.

Includes minor logging tweaks to vaguely related codepaths ;p.
reviewable/pr9995/r1
NiLuJe 1 year ago committed by GitHub
parent a8b333e4f9
commit 4ce0058e2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -537,7 +537,7 @@ function ReaderLink:isXpointerCoherent(a_xpointer)
-- but easier to workaround here that way) -- but easier to workaround here that way)
re_link_xpointer, re_a_xpointer = self.ui.document:getLinkFromPosition({x = screen_x+1, y = screen_y}) -- luacheck: no unused re_link_xpointer, re_a_xpointer = self.ui.document:getLinkFromPosition({x = screen_x+1, y = screen_y}) -- luacheck: no unused
if re_a_xpointer ~= a_xpointer then if re_a_xpointer ~= a_xpointer then
logger.info("not coherent a_xpointer:", a_xpointer) logger.info("noncoherent a_xpointer:", a_xpointer)
return false return false
end end
end end
@ -563,8 +563,7 @@ function ReaderLink:getLinkFromGes(ges)
end end
else else
local link_xpointer, a_xpointer = self.ui.document:getLinkFromPosition(ges.pos) local link_xpointer, a_xpointer = self.ui.document:getLinkFromPosition(ges.pos)
logger.dbg("getLinkFromPosition link_xpointer:", link_xpointer) logger.dbg("ReaderLink:getLinkFromPosition @", ges.pos.x, ges.pos.y, "from a_xpointer:", a_xpointer, "to link_xpointer:", link_xpointer)
logger.dbg("getLinkFromPosition a_xpointer:", a_xpointer)
-- On some documents, crengine may sometimes give a wrong a_xpointer -- On some documents, crengine may sometimes give a wrong a_xpointer
-- (in some Wikipedia saved as EPUB, it would point to some other <A> -- (in some Wikipedia saved as EPUB, it would point to some other <A>
@ -580,8 +579,8 @@ function ReaderLink:getLinkFromGes(ges)
-- This link's source xpointer is more precise than a classic -- This link's source xpointer is more precise than a classic
-- xpointer to top of a page: we can show a marker at its -- xpointer to top of a page: we can show a marker at its
-- y-position in target page -- y-position in target page
-- (keep a_xpointer even if incoherent, might be needed for -- (keep a_xpointer even if noncoherent, might be needed for
-- footnote detection (better than nothing if incoherent) -- footnote detection (better than nothing if noncoherent)
return { return {
xpointer = link_xpointer, xpointer = link_xpointer,
marker_xpointer = link_xpointer, marker_xpointer = link_xpointer,
@ -703,12 +702,11 @@ end
-- (This is called by other modules (highlight, search) to jump to a xpointer, -- (This is called by other modules (highlight, search) to jump to a xpointer,
-- they should not provide allow_footnote_popup=true) -- they should not provide allow_footnote_popup=true)
function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_popup) function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_popup)
logger.dbg("onGotoLink:", link)
local link_url local link_url
if self.ui.document.info.has_pages then if self.ui.document.info.has_pages then
-- internal pdf links have a "page" attribute, while external ones have an "uri" attribute -- internal pdf links have a "page" attribute, while external ones have an "uri" attribute
if link.page then -- Internal link if link.page then -- Internal link
logger.dbg("Internal link:", link) logger.dbg("ReaderLink:onGotoLink: Internal link:", link)
if not neglect_current_location then if not neglect_current_location then
self:addCurrentLocationToStack() self:addCurrentLocationToStack()
end end
@ -724,7 +722,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po
-- Best to check that this link exists in document with the following, -- Best to check that this link exists in document with the following,
-- which accepts both of the above legitimate xpointer as input. -- which accepts both of the above legitimate xpointer as input.
if self.ui.document:isXPointerInDocument(link.xpointer) then if self.ui.document:isXPointerInDocument(link.xpointer) then
logger.dbg("Internal link:", link) logger.dbg("ReaderLink:onGotoLink: Internal link:", link)
if allow_footnote_popup then if allow_footnote_popup then
if self:showAsFootnotePopup(link, neglect_current_location) then if self:showAsFootnotePopup(link, neglect_current_location) then
return true return true
@ -763,7 +761,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po
end end
link_url = link.xpointer -- external link link_url = link.xpointer -- external link
end end
logger.dbg("External link:", link_url) logger.dbg("ReaderLink:onGotoLink: External link:", link_url)
local is_http_link = link_url:find("^https?://") ~= nil local is_http_link = link_url:find("^https?://") ~= nil
if is_http_link and self:onGoToExternalLink(link_url) then if is_http_link and self:onGoToExternalLink(link_url) then
@ -876,10 +874,9 @@ end
--- Goes to link nearest to the gesture (or first link in page) --- Goes to link nearest to the gesture (or first link in page)
function ReaderLink:onGoToPageLink(ges, internal_links_only, max_distance) function ReaderLink:onGoToPageLink(ges, internal_links_only, max_distance)
local selected_link = nil local selected_link, selected_distance2
local selected_distance2 = nil -- We use squared distances throughout the computations,
-- We use squares of distances all along the calculations, no need -- no need to math.sqrt() anything for comparisons.
-- to math.sqrt() them when comparing
if self.ui.document.info.has_pages then if self.ui.document.info.has_pages then
local pos = self.view:screenToPageTransform(ges.pos) local pos = self.view:screenToPageTransform(ges.pos)
if not pos then if not pos then
@ -901,7 +898,7 @@ function ReaderLink:onGoToPageLink(ges, internal_links_only, max_distance)
-- ["page"] = 347 -- ["page"] = 347
-- }, -- },
local pos_x, pos_y = pos.x, pos.y local pos_x, pos_y = pos.x, pos.y
local shortest_dist = nil local shortest_dist
for _, link in ipairs(links) do for _, link in ipairs(links) do
if not internal_links_only or link.page then if not internal_links_only or link.page then
local start_dist = (link.x0 - pos_x)^2 + (link.y0 - pos_y)^2 local start_dist = (link.x0 - pos_x)^2 + (link.y0 - pos_y)^2
@ -917,15 +914,16 @@ function ReaderLink:onGoToPageLink(ges, internal_links_only, max_distance)
end end
if shortest_dist then if shortest_dist then
selected_distance2 = shortest_dist selected_distance2 = shortest_dist
if max_distance and selected_distance2 > max_distance^2 then
selected_link = nil
end
end end
else else
-- Getting segments on a page with many internal links is -- Getting segments on a page with many internal links is a bit expensive.
-- a bit expensive. With larger_tap_area_to_follow_links=true, -- With larger_tap_area_to_follow_links, this is done on every tap, page turn or not.
-- this is done for each tap on screen (changing pages, showing -- getPageLinks goes through the CRe call cache, so at least repeat calls are cheaper.
-- menu...). We might want to cache these links per page (and -- If we only care about internal links, we only request those.
-- clear that cache when page layout change). -- That expensive segments work is always skipped on external links.
-- If we care only about internal links, request them only
-- (and avoid that expensive segments work on external links)
local links = self.ui.document:getPageLinks(internal_links_only) local links = self.ui.document:getPageLinks(internal_links_only)
if not links or #links == 0 then if not links or #links == 0 then
return return
@ -976,7 +974,7 @@ function ReaderLink:onGoToPageLink(ges, internal_links_only, max_distance)
-- coordinates, and our code below may miss or give the wrong first -- coordinates, and our code below may miss or give the wrong first
-- or nearest link... -- or nearest link...
local pos_x, pos_y = ges.pos.x, ges.pos.y local pos_x, pos_y = ges.pos.x, ges.pos.y
local shortest_dist = nil local shortest_dist
for _, link in ipairs(links) do for _, link in ipairs(links) do
-- link.uri may be an empty string with some invalid links: ignore them -- link.uri may be an empty string with some invalid links: ignore them
if link.section or (link.uri and link.uri ~= "") then if link.section or (link.uri and link.uri ~= "") then
@ -1040,35 +1038,34 @@ function ReaderLink:onGoToPageLink(ges, internal_links_only, max_distance)
end end
if shortest_dist then if shortest_dist then
selected_distance2 = shortest_dist selected_distance2 = shortest_dist
end if max_distance and selected_distance2 > max_distance^2 then
logger.dbg("nearest link is further than max distance, ignoring it")
if selected_link then selected_link = nil
logger.dbg("nearest selected_link", selected_link) else
-- Check a_xpointer is coherent, use it as from_xpointer only if it is logger.dbg("nearest selected_link", selected_link)
local from_xpointer = nil -- Check if a_xpointer is coherent, use it as from_xpointer only if it is
if selected_link.a_xpointer and self:isXpointerCoherent(selected_link.a_xpointer) then local from_xpointer = nil
from_xpointer = selected_link.a_xpointer if selected_link.a_xpointer and self:isXpointerCoherent(selected_link.a_xpointer) then
from_xpointer = selected_link.a_xpointer
end
-- Make it a link as expected by onGotoLink
selected_link = {
xpointer = selected_link.section or selected_link.uri,
marker_xpointer = selected_link.section,
from_xpointer = from_xpointer,
-- (keep a_xpointer even if noncoherent, might be needed for
-- footnote detection (better than nothing if noncoherent)
a_xpointer = selected_link.a_xpointer,
-- keep the link y position, so we can keep its highlight shown
-- a bit more time if it was hidden by the footnote popup
link_y = selected_link.link_y,
}
end end
-- Make it a link as expected by onGotoLink
selected_link = {
xpointer = selected_link.section or selected_link.uri,
marker_xpointer = selected_link.section,
from_xpointer = from_xpointer,
-- (keep a_xpointer even if incoherent, might be needed for
-- footnote detection (better than nothing if incoherent)
a_xpointer = selected_link.a_xpointer,
-- keep the link y position, so we can keep its highlight shown
-- a bit more time if it was hidden by the footnote popup
link_y = selected_link.link_y,
}
end end
end end
if selected_link then if selected_link then
if max_distance and selected_distance2 and selected_distance2 > max_distance^2 then return self:onGotoLink(selected_link, false, isFootnoteLinkInPopupEnabled())
logger.dbg("nearest link is further than max distance, ignoring it")
else
return self:onGotoLink(selected_link, false, isFootnoteLinkInPopupEnabled())
end
end end
end end
@ -1136,8 +1133,8 @@ function ReaderLink:selectRelPageLink(rel)
xpointer = selected_link.section or selected_link.uri, xpointer = selected_link.section or selected_link.uri,
marker_xpointer = selected_link.section, marker_xpointer = selected_link.section,
from_xpointer = from_xpointer, from_xpointer = from_xpointer,
-- (keep a_xpointer even if incoherent, might be needed for -- (keep a_xpointer even if noncoherent, might be needed for
-- footnote detection (better than nothing if incoherent) -- footnote detection (better than nothing if noncoherent)
a_xpointer = selected_link.a_xpointer, a_xpointer = selected_link.a_xpointer,
-- keep the link y position, so we can keep its highlight shown -- keep the link y position, so we can keep its highlight shown
-- a bit more time if it was hidden by the footnote popup -- a bit more time if it was hidden by the footnote popup

@ -816,7 +816,7 @@ function ReaderRolling:onRestoreBookLocation(saved_location)
end end
function ReaderRolling:onGotoViewRel(diff) function ReaderRolling:onGotoViewRel(diff)
logger.dbg("goto relative screen:", diff, ", in mode:", self.view.view_mode) logger.dbg("goto relative screen:", diff, "in mode:", self.view.view_mode)
if self.view.view_mode == "scroll" then if self.view.view_mode == "scroll" then
local footer_height = ((self.view.footer_visible and not self.view.footer.settings.reclaim_height) and 1 or 0) * self.view.footer:getHeight() local footer_height = ((self.view.footer_visible and not self.view.footer.settings.reclaim_height) and 1 or 0) * self.view.footer:getHeight()
local page_visible_height = self.ui.dimen.h - footer_height local page_visible_height = self.ui.dimen.h - footer_height

@ -158,11 +158,7 @@ function UIManager:show(widget, refreshtype, refreshregion, x, y, refreshdither)
-- tell the widget that it is shown now -- tell the widget that it is shown now
widget:handleEvent(Event:new("Show")) widget:handleEvent(Event:new("Show"))
-- check if this widget disables double tap gesture -- check if this widget disables double tap gesture
if widget.disable_double_tap == false then Input.disable_double_tap = widget.disable_double_tap ~= false
Input.disable_double_tap = false
else
Input.disable_double_tap = true
end
-- a widget may override tap interval (when it doesn't, nil restores the default) -- a widget may override tap interval (when it doesn't, nil restores the default)
Input.tap_interval_override = widget.tap_interval_override Input.tap_interval_override = widget.tap_interval_override
end end
@ -225,7 +221,7 @@ function UIManager:close(widget, refreshtype, refreshregion, refreshdither)
end end
end end
-- Set double tap to how the topmost specifying widget wants it -- Set double tap to how the topmost widget with that flag wants it
if requested_disable_double_tap == nil and w.disable_double_tap ~= nil then if requested_disable_double_tap == nil and w.disable_double_tap ~= nil then
requested_disable_double_tap = w.disable_double_tap requested_disable_double_tap = w.disable_double_tap
end end
@ -1341,7 +1337,7 @@ This is an explicit repaint *now*: it bypasses and ignores the paint queue (unli
function UIManager:widgetRepaint(widget, x, y) function UIManager:widgetRepaint(widget, x, y)
if not widget then return end if not widget then return end
logger.dbg("Explicit widgetRepaint:", widget.name or widget.id or tostring(widget), "@ (", x, ",", y, ")") logger.dbg("Explicit widgetRepaint:", widget.name or widget.id or tostring(widget), "@", x, y)
if widget.show_parent and widget.show_parent.cropping_widget then if widget.show_parent and widget.show_parent.cropping_widget then
-- The main widget parent of this subwidget has a cropping container: see if -- The main widget parent of this subwidget has a cropping container: see if
-- this widget is a child of this cropping container -- this widget is a child of this cropping container
@ -1368,7 +1364,7 @@ Same idea as `widgetRepaint`, but does a simple `bb:invertRect` on the Screen bu
function UIManager:widgetInvert(widget, x, y, w, h) function UIManager:widgetInvert(widget, x, y, w, h)
if not widget then return end if not widget then return end
logger.dbg("Explicit widgetInvert:", widget.name or widget.id or tostring(widget), "@ (", x, ",", y, ")") logger.dbg("Explicit widgetInvert:", widget.name or widget.id or tostring(widget), "@", x, y)
if widget.show_parent and widget.show_parent.cropping_widget then if widget.show_parent and widget.show_parent.cropping_widget then
-- The main widget parent of this subwidget has a cropping container: see if -- The main widget parent of this subwidget has a cropping container: see if
-- this widget is a child of this cropping container -- this widget is a child of this cropping container

Loading…
Cancel
Save