diff --git a/unireader.lua b/unireader.lua index 9def0d545..61fd3e26a 100644 --- a/unireader.lua +++ b/unireader.lua @@ -182,15 +182,24 @@ function UniReader:draworcache(no, preCache) local page = self.doc:openPage(no) local dc = self:setzoom(page) + -- offset_x_in_page & offset_y_in_page is the offset within zoomed page + -- they are always positive. + -- you can see self.offset_x_& self.offset_y as the offset within + -- draw space, which includes the page. So it can be negative and positive. + local offset_x_in_page = -self.offset_x + local offset_y_in_page = -self.offset_y + if offset_x_in_page < 0 then offset_x_in_page = 0 end + if offset_y_in_page < 0 then offset_y_in_page = 0 end + -- check if we have relevant cache contents local pagehash = no..'_'..self.globalzoom..'_'..self.globalrotate..'_'..self.globalgamma if self.cache[pagehash] ~= nil then -- we have something in cache, check if it contains the requested part - if self.cache[pagehash].x <= (-self.offset_x) - and self.cache[pagehash].y <= (-self.offset_y) - and ( self.cache[pagehash].x + self.cache[pagehash].w >= (-self.offset_x) + width + if self.cache[pagehash].x <= offset_x_in_page + and self.cache[pagehash].y <= offset_y_in_page + and ( self.cache[pagehash].x + self.cache[pagehash].w >= offset_x_in_page + width or self.cache[pagehash].w >= self.fullwidth - 1) - and ( self.cache[pagehash].y + self.cache[pagehash].h >= (-self.offset_y) + height + and ( self.cache[pagehash].y + self.cache[pagehash].h >= offset_y_in_page + height or self.cache[pagehash].h >= self.fullheight - 1) then -- requested part is within cached tile @@ -202,14 +211,15 @@ function UniReader:draworcache(no, preCache) end -- ...and return blitbuffer plus offset into it return pagehash, - (-self.offset_x) - self.cache[pagehash].x, - (-self.offset_y) - self.cache[pagehash].y + offset_x_in_page - self.cache[pagehash].x, + offset_y_in_page - self.cache[pagehash].y end end -- okay, we do not have it in cache yet. -- so render now. -- start off with the requested area - local tile = { x = (-self.offset_x), y = (-self.offset_y), w = width, h = heigth } + local tile = { x = offset_x_in_page, y = offset_y_in_page, + w = width, h = height } -- can we cache the full page? local max_cache = self.cache_max_memsize if preCache then @@ -256,14 +266,16 @@ function UniReader:draworcache(no, preCache) size = tile.w * tile.h / 2, bb = Blitbuffer.new(tile.w, tile.h) } + --print ("# new biltbuffer:"..dump(self.cache[pagehash])) dc:setOffset(-tile.x, -tile.y) print("# rendering: page="..no) page:draw(dc, self.cache[pagehash].bb, 0, 0) page:close() + -- return hash and offset within blitbuffer return pagehash, - (-self.offset_x) - tile.x, - (-self.offset_y) - tile.y + offset_x_in_page - tile.x, + offset_y_in_page - tile.y end -- blank the cache @@ -430,16 +442,27 @@ function UniReader:show(no) local dest_x = 0 local dest_y = 0 if bb:getWidth() - offset_x < width then - -- we can't fill the whole output width + -- we can't fill the whole output width, center the content dest_x = (width - (bb:getWidth() - offset_x)) / 2 end - if bb:getHeight() - offset_y < height then - -- we can't fill the whole output heigth + if bb:getHeight() - offset_y < height and + self.globalzoommode ~= self.ZOOM_FIT_TO_CONTENT_WIDTH_PAN then + -- we can't fill the whole output height and not in + -- ZOOM_FIT_TO_CONTENT_WIDTH_PAN mode, center the content dest_y = (height - (bb:getHeight() - offset_y)) / 2 + elseif self.globalzoommode == self.ZOOM_FIT_TO_CONTENT_WIDTH_PAN and + self.offset_y > 0 then + -- if we are in ZOOM_FIT_TO_CONTENT_WIDTH_PAN mode and turning to + -- the top of the page, we might leave an empty space between the + -- page top and screen top. + dest_y = self.offset_y end if dest_x or dest_y then fb.bb:paintRect(0, 0, width, height, 8) end + print("# blitFrom dest_off:("..dest_x..", "..dest_y.. + "), src_off:("..offset_x..", "..offset_y.."), ".. + "width:"..width..", height:"..height) fb.bb:blitFrom(bb, dest_x, dest_y, offset_x, offset_y, width, height) if self.rcount == self.rcountmax then print("full refresh")