From 93abd2fee73107adbee9fc09c27b1945ae422887 Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sat, 22 Dec 2012 13:27:46 +0800 Subject: [PATCH] add page status to readerrolling for better page view_mode support * now when rendering in page view mode, we only keep track of page number instead of pos inside document. Because using pos inside document for page view mode is really a bad idea and will lead to many unsovlabe bugs... --- frontend/document/credocument.lua | 58 +++++++++++++++++++++--- frontend/document/document.lua | 7 --- frontend/ui/reader/readerfont.lua | 3 ++ frontend/ui/reader/readerrolling.lua | 66 +++++++++++++++++++++------- frontend/ui/reader/readerview.lua | 23 +++++++--- 5 files changed, 122 insertions(+), 35 deletions(-) diff --git a/frontend/document/credocument.lua b/frontend/document/credocument.lua index 9fae1bf89..44360990b 100644 --- a/frontend/document/credocument.lua +++ b/frontend/document/credocument.lua @@ -10,7 +10,6 @@ CreDocument = Document:new{ line_space_percent = 100, default_font = "Droid Sans Fallback", - view_mode = "page", } -- NuPogodi, 20.05.12: inspect the zipfile content @@ -73,13 +72,10 @@ function CreDocument:init() end local style_sheet = "./data/"..file_type..".css" - -- view_mode default to page mode - local view_mode = self.PAGE_VIEW_MODE - if self.view_mode == "scroll" then - view_mode = self.SCROLL_VIEW_MODE - end + -- @TODO check the default view_mode to a global user configurable + -- variable 22.12 2012 (houqp) ok, self._document = pcall(cre.openDocument, self.file, style_sheet, - Screen:getWidth(), Screen:getHeight(), view_mode) + Screen:getWidth(), Screen:getHeight(), self.PAGE_VIEW_MODE) if not ok then self.error_message = self.doc -- will contain error message return @@ -92,6 +88,22 @@ function CreDocument:init() --self._document:setDefaultInterlineSpace(self.line_space_percent) end +function CreDocument:drawCurrentView(target, x, y, rect, pos) + tile_bb = Blitbuffer.new(rect.w, rect.h) + self._document:drawCurrentPage(tile_bb) + target:blitFrom(tile_bb, x, y, 0, 0, rect.w, rect.h) +end + +function CreDocument:drawCurrentViewByPos(target, x, y, rect, pos) + self._document:gotoPos(pos) + self:drawCurrentView(target, x, y, rect) +end + +function CreDocument:drawCurrentViewByPage(target, x, y, rect, page) + self._document:gotoPage(page) + self:drawCurrentView(target, x, y, rect) +end + function CreDocument:hintPage(pageno, zoom, rotation) end @@ -101,10 +113,42 @@ end function CreDocument:renderPage(pageno, rect, zoom, rotation) end +function CreDocument:gotoXPointer(xpointer) + self._document:gotoXPointer(xpointer) +end + +function CreDocument:getXPointer() + return self._document:getXPointer() +end + +function CreDocument:getPosFromXPointer(xp) + return self._document:getPosFromXPointer(xp) +end + +function CreDocument:getPageFromXPointer(xp) + return self._document:getPageFromXPointer(xp) +end + function CreDocument:getFontFace() return self._document:getFontFace() end +function CreDocument:getCurrentPos() + return self._document:getCurrentPos() +end + +function Document:gotoPos(pos) + self._document:gotoPos(pos) +end + +function CreDocument:gotoPage(page) + self._document:gotoPage(page) +end + +function CreDocument:getCurrentPage() + return self._document:getCurrentPage() +end + function CreDocument:setFontFace(new_font_face) if new_font_face then self._document:setFontFace(new_font_face) diff --git a/frontend/document/document.lua b/frontend/document/document.lua index fca96135b..715dc34d9 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -234,13 +234,6 @@ function Document:drawPage(target, x, y, rect, pageno, zoom, rotation, render_mo rect.w, rect.h) end -function Document:drawCurrentView(target, x, y, rect, pos) - self._document:gotoPos(pos) - tile_bb = Blitbuffer.new(rect.w, rect.h) - self._document:drawCurrentPage(tile_bb) - target:blitFrom(tile_bb, x, y, 0, 0, rect.w, rect.h) -end - function Document:getPageText(pageno) -- is this worth caching? not done yet. local page = self._document:openPage(pageno) diff --git a/frontend/ui/reader/readerfont.lua b/frontend/ui/reader/readerfont.lua index 4adc1c77a..b4e228fb0 100644 --- a/frontend/ui/reader/readerfont.lua +++ b/frontend/ui/reader/readerfont.lua @@ -92,6 +92,9 @@ function ReaderFont:onShowFontMenu() return true end +--[[ + UpdatePos event is used to tell ReaderRolling to update pos. +--]] function ReaderFont:onChangeSize(direction) local delta = 1 if direction == "decrease" then diff --git a/frontend/ui/reader/readerrolling.lua b/frontend/ui/reader/readerrolling.lua index 193a88e26..caca7691a 100644 --- a/frontend/ui/reader/readerrolling.lua +++ b/frontend/ui/reader/readerrolling.lua @@ -2,7 +2,10 @@ require "ui/reader/readerpanning" ReaderRolling = InputContainer:new{ old_doc_height = nil, + view_mode = "page", current_pos = 0, + -- only used for page view mode + current_page= nil, doc_height = nil, panning_steps = ReaderPanning.panning_steps, show_overlap_enable = true, @@ -90,11 +93,18 @@ function ReaderRolling:onReadSettings(config) self.show_overlap_enable = soe end self:gotoPercent(config:readSetting("last_percent") or 0) + -- we have to do a real pos change in self.ui.document._document to + -- update status information in CREngine. + self.ui.document:gotoPos(self.current_pos) + if self.view_mode == "page" then + self.ui:handleEvent(Event:new("PageUpdate", self.ui.document:getCurrentPage())) + end end function ReaderRolling:onCloseDocument() + local cur_xp = self.ui.document:getXPointer() self.ui.doc_settings:saveSetting("last_percent", - 10000 * self.current_pos / self.doc_height) + 10000 * self.ui.document:getPosFromXPointer(cur_xp) / self.doc_height) end function ReaderRolling:onTapForward() @@ -111,6 +121,10 @@ function ReaderRolling:onPosUpdate(new_pos) self.current_pos = new_pos end +function ReaderRolling:onPageUpdate(new_page) + self.current_page = new_page +end + function ReaderRolling:onGotoPercent(percent) DEBUG("goto document offset in percent:", percent) self:gotoPercent(percent) @@ -119,19 +133,24 @@ end function ReaderRolling:onGotoViewRel(diff) DEBUG("goto relative screen:", diff) - local pan_diff = diff * self.ui.dimen.h - if self.ui.document.view_mode ~= "page" and self.show_overlap_enable then - if pan_diff > self.overlap then - pan_diff = pan_diff - self.overlap - elseif pan_diff < -self.overlap then - pan_diff = pan_diff + self.overlap + if self.ui.document.view_mode ~= "page" then + local pan_diff = diff * self.ui.dimen.h + if self.show_overlap_enable then + if pan_diff > self.overlap then + pan_diff = pan_diff - self.overlap + elseif pan_diff < -self.overlap then + pan_diff = pan_diff + self.overlap + end end + self:gotoPos(self.current_pos + pan_diff) + else + self:gotoPage(self.current_page + diff) end - self:gotoPos(self.current_pos + pan_diff) return true end function ReaderRolling:onPanning(args, key) + --@TODO disable panning in page view_mode? 22.12 2012 (houqp) local _, dy = unpack(args) DEBUG("key =", key) self:gotoPos(self.current_pos + dy * self.panning_steps.normal) @@ -143,21 +162,25 @@ function ReaderRolling:onZoom() self:onUpdatePos() end --- remember to signal this event the document has been zoomed, --- font has been changed, or line height has been changed. +--[[ + remember to signal this event the document has been zoomed, + font has been changed, or line height has been changed. +--]] function ReaderRolling:onUpdatePos() -- reread document height self.ui.document:_readMetadata() -- update self.current_pos if the height of document has been changed. - if self.old_doc_height ~= self.ui.document.info.doc_height then - self:gotoPos(self.current_pos * - (self.ui.document.info.doc_height - self.dialog.dimen.h) / - (self.old_doc_height - self.dialog.dimen.h)) - self.old_doc_height = self.ui.document.info.doc_height + local new_height = self.ui.document.info.doc_height + if self.old_doc_height ~= new_height then + self:gotoXPointer(self.ui.document:getXPointer()) + self.old_doc_height = new_height end return true end +--[[ + PosUpdate event is used to signal other widgets that pos has been changed. +--]] function ReaderRolling:gotoPos(new_pos) if new_pos == self.current_pos then return end if new_pos < 0 then new_pos = 0 end @@ -177,6 +200,19 @@ function ReaderRolling:gotoPos(new_pos) self.ui:handleEvent(Event:new("PosUpdate", new_pos)) end +function ReaderRolling:gotoPage(new_page) + self.ui.document:gotoPage(new_page) + self.ui:handleEvent(Event:new("PageUpdate", new_page)) +end + +function ReaderRolling:gotoXPointer(xpointer) + if self.view_mode == "page" then + self:gotoPage(self.ui.document:getPageFromXPointer(xpointer)) + else + self:gotoPos(self.ui.document:getPosFromXPointer(xpointer)) + end +end + function ReaderRolling:gotoPercent(new_percent) self:gotoPos(new_percent * self.doc_height / 10000) end diff --git a/frontend/ui/reader/readerview.lua b/frontend/ui/reader/readerview.lua index e6d4ed2a1..cfe995d58 100644 --- a/frontend/ui/reader/readerview.lua +++ b/frontend/ui/reader/readerview.lua @@ -12,6 +12,8 @@ ReaderView = WidgetContainer:new{ outer_page_color = 7, -- DjVu page rendering mode (used in djvu.c:drawPage()) render_mode = 0, -- default to COLOR + -- Crengine view mode + view_mode = "page", -- default to page mode -- visible area within current viewing page visible_area = Geom:new{x = 0, y = 0}, @@ -49,12 +51,21 @@ function ReaderView:paintTo(bb, x, y) self.state.rotation, self.render_mode) else - self.ui.document:drawCurrentView( - bb, - x + inner_offset.x, - y + inner_offset.y, - self.visible_area, - self.state.pos) + if self.view_mode == "page" then + self.ui.document:drawCurrentViewByPage( + bb, + x + inner_offset.x, + y + inner_offset.y, + self.visible_area, + self.state.page) + else + self.ui.document:drawCurrentViewByPos( + bb, + x + inner_offset.x, + y + inner_offset.y, + self.visible_area, + self.state.pos) + end end -- dim last read area if self.document.view_mode ~= "page"