From 918f296bd3464ec6bbd87ed044209566f5e8c499 Mon Sep 17 00:00:00 2001 From: poire-z Date: Tue, 26 Feb 2019 07:16:43 +0100 Subject: [PATCH] cre scroll mode: fix highlights not shown when small pages The idea of looking for highlights 1 page before and after was not working when you have multiple small pages, and some scroll mode view was actually showing 3 or 4 pages. So, rework that by using absolute positions when looking for highlights present in the scrolled view. --- .../apps/reader/modules/readerhighlight.lua | 42 ++++++++++------- frontend/apps/reader/modules/readerview.lua | 45 +++++++++++-------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 6b0264124..834d401b1 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -207,10 +207,7 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges) -- showing menu...). We might want to cache these boxes per page (and -- clear that cache when page layout change or highlights are added -- or removed). - local cur_page - -- In scroll mode, we'll need to check for highlights in previous or next - -- page too as some parts of them may be displayed - local neighbour_pages = self.view.view_mode ~= "page" and 1 or 0 + local cur_page, cur_scroll_top, cur_scroll_bottom local pos = self.view:screenToPageTransform(ges.pos) for page, _ in pairs(self.view.highlight.saved) do local items = self.view.highlight.saved[page] @@ -222,17 +219,32 @@ function ReaderHighlight:onTapXPointerSavedHighlight(ges) local pos0, pos1 = items[i].pos0, items[i].pos1 -- document:getScreenBoxesFromPositions() is expensive, so we -- first check this item is on current page - local page0 = self.ui.document:getPageFromXPointer(pos0) - local page1 = self.ui.document:getPageFromXPointer(pos1) - local start_page = math.min(page0, page1) - local end_page = math.max(page0, page1) - -- In scroll mode, we may be displaying cur_page and cur_page+1, so - -- we have to check the highlight start_page is <= cur_page+1. - -- Same thinking with highlight's end_page >= cur_page-1 as we may - -- be displaying a part of cur_page-1. - -- (A highlight starting on cur_page-17 and ending on cur_page+13 is - -- a highlight to consider) - if start_page <= cur_page + neighbour_pages and end_page >= cur_page - neighbour_pages then + local is_in_view = false + if self.view_mode == "page" then + if not cur_page then + cur_page = self.ui.document:getPageFromXPointer(self.ui.document:getXPointer()) + end + local page0 = self.ui.document:getPageFromXPointer(pos0) + local page1 = self.ui.document:getPageFromXPointer(pos1) + local start_page = math.min(page0, page1) + local end_page = math.max(page0, page1) + if start_page <= cur_page and end_page >= cur_page then + is_in_view = true + end + else + if not cur_scroll_top then + cur_scroll_top = self.ui.document:getPosFromXPointer(self.ui.document:getXPointer()) + cur_scroll_bottom = cur_scroll_top + self.ui.dimen.h + end + local spos0 = self.ui.document:getPosFromXPointer(pos0) + local spos1 = self.ui.document:getPosFromXPointer(pos1) + local start_pos = math.min(spos0, spos1) + local end_pos = math.max(spos0, spos1) + if start_pos <= cur_scroll_bottom and end_pos >= cur_scroll_top then + is_in_view = true + end + end + if is_in_view then local boxes = self.ui.document:getScreenBoxesFromPositions(pos0, pos1, true) -- get_segments=true if boxes then for index, box in pairs(boxes) do diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index 10b2dcbf5..9f9a5fa10 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -495,32 +495,41 @@ function ReaderView:drawXPointerSavedHighlight(bb, x, y) -- showing menu...). We might want to cache these boxes per page (and -- clear that cache when page layout change or highlights are added -- or removed). - local cur_page - -- In scroll mode, we'll need to check for highlights in previous or next - -- page too as some parts of them may be displayed - local neighbour_pages = self.view_mode ~= "page" and 1 or 0 + local cur_page, cur_scroll_top, cur_scroll_bottom for page, _ in pairs(self.highlight.saved) do local items = self.highlight.saved[page] if not items then items = {} end for j = 1, #items do - if not cur_page then - cur_page = self.ui.document:getPageFromXPointer(self.ui.document:getXPointer()) - end local item = items[j] local pos0, pos1 = item.pos0, item.pos1 -- document:getScreenBoxesFromPositions() is expensive, so we -- first check this item is on current page - local page0 = self.ui.document:getPageFromXPointer(pos0) - local page1 = self.ui.document:getPageFromXPointer(pos1) - local start_page = math.min(page0, page1) - local end_page = math.max(page0, page1) - -- In scroll mode, we may be displaying cur_page and cur_page+1, so - -- we have to check the highlight start_page is <= cur_page+1. - -- Same thinking with highlight's end_page >= cur_page-1 as we may - -- be displaying a part of cur_page-1. - -- (A highlight starting on cur_page-17 and ending on cur_page+13 is - -- a highlight to consider) - if start_page <= cur_page + neighbour_pages and end_page >= cur_page - neighbour_pages then + local is_in_view = false + if self.view_mode == "page" then + if not cur_page then + cur_page = self.ui.document:getPageFromXPointer(self.ui.document:getXPointer()) + end + local page0 = self.ui.document:getPageFromXPointer(pos0) + local page1 = self.ui.document:getPageFromXPointer(pos1) + local start_page = math.min(page0, page1) + local end_page = math.max(page0, page1) + if start_page <= cur_page and end_page >= cur_page then + is_in_view = true + end + else + if not cur_scroll_top then + cur_scroll_top = self.ui.document:getPosFromXPointer(self.ui.document:getXPointer()) + cur_scroll_bottom = cur_scroll_top + self.ui.dimen.h + end + local spos0 = self.ui.document:getPosFromXPointer(pos0) + local spos1 = self.ui.document:getPosFromXPointer(pos1) + local start_pos = math.min(spos0, spos1) + local end_pos = math.max(spos0, spos1) + if start_pos <= cur_scroll_bottom and end_pos >= cur_scroll_top then + is_in_view = true + end + end + if is_in_view then local boxes = self.ui.document:getScreenBoxesFromPositions(pos0, pos1, true) -- get_segments=true if boxes then for _, box in pairs(boxes) do