bump crengine, show progress meter on load/re-rendering (#5406)

Includes:
- Adds tinyNodeCollection::getStatistics()
- epubfmt.cpp: cleanup indentation and small optimisation
- Add more progress callback events
- Optimisation: avoid re-init for EPUBs with embedded fonts
- Fix: don't draw border when border-color: transparent
- CSS: ignore 'inherit' inside font-family

Show a small progress meter at top left of screen when
crengine is loading, re-rendering, and saving cache file
(after a 2 second delay to not be bothered on small books).

Also add a wrapper for the last remaining bit of code that
was accessing _document directly (:getPageOffsetX()).
pull/5407/head
poire-z 5 years ago committed by GitHub
parent e2c771dd2d
commit 5bc6bf046c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1 +1 @@
Subproject commit b9d95c73718fde01f02b4b9200fc36ea8ddc8e9c
Subproject commit 0019d032c8993b47ab25b4f66a028149da824794

@ -1,11 +1,13 @@
local bit = require("bit")
local Blitbuffer = require("ffi/blitbuffer")
local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device")
local InputContainer = require("ui/widget/container/inputcontainer")
local Event = require("ui/event")
local InputContainer = require("ui/widget/container/inputcontainer")
local ProgressWidget = require("ui/widget/progresswidget")
local ReaderPanning = require("apps/reader/modules/readerpanning")
local TimeVal = require("ui/timeval")
local UIManager = require("ui/uimanager")
local bit = require("bit")
local logger = require("logger")
local _ = require("gettext")
local Screen = Device.screen
@ -203,6 +205,19 @@ function ReaderRolling:onReadSettings(config)
self.visible_pages = config:readSetting("visible_pages") or
G_reader_settings:readSetting("copt_visible_pages") or 1
self.ui.document:setVisiblePageCount(self.visible_pages)
-- Set a callback to allow showing load and rendering progress
-- (this callback will be cleaned up by cre.cpp closeDocument(),
-- no need to handle it in :onCloseDocument() here.)
self.ui.document:setCallback(function(...)
-- Catch and log any error happening in handleCallback(),
-- as otherwise it would just silently abort (but beware
-- having errors, this may flood crash.log)
local ok, err = xpcall(self.handleEngineCallback, debug.traceback, self, ...)
if not ok then
logger.warn("cre callback() error:", err)
end
end)
end
-- in scroll mode percent_finished must be save before close document
@ -582,7 +597,7 @@ function ReaderRolling:onGotoXPointer(xp, marker_xp)
-- This is a bit tricky with how the middle margin is sized
-- by crengine (see LVDocView::updateLayout() in lvdocview.cpp)
screen_x = Screen:getWidth() / 2
local page2_x = self.ui.document._document:getPageOffsetX(self.ui.document:getCurrentPage()+1)
local page2_x = self.ui.document:getPageOffsetX(self.ui.document:getCurrentPage()+1)
marker_w = page2_x + marker_w - screen_x
else
screen_x = 0
@ -922,4 +937,95 @@ function ReaderRolling:updateBatteryState()
end
end
function ReaderRolling:handleEngineCallback(ev, ...)
local args = {...}
-- logger.info("handleCallback: got", ev, args and #args > 0 and args[1] or nil)
if ev == "OnLoadFileStart" then -- Start of book loading
self:showEngineProgress(0) -- Start initial delay countdown
elseif ev == "OnLoadFileProgress" then
-- Initial load from file (step 1/2) or from cache (step 1/1)
self:showEngineProgress(args[1]/100/2)
elseif ev == "OnNodeStylesUpdateStart" then -- Start of re-rendering
self:showEngineProgress(0) -- Start initial delay countdown
elseif ev == "OnNodeStylesUpdateProgress" then
-- Update node styles (step 1/2 on re-rendering)
self:showEngineProgress(args[1]/100/2)
elseif ev == "OnFormatStart" then -- Start of step 2/2
self:showEngineProgress(1/2) -- 50%, in case of no OnFormatProgress
elseif ev == "OnFormatProgress" then
-- Paragraph formatting and page splitting (step 2/2 after load
-- from file, step 2/2 on re-rendering)
self:showEngineProgress(1/2 + args[1]/100/2)
elseif ev == "OnSaveCacheFileStart" then -- Start of cache file save
self:showEngineProgress(1) -- Start initial delay countdown, fully filled
elseif ev == "OnSaveCacheFileProgress" then
-- Cache file save (when closing book after initial load from
-- file or re-rendering)
self:showEngineProgress(1 - args[1]/100) -- unfill progress
elseif ev == "OnDocumentReady" or ev == "OnSaveCacheFileEnd" then
self:showEngineProgress() -- cleanup
elseif ev == "OnLoadFileError" then
logger.warn("Cre error loading file:", args[1])
end
-- ignore other events
end
local ENGINE_PROGRESS_INITIAL_DELAY = TimeVal:new{ sec = 2 }
local ENGINE_PROGRESS_UPDATE_DELAY = TimeVal:new{ usec = 500000 }
function ReaderRolling:showEngineProgress(percent)
if G_reader_settings:isFalse("cre_show_progress") then
-- This may slow things down too much with SDL over SSH,
-- so allow disabling it.
return
end
if percent then
local now = TimeVal:now()
if self.engine_progress_update_not_before and now < self.engine_progress_update_not_before then
return
end
if not self.engine_progress_update_not_before then
-- Start showing the progress widget only if load or re-rendering
-- have not yet finished after 2 seconds
self.engine_progress_update_not_before = now + ENGINE_PROGRESS_INITIAL_DELAY
return
end
-- Widget size and position: best to anchor it at top left,
-- so it does not override the footer or a bookmark dogear
local x = 0
local y = 0
local w = Screen:getWidth() / 3
local h = Screen:scaleBySize(5)
if self.engine_progress_widget then
self.engine_progress_widget:setPercentage(percent)
else
self.engine_progress_widget = ProgressWidget:new{
width = w,
height = h,
percentage = percent,
margin_h = 0,
margin_v = 0,
radius = 0,
-- Show a tick at 50% (below is loading, after is rendering)
tick_width = Screen:scaleBySize(1),
ticks = {1,2},
last = 2,
}
end
-- Paint directly to the screen and force a regional refresh
-- as UIManager won't get a change to run until loading/rendering
-- is finished.
self.engine_progress_widget:paintTo(Screen.bb, x, y)
Screen["refreshFast"](Screen, x, y, w, h)
self.engine_progress_update_not_before = now + ENGINE_PROGRESS_UPDATE_DELAY
else
-- Done: cleanup
self.engine_progress_widget = nil
self.engine_progress_update_not_before = nil
-- No need for any paint/refresh: any action we got
-- some progress callback for will generate a full
-- screen refresh.
end
end
return ReaderRolling

@ -435,6 +435,10 @@ function CreDocument:getPageFromXPointer(xp)
return self._document:getPageFromXPointer(xp)
end
function CreDocument:getPageOffsetX(page)
return self._document:getPageOffsetX(page)
end
function CreDocument:getScreenPositionFromXPointer(xp)
-- We do not ensure xp is in the current page: we may return
-- a negative screen_y, which could be useful in some contexts
@ -806,6 +810,10 @@ function CreDocument:enableInternalHistory(toggle)
self._document:setIntProperty("crengine.highlight.bookmarks", toggle and 2 or 0)
end
function CreDocument:setCallback(func)
return self._document:setCallback(func)
end
function CreDocument:isBuiltDomStale()
return self._document:isBuiltDomStale()
end
@ -822,6 +830,10 @@ function CreDocument:getCacheFilePath()
return self._document:getCacheFilePath()
end
function CreDocument:getStatistics()
return self._document:getStatistics()
end
function CreDocument:canHaveAlternativeToc()
return true
end

Loading…
Cancel
Save