From c13677320344be69e674dfe8686c6a81bdc19133 Mon Sep 17 00:00:00 2001 From: HW Date: Sun, 27 May 2012 18:23:01 +0200 Subject: [PATCH 1/5] some minor changes to avoid long access paths into tables --- frontend/ui/dialog.lua | 77 ++++++++++++++++++++++-------------------- frontend/ui/widget.lua | 7 ++++ 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/frontend/ui/dialog.lua b/frontend/ui/dialog.lua index 19e9a4450..f92d35a64 100644 --- a/frontend/ui/dialog.lua +++ b/frontend/ui/dialog.lua @@ -323,6 +323,7 @@ MenuItem = WidgetContainer:new{ height = nil, shortcut = nil, shortcut_style = "square", + _underline_container = nil } function MenuItem:init() @@ -345,6 +346,20 @@ function MenuItem:init() self.content_width - indicator_w, true) .. indicator end + self._underline_container = UnderlineContainer:new{ + dimen = { + w = self.content_width, + h = self.height + }, + HorizontalGroup:new { + align = "center", + TextWidget:new{ + text = self.text, + face = self.face, + }, + }, + } + self[1] = HorizontalGroup:new{ HorizontalSpan:new{ width = 5 }, ItemShortCutIcon:new{ @@ -355,29 +370,17 @@ function MenuItem:init() style = self.shortcut_style, }, HorizontalSpan:new{ width = 10 }, - UnderlineContainer:new{ - dimen = { - w = self.content_width, - h = self.height - }, - HorizontalGroup:new { - align = "center", - TextWidget:new{ - text = self.text, - face = self.face, - }, - }, - }, + self._underline_container } end function MenuItem:onFocus() - self[1][4].color = 10 + self._underline_container.color = 10 return true end function MenuItem:onUnfocus() - self[1][4].color = 0 + self._underline_container.color = 0 return true end @@ -418,6 +421,9 @@ Menu = FocusManager:new{ page = 1, on_select_callback = function() end, + + item_group = nil, + page_info = nil, } function Menu:init() @@ -426,6 +432,7 @@ function Menu:init() self.page = 1 self.page_num = math.ceil(self.items / self.perpage) + -- set up keyboard events self.key_events.Close = { {"Back"}, doc = "close menu" } self.key_events.Select = { {"Press"}, doc = "chose selected item" } self.key_events.NextPage = { @@ -434,13 +441,21 @@ function Menu:init() self.key_events.PrevPage = { {Input.group.PgBack}, doc = "goto previous page of the menu" } + -- we won't catch presses to "Right" self.key_events.FocusRight = nil + -- rather, we reserve that key for showing details self.key_events.ShowItemDetail = { {"Right"}, doc = "show item detail" } if self.is_enable_shortcut then self.key_events.SelectByShortCut = { {self.item_shortcuts} } end self.key_events.Select = { {"Press"}, doc = "select current menu item"} + -- group for items + self.item_group = VerticalGroup:new{} + self.page_info = TextWidget:new{ + face = self.fface, + } + self[1] = CenterContainer:new{ FrameContainer:new{ background = 0, @@ -450,13 +465,8 @@ function Menu:init() text = self.title, face = self.tface, }, - -- group for items - VerticalGroup:new{ - }, - TextWidget:new{ - text = "page "..self.page.."/"..self.page_num, - face = self.fface, - }, + self.item_group, + self.page_info, }, -- VerticalGroup }, -- FrameContainer dimen = {w = G_width, h = G_height}, @@ -467,11 +477,7 @@ end function Menu:_updateItems() self.layout = {} - self[1] - [1] -- FrameContainer - [1] -- VerticalGroup - [2] = VerticalGroup:new{} - local item_group = self[1][1][1][2] + self.item_group:clear() for c = 1, self.perpage do local i = (self.page - 1) * self.perpage + c @@ -498,13 +504,17 @@ function Menu:_updateItems() shortcut = item_shortcut, shortcut_style = shortcut_style, } - table.insert(item_group, item_tmp) + table.insert(self.item_group, item_tmp) table.insert(self.layout, {item_tmp}) --self.last_shortcut = c end -- if i <= self.items end -- for c=1, self.perpage -- set focus to first menu item - item_group[1]:onFocus() + self.item_group[1]:onFocus() + -- reset focus manager accordingly + self.selected = { x = 1, y = 1 } + -- update page information + self.page_info.text = "page "..self.page.."/"..self.page_num end function Menu:onSelectByShortCut(_, keyevent) @@ -524,11 +534,8 @@ end function Menu:onNextPage() if self.page < self.page_num then - local page_info = self[1][1][1][3] self.page = self.page + 1 self:_updateItems() - self.selected = { x = 1, y = 1 } - self[1][1][1][3].text = "page "..self.page.."/"..self.page_num UIManager:setDirty(self) end return true @@ -536,20 +543,18 @@ end function Menu:onPrevPage() if self.page > 1 then - local page_info = self[1][1][1][3] self.page = self.page - 1 self:_updateItems() - self.selected = { x = 1, y = 1 } - self[1][1][1][3].text = "page "..self.page.."/"..self.page_num UIManager:setDirty(self) end return true end function Menu:onShowItemDetail() - return self.layout[self.selected.y][self.selected.x]:handleEvent( + self.layout[self.selected.y][self.selected.x]:handleEvent( Event:new("ShowDetail") ) + return true end function Menu:onSelect() diff --git a/frontend/ui/widget.lua b/frontend/ui/widget.lua index 5b814dc8f..415d577fe 100644 --- a/frontend/ui/widget.lua +++ b/frontend/ui/widget.lua @@ -63,6 +63,13 @@ function WidgetContainer:getSize() end end +--[[ +delete all child widgets +]]-- +function WidgetContainer:clear() + while table.remove(self) do end +end + function WidgetContainer:paintTo(bb, x, y) -- default to pass request to first child widget if self[1] then From ca3247320fb05c5818c8f0c287fbe1f9dd229a30 Mon Sep 17 00:00:00 2001 From: HW Date: Sun, 27 May 2012 23:43:00 +0200 Subject: [PATCH 2/5] first filechooser implementation --- frontend/ui/dialog.lua | 22 ++++++++++--------- frontend/ui/filechooser.lua | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 frontend/ui/filechooser.lua diff --git a/frontend/ui/dialog.lua b/frontend/ui/dialog.lua index f92d35a64..5bdaa088a 100644 --- a/frontend/ui/dialog.lua +++ b/frontend/ui/dialog.lua @@ -409,7 +409,6 @@ Menu = FocusManager:new{ height = 500, width = 500, item_table = {}, - items = 0, item_shortcuts = { "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Del", @@ -427,10 +426,9 @@ Menu = FocusManager:new{ } function Menu:init() - self.items = #self.item_table self.perpage = math.floor(self.height / self.item_height) - 2 self.page = 1 - self.page_num = math.ceil(self.items / self.perpage) + self.page_num = math.ceil(#self.item_table / self.perpage) -- set up keyboard events self.key_events.Close = { {"Back"}, doc = "close menu" } @@ -472,16 +470,20 @@ function Menu:init() dimen = {w = G_width, h = G_height}, } -- CenterContainer - self:_updateItems() + if #self.item_table > 0 then + -- if the table is not yet initialized, this call + -- must be done manually: + self:updateItems() + end end -function Menu:_updateItems() +function Menu:updateItems() self.layout = {} self.item_group:clear() for c = 1, self.perpage do local i = (self.page - 1) * self.perpage + c - if i <= self.items then + if i <= #self.item_table then local item_shortcut = nil local shortcut_style = "square" if self.is_enable_shortcut then @@ -515,6 +517,8 @@ function Menu:_updateItems() self.selected = { x = 1, y = 1 } -- update page information self.page_info.text = "page "..self.page.."/"..self.page_num + + UIManager:setDirty(self) end function Menu:onSelectByShortCut(_, keyevent) @@ -535,8 +539,7 @@ end function Menu:onNextPage() if self.page < self.page_num then self.page = self.page + 1 - self:_updateItems() - UIManager:setDirty(self) + self:updateItems() end return true end @@ -544,8 +547,7 @@ end function Menu:onPrevPage() if self.page > 1 then self.page = self.page - 1 - self:_updateItems() - UIManager:setDirty(self) + self:updateItems() end return true end diff --git a/frontend/ui/filechooser.lua b/frontend/ui/filechooser.lua new file mode 100644 index 000000000..d5740b6b4 --- /dev/null +++ b/frontend/ui/filechooser.lua @@ -0,0 +1,42 @@ +require "ui/dialog" -- for Menu + +FileChooser = Menu:new{ + path = ".", + show_hidden = false, + filter = function(filename) return true end, +} + +function FileChooser:init() + self:changeToPath(self.path) +end + +function FileChooser:changeToPath(path) + local dirs = {} + local files = {} + for f in lfs.dir(self.path) do + if self.show_hidden or not string.match(f, "^%.[^.]") then + local filename = self.path.."/"..f + local filemode = lfs.attributes(filename, "mode") + if filemode == "directory" and f ~= "." and f~=".." then + table.insert(dirs, f) + elseif filemode == "file" then + if self.filter(filename) then + table.insert(files, f) + end + end + end + end + table.sort(dirs) + if self.path ~= "/" then table.insert(dirs, 1, "..") end + table.sort(files) + + self.item_table = {} + for _, dir in ipairs(dirs) do + table.insert(self.item_table, { text = dir.."/" }) + end + for _, file in ipairs(files) do + table.insert(self.item_table, { text = file }) + end + + Menu.init(self) -- call parent's init() +end From 8191cbe8523417aecd1108359845b48577d51167 Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 28 May 2012 00:14:08 +0200 Subject: [PATCH 3/5] some fixes to filechoser and menu --- frontend/ui/dialog.lua | 14 ++++++++------ frontend/ui/filechooser.lua | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/frontend/ui/dialog.lua b/frontend/ui/dialog.lua index 5bdaa088a..6112c18db 100644 --- a/frontend/ui/dialog.lua +++ b/frontend/ui/dialog.lua @@ -315,7 +315,7 @@ end Widget that displays an item for menu ]] -MenuItem = WidgetContainer:new{ +MenuItem = InputContainer:new{ text = nil, detail = nil, face = Font:getFace("cfont", 22), @@ -323,7 +323,12 @@ MenuItem = WidgetContainer:new{ height = nil, shortcut = nil, shortcut_style = "square", - _underline_container = nil + _underline_container = nil, + + key_events = { + Select = { {"Press"}, doc = "chose selected item" }, + ShowItemDetail = { {"Right"}, doc = "show item detail" } + } } function MenuItem:init() @@ -432,7 +437,6 @@ function Menu:init() -- set up keyboard events self.key_events.Close = { {"Back"}, doc = "close menu" } - self.key_events.Select = { {"Press"}, doc = "chose selected item" } self.key_events.NextPage = { {Input.group.PgFwd}, doc = "goto next page of the menu" } @@ -441,8 +445,6 @@ function Menu:init() } -- we won't catch presses to "Right" self.key_events.FocusRight = nil - -- rather, we reserve that key for showing details - self.key_events.ShowItemDetail = { {"Right"}, doc = "show item detail" } if self.is_enable_shortcut then self.key_events.SelectByShortCut = { {self.item_shortcuts} } end @@ -561,7 +563,7 @@ end function Menu:onSelect() UIManager:close(self) - self.on_select_callback(self.item_table[self.selected.y]) + self.on_select_callback(self.item_table[(self.page-1)*self.perpage+self.selected.y]) return true end diff --git a/frontend/ui/filechooser.lua b/frontend/ui/filechooser.lua index d5740b6b4..62702a288 100644 --- a/frontend/ui/filechooser.lua +++ b/frontend/ui/filechooser.lua @@ -2,6 +2,7 @@ require "ui/dialog" -- for Menu FileChooser = Menu:new{ path = ".", + parent = nil, show_hidden = false, filter = function(filename) return true end, } @@ -13,6 +14,7 @@ end function FileChooser:changeToPath(path) local dirs = {} local files = {} + self.path = path for f in lfs.dir(self.path) do if self.show_hidden or not string.match(f, "^%.[^.]") then local filename = self.path.."/"..f @@ -32,11 +34,24 @@ function FileChooser:changeToPath(path) self.item_table = {} for _, dir in ipairs(dirs) do - table.insert(self.item_table, { text = dir.."/" }) + table.insert(self.item_table, { text = dir.."/", path = self.path.."/"..dir }) end for _, file in ipairs(files) do - table.insert(self.item_table, { text = file }) + table.insert(self.item_table, { text = file, path = self.path.."/"..file }) end Menu.init(self) -- call parent's init() end + +function FileChooser:onSelect() + local selected = self.item_table[(self.page-1)*self.perpage+self.selected.y] + if lfs.attributes(selected.path, "mode") == "directory" then + UIManager:close(self) + self:changeToPath(selected.path) + UIManager:show(self) + else + UIManager:close(self) + self.on_select_callback(self.item_table[self.selected.y]) + end + return true +end From 60ccd7441e5c326b80d13a3f669b0818170109db Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 28 May 2012 18:59:16 +0200 Subject: [PATCH 4/5] fixed menu info displaying, replaced debug() by DEBUG() the replacement of debug() was necessary to be able to access the lua library "debug" (for backtraces etc.) --- frontend/document/document.lua | 2 +- frontend/document/pdfdocument.lua | 8 ++++---- frontend/settings.lua | 2 +- frontend/ui/dialog.lua | 24 ++++++++++-------------- frontend/ui/font.lua | 6 +++--- frontend/ui/geometry.lua | 6 +++--- frontend/ui/inputevent.lua | 2 +- frontend/ui/reader/readerpaging.lua | 6 +++--- frontend/ui/reader/readerpanning.lua | 2 +- frontend/ui/reader/readerview.lua | 8 ++++---- frontend/ui/reader/readerzooming.lua | 6 +++--- frontend/ui/readerui.lua | 2 +- frontend/ui/rendertext.lua | 16 ++++++++-------- frontend/ui/screen.lua | 2 +- frontend/ui/ui.lua | 12 ++++++------ 15 files changed, 50 insertions(+), 54 deletions(-) diff --git a/frontend/document/document.lua b/frontend/document/document.lua index 3d96d7592..509f9055a 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -88,7 +88,7 @@ function Document:getPageDimensions(pageno, zoom, rotation) native_dimen.w, native_dimen.h = native_dimen.h, native_dimen.w end native_dimen:scaleBy(zoom) - debug("dimen for pageno", pageno, "zoom", zoom, "rotation", rotation, "is", native_dimen) + DEBUG("dimen for pageno", pageno, "zoom", zoom, "rotation", rotation, "is", native_dimen) return native_dimen end diff --git a/frontend/document/pdfdocument.lua b/frontend/document/pdfdocument.lua index 0353e367c..03a3861e0 100644 --- a/frontend/document/pdfdocument.lua +++ b/frontend/document/pdfdocument.lua @@ -89,10 +89,10 @@ function PdfDocument:renderPage(pageno, rect, zoom, rotation) -- we prefer to render the full page, if it fits into cache if not Cache:willAccept(size.w * size.h / 2) then -- whole page won't fit into cache - debug("rendering only part of the page") + DEBUG("rendering only part of the page") -- TODO: figure out how to better segment the page if not rect then - debug("aborting, since we do not have a specification for that part") + DEBUG("aborting, since we do not have a specification for that part") -- required part not given, so abort return end @@ -145,11 +145,11 @@ function PdfDocument:drawPage(target, x, y, rect, pageno, zoom, rotation) if not tile then tile = Cache:check(hash_excerpt) if not tile then - debug("rendering") + DEBUG("rendering") tile = self:renderPage(pageno, rect, zoom, rotation) end end - debug("now painting", tile) + DEBUG("now painting", tile) target:blitFrom(tile.bb, x, y, rect.x - tile.excerpt.x, rect.y - tile.excerpt.y, rect.w, rect.h) end diff --git a/frontend/settings.lua b/frontend/settings.lua index 7a15b6be9..260cb185a 100644 --- a/frontend/settings.lua +++ b/frontend/settings.lua @@ -27,7 +27,7 @@ function dump(data) return table.concat(out) end -function debug(...) +function DEBUG(...) local line = "" for i,v in ipairs(arg) do if type(v) == "table" then diff --git a/frontend/ui/dialog.lua b/frontend/ui/dialog.lua index 6112c18db..da6543347 100644 --- a/frontend/ui/dialog.lua +++ b/frontend/ui/dialog.lua @@ -193,7 +193,7 @@ function ConfirmBox:onClose() end function ConfirmBox:onSelect() - debug("selected:", self.selected.x) + DEBUG("selected:", self.selected.x) if self.selected.x == 1 then self:ok_callback() else @@ -324,11 +324,6 @@ MenuItem = InputContainer:new{ shortcut = nil, shortcut_style = "square", _underline_container = nil, - - key_events = { - Select = { {"Press"}, doc = "chose selected item" }, - ShowItemDetail = { {"Right"}, doc = "show item detail" } - } } function MenuItem:init() @@ -343,8 +338,14 @@ function MenuItem:init() -- 15 for HorizontalSpan, self.content_width = self.width - shortcut_icon_w - 15 + -- we need this table per-instance, so we declare it here + self.active_key_events = { + Select = { {"Press"}, doc = "chose selected item" }, + } + w = sizeUtf8Text(0, self.width, self.face, self.text, true).x if w >= self.content_width then + self.active_key_events.ShowItemDetail = { {"Right"}, doc = "show item detail" } indicator = " >>" indicator_w = sizeUtf8Text(0, self.width, self.face, indicator, true).x self.text = getSubTextByWidth(self.text, self.face, @@ -381,15 +382,17 @@ end function MenuItem:onFocus() self._underline_container.color = 10 + self.key_events = self.active_key_events return true end function MenuItem:onUnfocus() self._underline_container.color = 0 + self.key_events = { } return true end -function MenuItem:onShowDetail() +function MenuItem:onShowItemDetail() UIManager:show(InfoMessage:new{ text=self.detail, }) @@ -554,13 +557,6 @@ function Menu:onPrevPage() return true end -function Menu:onShowItemDetail() - self.layout[self.selected.y][self.selected.x]:handleEvent( - Event:new("ShowDetail") - ) - return true -end - function Menu:onSelect() UIManager:close(self) self.on_select_callback(self.item_table[(self.page-1)*self.perpage+self.selected.y]) diff --git a/frontend/ui/font.lua b/frontend/ui/font.lua index f9d77b639..b0c919114 100644 --- a/frontend/ui/font.lua +++ b/frontend/ui/font.lua @@ -1,4 +1,4 @@ -require "settings" -- for debug() +require "settings" -- for DEBUG() Font = { fontmap = { @@ -54,11 +54,11 @@ function Font:getFace(font, size) realname = self.fontdir.."/"..realname ok, face = pcall(freetype.newFace, realname, size) if not ok then - debug("#! Font "..font.." ("..realname..") not supported: "..face) + DEBUG("#! Font "..font.." ("..realname..") not supported: "..face) return nil end self.faces[font..size] = face - --debug("getFace, found: "..realname.." size:"..size) + --DEBUG("getFace, found: "..realname.." size:"..size) end return { size = size, ftface = face, hash = font..size } end diff --git a/frontend/ui/geometry.lua b/frontend/ui/geometry.lua index 157993b72..0fab4dcdc 100644 --- a/frontend/ui/geometry.lua +++ b/frontend/ui/geometry.lua @@ -174,12 +174,12 @@ end check if our size is smaller than the size of the given dimension/rectangle ]]-- function Geom:__lt(rect_b) - debug("lt:",self,rect_b) + DEBUG("lt:",self,rect_b) if self.w < rect_b.w and self.h < rect_b.h then -debug("lt+") +DEBUG("lt+") return true end -debug("lt-") +DEBUG("lt-") return false end diff --git a/frontend/ui/inputevent.lua b/frontend/ui/inputevent.lua index 81bb67d80..91d1be345 100644 --- a/frontend/ui/inputevent.lua +++ b/frontend/ui/inputevent.lua @@ -248,7 +248,7 @@ function Input:waitEvent(timeout_us, timeout_s) ev = nil break end - debug("got error waiting for events:", ev) + DEBUG("got error waiting for events:", ev) if ev ~= "Waiting for input failed: 4\n" then -- we abort if the error is not EINTR break diff --git a/frontend/ui/reader/readerpaging.lua b/frontend/ui/reader/readerpaging.lua index 86523a2d2..0549542b8 100644 --- a/frontend/ui/reader/readerpaging.lua +++ b/frontend/ui/reader/readerpaging.lua @@ -31,7 +31,7 @@ function ReaderPaging:gotoPage(number) or number < 1 then return false end - debug("going to page number", number) + DEBUG("going to page number", number) -- this is an event to allow other controllers to be aware of this change self.ui:handleEvent(Event:new("PageUpdate", number)) @@ -44,7 +44,7 @@ function ReaderPaging:onPageUpdate(new_page_no) end function ReaderPaging:onGotoPercent(percent) - debug("goto document offset in percent:", percent) + DEBUG("goto document offset in percent:", percent) local dest = math.floor(self.number_of_pages * percent / 100) if dest < 1 then dest = 1 end if dest > self.number_of_pages then @@ -55,7 +55,7 @@ function ReaderPaging:onGotoPercent(percent) end function ReaderPaging:onGotoPageRel(diff) - debug("goto relative page:", diff) + DEBUG("goto relative page:", diff) self:gotoPage(self.current_page + diff) return true end diff --git a/frontend/ui/reader/readerpanning.lua b/frontend/ui/reader/readerpanning.lua index 3bc09fc87..7ff54309f 100644 --- a/frontend/ui/reader/readerpanning.lua +++ b/frontend/ui/reader/readerpanning.lua @@ -22,7 +22,7 @@ end function ReaderPanning:onPanning(args, key) local dx, dy = unpack(args) - debug("key =", key) + DEBUG("key =", key) -- for now, bounds checking/calculation is done in the view self.view:PanningUpdate( dx * self.panning_steps.normal * self.dimen.w / 100, diff --git a/frontend/ui/reader/readerview.lua b/frontend/ui/reader/readerview.lua index bb6687ef4..64ee266d8 100644 --- a/frontend/ui/reader/readerview.lua +++ b/frontend/ui/reader/readerview.lua @@ -16,7 +16,7 @@ ReaderView = WidgetContainer:new{ } function ReaderView:paintTo(bb, x, y) - debug("painting", self.visible_area, "to", x, y) + DEBUG("painting", self.visible_area, "to", x, y) local inner_offset = Geom:new{x = 0, y = 0} -- draw surrounding space, if any @@ -61,14 +61,14 @@ function ReaderView:onSetDimensions(dimensions) end function ReaderView:PanningUpdate(dx, dy) - debug("pan by", dx, dy) + DEBUG("pan by", dx, dy) local old = Geom:copy(self.visible_area) self.visible_area:offsetWithin(self.page_area, dx, dy) if self.visible_area ~= old then -- flag a repaint UIManager:setDirty(self.dialog) - debug(self.page_area) - debug(self.visible_area) + DEBUG(self.page_area) + DEBUG(self.visible_area) end return true end diff --git a/frontend/ui/reader/readerzooming.lua b/frontend/ui/reader/readerzooming.lua index 5297a0b9d..92b88da93 100644 --- a/frontend/ui/reader/readerzooming.lua +++ b/frontend/ui/reader/readerzooming.lua @@ -63,13 +63,13 @@ function ReaderZooming:setZoom() end function ReaderZooming:onZoom(direction) - debug("zoom", direction) + DEBUG("zoom", direction) if direction == "in" then self.zoom = self.zoom * 1.333333 elseif direction == "out" then self.zoom = self.zoom * 0.75 end - debug("zoom is now at", self.zoom) + DEBUG("zoom is now at", self.zoom) self:onSetZoomMode("free") self.view:ZoomUpdate(self.zoom) return true @@ -77,7 +77,7 @@ end function ReaderZooming:onSetZoomMode(what) if self.zoom_mode ~= what then - debug("setting zoom mode to", what) + DEBUG("setting zoom mode to", what) self.zoom_mode = what self:setZoom() end diff --git a/frontend/ui/readerui.lua b/frontend/ui/readerui.lua index 593f24293..08e5665f8 100644 --- a/frontend/ui/readerui.lua +++ b/frontend/ui/readerui.lua @@ -76,7 +76,7 @@ function ReaderUI:init() end function ReaderUI:onClose() - debug("closing reader") + DEBUG("closing reader") if self.document then self.document:close() self.document = false diff --git a/frontend/ui/rendertext.lua b/frontend/ui/rendertext.lua index 32eaba389..743240916 100644 --- a/frontend/ui/rendertext.lua +++ b/frontend/ui/rendertext.lua @@ -13,7 +13,7 @@ function getGlyph(face, charcode) end local rendered_glyph = face.ftface:renderGlyph(charcode) if not rendered_glyph then - debug("error rendering glyph (charcode=", charcode, ") for face", face) + DEBUG("error rendering glyph (charcode=", charcode, ") for face", face) return end glyph = CacheItem:new{rendered_glyph} @@ -48,7 +48,7 @@ end function sizeUtf8Text(x, width, face, text, kerning) if text == nil then - debug("sizeUtf8Text called without text"); + DEBUG("sizeUtf8Text called without text"); return end -- may still need more adaptive pen placement when kerning, @@ -64,14 +64,14 @@ function sizeUtf8Text(x, width, face, text, kerning) if kerning and prevcharcode then local kern = face.ftface:getKerning(prevcharcode, charcode) pen_x = pen_x + kern - --debug("prev:"..string.char(prevcharcode).." curr:"..string.char(charcode).." kern:"..kern) + --DEBUG("prev:"..string.char(prevcharcode).." curr:"..string.char(charcode).." kern:"..kern) else - --debug("curr:"..string.char(charcode)) + --DEBUG("curr:"..string.char(charcode)) end pen_x = pen_x + glyph.ax pen_y_top = math.max(pen_y_top, glyph.t) pen_y_bottom = math.max(pen_y_bottom, glyph.bb:getHeight() - glyph.t) - --debug("ax:"..glyph.ax.." t:"..glyph.t.." r:"..glyph.r.." h:"..glyph.bb:getHeight().." w:"..glyph.bb:getWidth().." yt:"..pen_y_top.." yb:"..pen_y_bottom) + --DEBUG("ax:"..glyph.ax.." t:"..glyph.t.." r:"..glyph.r.." h:"..glyph.bb:getHeight().." w:"..glyph.bb:getWidth().." yt:"..pen_y_top.." yb:"..pen_y_bottom) prevcharcode = charcode end end @@ -80,7 +80,7 @@ end function renderUtf8Text(buffer, x, y, face, text, kerning) if text == nil then - debug("renderUtf8Text called without text"); + DEBUG("renderUtf8Text called without text"); return 0 end -- may still need more adaptive pen placement when kerning, @@ -94,10 +94,10 @@ function renderUtf8Text(buffer, x, y, face, text, kerning) if kerning and prevcharcode then local kern = face.ftface:getKerning(prevcharcode, charcode) pen_x = pen_x + kern - --debug("prev:"..string.char(prevcharcode).." curr:"..string.char(charcode).." pen_x:"..pen_x.." kern:"..kern) + --DEBUG("prev:"..string.char(prevcharcode).." curr:"..string.char(charcode).." pen_x:"..pen_x.." kern:"..kern) buffer:addblitFrom(glyph.bb, x + pen_x + glyph.l, y - glyph.t, 0, 0, glyph.bb:getWidth(), glyph.bb:getHeight()) else - --debug(" curr:"..string.char(charcode)) + --DEBUG(" curr:"..string.char(charcode)) buffer:blitFrom(glyph.bb, x + pen_x + glyph.l, y - glyph.t, 0, 0, glyph.bb:getWidth(), glyph.bb:getHeight()) end pen_x = pen_x + glyph.ax diff --git a/frontend/ui/screen.lua b/frontend/ui/screen.lua index 3dd0ebfae..67312cf3b 100644 --- a/frontend/ui/screen.lua +++ b/frontend/ui/screen.lua @@ -103,6 +103,6 @@ function Screen:restoreFromBB(bb) if bb then fb.bb:blitFullFrom(bb) else - debug("Got nil bb in restoreFromSavedBB!") + DEBUG("Got nil bb in restoreFromSavedBB!") end end diff --git a/frontend/ui/ui.lua b/frontend/ui/ui.lua index 0120de519..5c55bedd5 100644 --- a/frontend/ui/ui.lua +++ b/frontend/ui/ui.lua @@ -3,7 +3,7 @@ require "ui/inputevent" require "ui/widget" require "ui/screen" require "ui/dialog" -require "settings" -- for debug(), TODO: put debug() somewhere else +require "settings" -- for DEBUG(), TODO: put DEBUG() somewhere else -- we also initialize the framebuffer @@ -136,11 +136,11 @@ function UIManager:run() end until all_tasks_checked - --debug("---------------------------------------------------") - --debug("exec stack", self._execution_stack) - --debug("window stack", self._window_stack) - --debug("dirty stack", self._dirty) - --debug("---------------------------------------------------") + --DEBUG("---------------------------------------------------") + --DEBUG("exec stack", self._execution_stack) + --DEBUG("window stack", self._window_stack) + --DEBUG("dirty stack", self._dirty) + --DEBUG("---------------------------------------------------") -- stop when we have no window to show (bug) if #self._window_stack == 0 then From 7f6773dc6f061411ce7ec971ce6f15e88471740e Mon Sep 17 00:00:00 2001 From: Qingping Hou Date: Sun, 3 Jun 2012 10:59:35 +0800 Subject: [PATCH 5/5] demo for djvu support wait for code clean up --- frontend/document/djvudocument.lua | 153 +++++++++++++++++++++++++++++ frontend/document/document.lua | 1 + 2 files changed, 154 insertions(+) create mode 100644 frontend/document/djvudocument.lua diff --git a/frontend/document/djvudocument.lua b/frontend/document/djvudocument.lua new file mode 100644 index 000000000..3e49762f8 --- /dev/null +++ b/frontend/document/djvudocument.lua @@ -0,0 +1,153 @@ +require "cache" +require "ui/geometry" + +DjvuDocument = Document:new{ + _document = false, + -- libdjvulibre manages its own additional cache, default value is hard written in c module. + djvulibre_cache_size = nil, + dc_null = DrawContext.new() +} + +function DjvuDocument:init() + local ok + ok, self._document = pcall(djvu.openDocument, self.file, self.djvulibre_cache_size) + if not ok then + self.error_message = self.doc -- will contain error message + return + end + self.is_open = true + self.info.has_pages = true + self:_readMetadata() +end + +function DjvuDocument:_readMetadata() + self.info.number_of_pages = self._document:getPages() + return true +end + +function DjvuDocument:close() + if self.is_open then + self.is_open = false + self._document:close() + end +end + +function DjvuDocument:getNativePageDimensions(pageno) + local hash = "pgdim|"..self.file.."|"..pageno + local cached = Cache:check(hash) + if cached then + return cached[1] + end + local page = self._document:openPage(pageno) + local page_size_w, page_size_h = page:getSize(self.dc_null) + local page_size = Geom:new{ w = page_size_w, h = page_size_h } + Cache:insert(hash, CacheItem:new{ page_size }) + page:close() + return page_size +end + +function DjvuDocument:getUsedBBox(pageno) + --local hash = "pgubbox|"..self.file.."|"..pageno + --local cached = Cache:check(hash) + --if cached then + --return cached.data + --end + --local page = self._document:openPage(pageno) + local used = {} + used.x, used.y, used.w, used.h = 0.01, 0.01, -0.01, -0.01 + --Cache:insert(hash, CacheItem:new{ used }) + --page:close() + return used +end + +function DjvuDocument:getPageText(pageno) + -- is this worth caching? not done yet. + local page = self._document:openPage(pageno) + local text = page:getPageText() + page:close() + return text +end + +function DjvuDocument:renderPage(pageno, rect, zoom, rotation) + local hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation + local page_size = self:getPageDimensions(pageno, zoom, rotation) + -- this will be the size we actually render + local size = page_size + -- we prefer to render the full page, if it fits into cache + if not Cache:willAccept(size.w * size.h / 2) then + -- whole page won't fit into cache + DEBUG("rendering only part of the page") + -- TODO: figure out how to better segment the page + if not rect then + DEBUG("aborting, since we do not have a specification for that part") + -- required part not given, so abort + return + end + -- only render required part + hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..tostring(rect) + size = rect + 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) + } + + -- create a draw context + local dc = DrawContext.new() + + dc:setRotate(rotation) + -- correction of rotation + if rotation == 90 then + dc:setOffset(page_size.w, 0) + elseif rotation == 180 then + dc:setOffset(page_size.w, page_size.h) + elseif rotation == 270 then + dc:setOffset(0, page_size.h) + end + dc:setZoom(zoom) + + -- render + local page = self._document:openPage(pageno) + page:draw(dc, tile.bb, size.x, size.y) + page:close() + Cache:insert(hash, tile) + + return tile +end + +-- a hint for the cache engine to paint a full page to the cache +-- TODO: this should trigger a background operation +function DjvuDocument:hintPage(pageno, zoom, rotation) + self:renderPage(pageno, nil, zoom, rotation) +end + +function DjvuDocument:drawPage(target, x, y, rect, pageno, zoom, rotation) + local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation + local hash_excerpt = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..tostring(rect) + local tile = Cache:check(hash_full_page) + if not tile then + tile = Cache:check(hash_excerpt) + if not tile then + DEBUG("rendering") + tile = self:renderPage(pageno, rect, zoom, rotation) + end + end + DEBUG("now painting", tile) + target:blitFrom(tile.bb, x, y, rect.x - tile.excerpt.x, rect.y - tile.excerpt.y, rect.w, rect.h) +end + +function DjvuDocument:invertTextYAxel(pageno, text_table) + local _, height = self.doc:getOriginalPageSize(pageno) + for _,text in pairs(text_table) do + for _,line in ipairs(text) do + line.y0, line.y1 = (height - line.y1), (height - line.y0) + end + end + return text_table +end + +DocumentRegistry:addProvider("djvu", "application/djvu", DjvuDocument) diff --git a/frontend/document/document.lua b/frontend/document/document.lua index 509f9055a..cff33f2a7 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -99,3 +99,4 @@ end -- load implementations: require "document/pdfdocument" +require "document/djvudocument"