mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Hide non-linear fragments
Add option to hide (skip) non-linear fragments, only working in 1-page mode. Tweaks mostly to footer, toc and skim code to make it clear(er) which pages belong to linear or non-linear fragments.
This commit is contained in:
@@ -58,6 +58,11 @@ local CreDocument = Document:new{
|
||||
default_css = "./data/cr3.css",
|
||||
provider = "crengine",
|
||||
provider_name = "Cool Reader Engine",
|
||||
|
||||
hide_nonlinear_flows = false,
|
||||
flows = {},
|
||||
page_in_flow = {},
|
||||
last_linear_page = nil,
|
||||
}
|
||||
|
||||
-- NuPogodi, 20.05.12: inspect the zipfile content
|
||||
@@ -283,10 +288,188 @@ function CreDocument:updateColorRendering()
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:setHideNonlinearFlows(hide_nonlinear_flows)
|
||||
if hide_nonlinear_flows ~= self.hide_nonlinear_flows then
|
||||
self.hide_nonlinear_flows = hide_nonlinear_flows
|
||||
self._document:setIntProperty("crengine.doc.nonlinear.pagebreak.force", self.hide_nonlinear_flows and 1 or 0)
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:getPageCount()
|
||||
return self._document:getPages()
|
||||
end
|
||||
|
||||
-- Whether the document has any non-linear flow to care about
|
||||
function CreDocument:hasNonLinearFlows()
|
||||
return self._document:hasNonLinearFlows()
|
||||
end
|
||||
|
||||
-- Whether non-linear flows (if any) will be hidden
|
||||
function CreDocument:hasHiddenFlows()
|
||||
return self.flows[1] ~= nil
|
||||
end
|
||||
|
||||
-- Get the next/prev page number, skipping non-linear flows,
|
||||
-- i.e. the next/prev page that is either in the current
|
||||
-- flow or in the linear flow (flow 0)
|
||||
-- If "page" is 0, these give the initial and final linear pages
|
||||
function CreDocument:getNextPage(page)
|
||||
if self:hasHiddenFlows() then
|
||||
if page < 0 or page >= self:getPageCount() then
|
||||
return 0
|
||||
elseif page == 0 then
|
||||
return self:getFirstPageInFlow(0)
|
||||
end
|
||||
local flow = self:getPageFlow(page)
|
||||
local start_page = page + 1
|
||||
local end_page = self:getLastLinearPage()
|
||||
local test_page = start_page
|
||||
-- max to ensure at least one iteration
|
||||
-- (in case the current flow goes after all linear pages)
|
||||
while test_page <= math.max(end_page, start_page) do
|
||||
local test_page_flow = self:getPageFlow(test_page)
|
||||
if test_page_flow == flow or test_page_flow == 0 then
|
||||
-- same flow as current, or linear flow, this is a "good" page
|
||||
return test_page
|
||||
elseif test_page_flow > 0 then
|
||||
-- some other non-linear flow, skip all pages in this flow
|
||||
test_page = test_page + self:getTotalPagesInFlow(test_page_flow)
|
||||
else
|
||||
-- went beyond the last page
|
||||
break
|
||||
end
|
||||
end
|
||||
return 0
|
||||
else
|
||||
return Document.getNextPage(self, page)
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:getPrevPage(page)
|
||||
if self:hasHiddenFlows() then
|
||||
if page < 0 or page > self:getPageCount() then
|
||||
return 0
|
||||
elseif page == 0 then
|
||||
return self:getLastLinearPage()
|
||||
end
|
||||
local flow = self:getPageFlow(page)
|
||||
local start_page = page - 1
|
||||
local end_page = self:getFirstPageInFlow(0)
|
||||
local test_page = start_page
|
||||
-- min to ensure at least one iteration
|
||||
-- (in case the current flow goes before all linear pages)
|
||||
while test_page >= math.min(end_page, start_page) do
|
||||
local test_page_flow = self:getPageFlow(test_page)
|
||||
if test_page_flow == flow or test_page_flow == 0 then
|
||||
-- same flow as current, or linear flow, this is a "good" page
|
||||
return test_page
|
||||
elseif test_page_flow > 0 then
|
||||
-- some other non-linear flow, skip all pages in this flow
|
||||
test_page = self:getFirstPageInFlow(test_page_flow) - 1
|
||||
else
|
||||
-- went beyond the first page
|
||||
break
|
||||
end
|
||||
end
|
||||
return 0
|
||||
else
|
||||
return Document.getPrevPage(self, page)
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:getPageFlow(page)
|
||||
-- Only report non-linear pages if "hide_nonlinear_flows" is enabled, and in 1-page mode,
|
||||
-- otherwise all pages are linear (flow 0)
|
||||
if self.hide_nonlinear_flows and self._view_mode == self.PAGE_VIEW_MODE and self:getVisiblePageCount() == 1 then
|
||||
return self._document:getPageFlow(page)
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:getLastLinearPage()
|
||||
return self.last_linear_page
|
||||
end
|
||||
|
||||
function CreDocument:getFirstPageInFlow(flow)
|
||||
return self.flows[flow][1]
|
||||
end
|
||||
|
||||
function CreDocument:getTotalPagesInFlow(flow)
|
||||
return self.flows[flow][2]
|
||||
end
|
||||
|
||||
function CreDocument:getPageNumberInFlow(page)
|
||||
if self:hasHiddenFlows() then
|
||||
return self.page_in_flow[page]
|
||||
else
|
||||
return page
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:cacheFlows()
|
||||
-- Build the cache tables "flows" and "page_in_flow", if there are
|
||||
-- any non-linear flows in the source document. Also set the value
|
||||
-- of "last_linear_page", to possibly speed up counting in documents
|
||||
-- with many non-linear pages at the end.
|
||||
-- flows[i] contains {ini, num}, where ini is the first page in flow i,
|
||||
-- and num is the total number of pages in the flow.
|
||||
-- page_in_flow[i] contains the number of page i with its flow.
|
||||
--
|
||||
-- So, flows[0][1] is the first page in the linear flow,
|
||||
-- and page_in_flow[flows[0][1]] must be 1, because it is the first
|
||||
self.flows = {}
|
||||
self.page_in_flow = {}
|
||||
if self:hasNonLinearFlows() and self.hide_nonlinear_flows then
|
||||
for i=1,self:getPageCount() do
|
||||
local flow = self:getPageFlow(i)
|
||||
if self.flows[flow] ~= nil then
|
||||
self.flows[flow][2] = self.flows[flow][2]+1
|
||||
else
|
||||
self.flows[flow] = {i, 1}
|
||||
end
|
||||
self.page_in_flow[i] = self.flows[flow][2]
|
||||
if flow == 0 then
|
||||
self.last_linear_page = i
|
||||
end
|
||||
end
|
||||
else
|
||||
self.last_linear_page = self:getPageCount()
|
||||
self.flows[0] = {1, self.last_linear_page}
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:getTotalPagesLeft(page)
|
||||
if self:hasHiddenFlows() then
|
||||
local pages_left
|
||||
local last_linear = self:getLastLinearPage()
|
||||
if page > last_linear then
|
||||
-- If beyond the last linear page, count only the pages in the current flow
|
||||
local flow = self:getPageFlow(page)
|
||||
pages_left = self:getTotalPagesInFlow(flow) - self:getPageNumberInFlow(page)
|
||||
else
|
||||
-- Otherwise, count all pages until the last linear,
|
||||
-- except the flows that start (and end) between
|
||||
-- the current page and the last linear
|
||||
pages_left = last_linear - page
|
||||
for flow, tab in ipairs(self.flows) do
|
||||
-- tab[1] is the initial page of the flow
|
||||
-- tab[2] is the total number of pages in the flow
|
||||
if tab[1] > last_linear then
|
||||
break
|
||||
end
|
||||
-- strict >, to make sure we include pages in the current flow
|
||||
if tab[1] > page then
|
||||
pages_left = pages_left - tab[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
return pages_left
|
||||
else
|
||||
return Document.getTotalPagesLeft(self, page)
|
||||
end
|
||||
end
|
||||
|
||||
function CreDocument:getCoverPageImage()
|
||||
-- no need to render document in order to get cover image
|
||||
if not self:loadDocument() then
|
||||
@@ -578,7 +761,7 @@ function CreDocument:gotoPos(pos)
|
||||
end
|
||||
|
||||
function CreDocument:gotoPage(page)
|
||||
logger.dbg("CreDocument: goto page", page)
|
||||
logger.dbg("CreDocument: goto page", page, "flow", self:getPageFlow(page))
|
||||
self._document:gotoPage(page)
|
||||
end
|
||||
|
||||
@@ -766,6 +949,9 @@ function CreDocument:setViewMode(new_mode)
|
||||
self._view_mode = self.PAGE_VIEW_MODE
|
||||
end
|
||||
self._document:setViewMode(self._view_mode)
|
||||
if self.hide_nonlinear_flows then
|
||||
self:cacheFlows()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1272,6 +1458,7 @@ function CreDocument:setupCallCache()
|
||||
elseif name:sub(1,6) == "enable" then add_reset = true
|
||||
elseif name == "zoomFont" then add_reset = true -- not used by koreader
|
||||
elseif name == "resetCallCache" then add_reset = true
|
||||
elseif name == "cacheFlows" then add_reset = true
|
||||
|
||||
-- These may have crengine do native highlight or unhighlight
|
||||
-- (we could keep the original buffer and use a scratch buffer while
|
||||
@@ -1313,6 +1500,11 @@ function CreDocument:setupCallCache()
|
||||
elseif name == "getCacheFilePath" then no_wrap = true
|
||||
elseif name == "getStatistics" then no_wrap = true
|
||||
elseif name == "getNormalizedXPointer" then no_wrap = true
|
||||
elseif name == "getNextPage" then no_wrap = true
|
||||
elseif name == "getPrevPage" then no_wrap = true
|
||||
elseif name == "getPageFlow" then no_wrap = true
|
||||
elseif name == "getPageNumberInFlow" then no_wrap = true
|
||||
elseif name == "getTotalPagesLeft" then no_wrap = true
|
||||
|
||||
-- Some get* have different results by page/pos
|
||||
elseif name == "getLinkFromPosition" then cache_by_tag = true
|
||||
|
||||
Reference in New Issue
Block a user