Merge pull request #787 from chrox/background_hint

add background hinting in koptinterface
pull/2/merge
{Qingping,Dave} Hou 11 years ago
commit e488b9ae16

@ -80,6 +80,14 @@ function DjvuDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mod
end
end
function DjvuDocument:hintPage(pageno, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then
self.koptinterface:hintPage(self, pageno, zoom, rotation, gamma, render_mode)
else
Document.hintPage(self, pageno, zoom, rotation, gamma, render_mode)
end
end
function DjvuDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then
self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode)

@ -195,10 +195,38 @@ KoptOptions = {
},
}
KoptInterface = {}
KoptInterface = {
bg_context = {
contex = nil,
pageno = nil,
hash = nil,
cached = false,
},
}
function KoptInterface:waitForContext(kc)
-- if koptcontext is being processed in background thread
-- the isPreCache will return 1.
while kc and kc:isPreCache() == 1 do
DEBUG("waiting for background rendering")
util.usleep(100000)
end
end
function KoptInterface:consumeBgContext(doc)
-- clear up background context
self:waitForContext(self.bg_context.context)
if self.bg_context.context and not self.bg_context.cached then
self:makeCache(doc, self.bg_context.pageno, self.bg_context.hash)
self.bg_context.cached = true
end
end
-- get reflow context
function KoptInterface:getKOPTContext(doc, pageno, bbox)
-- since libk2pdfopt only has one bitmap buffer that holds reflowed page
-- we should consume background production before allocating new context.
self:consumeBgContext(doc)
local kc = KOPTContext.new()
local screen_size = Screen:getSize()
kc:setTrim(doc.configurable.trim_page)
@ -222,6 +250,7 @@ function KoptInterface:getKOPTContext(doc, pageno, bbox)
end
function KoptInterface:setTrimPage(doc, pageno)
if doc.configurable.trim_page == 0 then return end
local page_dimens = doc:getNativePageDimensions(pageno)
--DEBUG("original page dimens", page_dimens)
local orig_bbox = doc:getUsedBBox(pageno)
@ -251,6 +280,11 @@ function KoptInterface:logReflowDuration(pageno, dur)
end
end
function KoptInterface:getReflowedDim(kc)
self:waitForContext(kc)
return kc:getPageDim()
end
-- calculates page dimensions
function KoptInterface:getPageDimensions(doc, pageno, zoom, rotation)
self:setTrimPage(doc, pageno)
@ -277,11 +311,37 @@ function KoptInterface:getPageDimensions(doc, pageno, zoom, rotation)
return page_size
end
--DEBUG("Found cached koptcontex on page", pageno, cached)
local fullwidth, fullheight = cached.kctx:getPageDim()
local fullwidth, fullheight = self:getReflowedDim(cached.kctx)
local page_size = Geom:new{ w = fullwidth, h = fullheight }
return page_size
end
function KoptInterface:makeCache(doc, pageno, context_hash)
-- draw to blitbuffer
local kc_hash = "kctx|"..context_hash
local tile_hash = "renderpg|"..context_hash
local page = doc._document:openPage(pageno)
local cached = Cache:check(kc_hash)
if cached then
local fullwidth, fullheight = self:getReflowedDim(cached.kctx)
-- prepare cache item with contained blitbuffer
local tile = CacheItem:new{
size = fullwidth * fullheight / 2 + 64, -- estimation
excerpt = Geom:new{ w = fullwidth, h = fullheight },
pageno = pageno,
bb = Blitbuffer.new(fullwidth, fullheight)
}
page:rfdraw(cached.kctx, tile.bb)
page:close()
--DEBUG("cached hash", hash)
if not Cache:check(tile_hash) then
Cache:insert(tile_hash, tile)
end
return tile
end
DEBUG("Error: cannot render page before reflowing.")
end
function KoptInterface:renderPage(doc, pageno, rect, zoom, rotation, render_mode)
self:setTrimPage(doc, pageno)
doc.render_mode = render_mode
@ -307,30 +367,33 @@ function KoptInterface:renderPage(doc, pageno, rect, zoom, rotation, render_mode
end
local cached = Cache:check(hash)
if cached then return cached end
-- prepare cache item with contained blitbuffer
local tile = CacheItem:new{
size = size.w * size.h / 2 + 64, -- estimation
excerpt = size,
pageno = pageno,
bb = Blitbuffer.new(size.w, size.h)
}
-- draw to blitbuffer
local kc_hash = "kctx|"..context_hash
local page = doc._document:openPage(pageno)
local cached = Cache:check(kc_hash)
if cached then
page:rfdraw(cached.kctx, tile.bb)
return cached
else
return self:makeCache(doc, pageno, context_hash)
end
end
function KoptInterface:hintPage(doc, pageno, zoom, rotation, gamma, render_mode)
self:setTrimPage(doc, pageno)
local bbox = doc:getPageBBox(pageno)
local context_hash = self:getContextHash(doc, pageno, bbox)
local hash = "kctx|"..context_hash
local cached = Cache:check(hash)
if not cached then
local kc = self:getKOPTContext(doc, pageno, bbox)
local page = doc._document:openPage(pageno)
kc:setPreCache()
self.bg_context.context = kc
self.bg_context.pageno = pageno
self.bg_context.hash = context_hash
self.bg_context.cached = false
DEBUG("hinting page", pageno, "in background")
-- will return immediately
page:reflow(kc, 0)
page:close()
--DEBUG("cached hash", hash)
if not Cache:check(hash) then
Cache:insert(hash, tile)
end
return tile
Cache:insert(hash, CacheItem:new{ kctx = kc })
end
DEBUG("Error: cannot render page before reflowing.")
end
function KoptInterface:drawPage(doc, target, x, y, rect, pageno, zoom, rotation, render_mode)

@ -82,6 +82,14 @@ function PdfDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode
end
end
function PdfDocument:hintPage(pageno, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then
self.koptinterface:hintPage(self, pageno, zoom, rotation, gamma, render_mode)
else
Document.hintPage(self, pageno, zoom, rotation, gamma, render_mode)
end
end
function PdfDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
if self.configurable.text_wrap == 1 then
self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, render_mode)

@ -82,8 +82,11 @@ function ReaderConfig:onShowConfigMenu()
ui = self.ui,
configurable = self.configurable,
config_options = self.options,
close_callback = function()
self.ui:handleEvent(Event:new("RestoreHinting"))
end,
}
self.ui:handleEvent(Event:new("DisableHinting"))
UIManager:show(self.config_dialog)
return true

@ -63,6 +63,8 @@ function ReaderCropping:onPageCrop(mode)
-- backup original page scroll
self.orig_page_scroll = self.view.page_scroll
self.view.page_scroll = false
-- backup and disable original hinting state
self.ui:handleEvent(Event:new("DisableHinting"))
-- backup original reflow mode as cropping use non-reflow mode
self.orig_reflow_mode = self.document.configurable.text_wrap
if self.orig_reflow_mode == 1 then
@ -110,6 +112,8 @@ function ReaderCropping:onCancelPageCrop()
end
function ReaderCropping:exitPageCrop(confirmed)
-- restore hinting state
self.ui:handleEvent(Event:new("RestoreHinting"))
-- restore page scroll
self.view.page_scroll = self.orig_page_scroll
-- restore view bgcolor

@ -0,0 +1,19 @@
ReaderHinting = EventListener:new{
hinting_states = {}
}
function ReaderHinting:onSetHinting(hinting)
self.view.hinting = hinting
end
function ReaderHinting:onDisableHinting()
table.insert(self.hinting_states, self.view.hinting)
self.view.hinting = false
return true
end
function ReaderHinting:onRestoreHinting()
self.view.hinting = table.remove(self.hinting_states)
return true
end

@ -143,6 +143,7 @@ function ReaderPaging:onToggleFlipping()
if self.flipping_mode then
self:updateOriginalPage(self.current_page)
end
self.ui:handleEvent(Event:new("SetHinting", not self.flipping_mode))
UIManager:setDirty(self.view.dialog, "partial")
end

@ -31,7 +31,8 @@ ReaderView = OverlapGroup:new{
render_mode = 0, -- default to COLOR
-- Crengine view mode
view_mode = "page", -- default to page mode
hinting = true,
-- visible area within current viewing page
visible_area = Geom:new{x = 0, y = 0},
-- dimen for current viewing page
@ -148,7 +149,9 @@ function ReaderView:drawScrollPages(bb, x, y)
pos.y = pos.y + self.page_gap.height
end
end
UIManager:scheduleIn(0, function() self.ui:handleEvent(Event:new("HintPage")) end)
UIManager:scheduleIn(0, function()
self.ui:handleEvent(Event:new("HintPage", self.hinting))
end)
end
function ReaderView:drawPageGap(bb, x, y)
@ -170,7 +173,9 @@ function ReaderView:drawSinglePage(bb, x, y)
self.state.rotation,
self.state.gamma,
self.render_mode)
UIManager:scheduleIn(0, function() self.ui:handleEvent(Event:new("HintPage")) end)
UIManager:scheduleIn(0, function()
self.ui:handleEvent(Event:new("HintPage", self.hinting))
end)
end
function ReaderView:drawPageView(bb, x, y)

@ -110,6 +110,7 @@ function ReaderZooming:onPageUpdate(new_page_no)
end
function ReaderZooming:onHintPage()
if not self.view.hinting then return true end
if self.current_page < self.ui.document.info.number_of_pages then
self.ui.document:hintPage(
self.view.state.page + 1,

@ -15,6 +15,7 @@ require "ui/reader/readercropping"
require "ui/reader/readerkopt"
require "ui/reader/readercopt"
require "ui/reader/readerscreenshot"
require "ui/reader/readerhinting"
--[[
This is an abstraction for a reader interface
@ -132,6 +133,14 @@ function ReaderUI:init()
document = self.document,
}
table.insert(self, cropper)
-- hinting controller
local hinter = ReaderHinting:new{
dialog = self.dialog,
view = self[1],
ui = self,
document = self.document,
}
table.insert(self, hinter)
else
-- make sure we load document first before calling any callback
table.insert(self.postInitCallback, function()

Loading…
Cancel
Save