From e3bac94db1c84248a589e5c07bfe074efeae64e4 Mon Sep 17 00:00:00 2001 From: poire-z Date: Sun, 18 Jul 2021 19:56:19 +0200 Subject: [PATCH] PDF written highlights: fix boxes, trash cached tiles TileCacheItem: add created_ts property. Document: manage a tile_cache_validity_ts and ignore older cached tiles. This timestamps is updated when highlights are written as annotations in, or deleted from, the PDF, so we can get the most current rendered bitmap from MuPDF and avoid highlight ghosts on old tiles. Save this timestamp in doc settings so older cached to disk tiles will also be ignored across re-openings. Bump base for: mupdf.lua: update frontend pboxes with MuPDF adjusted ones. --- base | 2 +- frontend/apps/reader/modules/readerview.lua | 2 ++ frontend/document/document.lua | 24 ++++++++++++++++++++- frontend/document/pdfdocument.lua | 22 ++++++++++++++++++- frontend/document/tilecacheitem.lua | 2 ++ 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/base b/base index 0258347cb..13f0d3dec 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 0258347cb02184f51e891d258efceea63b0e1b8d +Subproject commit 13f0d3decc2c5c4cc7a1f17dfad8fd5d53721e68 diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index efc55d3ae..3db9bcf50 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -760,6 +760,7 @@ In combination with zoom to fit page, page height, content height, content or co end function ReaderView:onReadSettings(config) + self.document:setTileCacheValidity(config:readSetting("tile_cache_validity_ts")) self.render_mode = config:readSetting("render_mode") or 0 local rotation_mode = nil local locked = G_reader_settings:isTrue("lock_rotation") @@ -888,6 +889,7 @@ function ReaderView:onPageGapUpdate(page_gap) end function ReaderView:onSaveSettings() + self.ui.doc_settings:saveSetting("tile_cache_validity_ts", self.document:getTileCacheValidity()) self.ui.doc_settings:saveSetting("render_mode", self.render_mode) -- Don't etch the current rotation in stone when sticky rotation is enabled local locked = G_reader_settings:isTrue("lock_rotation") diff --git a/frontend/document/document.lua b/frontend/document/document.lua index d4b6c45e4..2d673eb97 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -372,6 +372,18 @@ function Document:postRenderPage() return nil end +function Document:getTileCacheValidity() + return self.tile_cache_validity_ts +end + +function Document:setTileCacheValidity(ts) + self.tile_cache_validity_ts = ts +end + +function Document:resetTileCacheValidity() + self.tile_cache_validity_ts = os.time() +end + function Document:getFullPageHash(pageno, zoom, rotation, gamma, render_mode, color) return "renderpg|"..self.file.."|"..self.mod_time.."|"..pageno.."|" ..zoom.."|"..rotation.."|"..gamma.."|"..render_mode..(color and "|color" or "") @@ -386,7 +398,16 @@ function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode) hash_excerpt = hash.."|"..tostring(rect) tile = DocCache:check(hash_excerpt) end - if tile then return tile end + if tile then + if self.tile_cache_validity_ts then + if tile.created_ts and tile.created_ts >= self.tile_cache_validity_ts then + return tile + end + logger.dbg("discarding stale cached tile") + else + return tile + end + end self:preRenderPage() @@ -411,6 +432,7 @@ function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode) -- prepare cache item with contained blitbuffer tile = TileCacheItem:new{ persistent = true, + created_ts = os.time(), excerpt = size, pageno = pageno, bb = Blitbuffer.new(size.w, size.h, self.render_color and self.color_bb_type or nil) diff --git a/frontend/document/pdfdocument.lua b/frontend/document/pdfdocument.lua index 4130b321b..97be49205 100644 --- a/frontend/document/pdfdocument.lua +++ b/frontend/document/pdfdocument.lua @@ -208,6 +208,20 @@ local function _quadpointsFromPboxes(pboxes) return quadpoints, n end +local function _quadpointsToPboxes(quadpoints, n) + -- reverse of previous function + local pboxes = {} + for i=1, n do + table.insert(pboxes, { + x = quadpoints[8*i-4], + y = quadpoints[8*i-3], + w = quadpoints[8*i-6] - quadpoints[8*i-4], + h = quadpoints[8*i-5] - quadpoints[8*i-3], + }) + end + return pboxes +end + function PdfDocument:saveHighlight(pageno, item) local can_write = self:_checkIfWritable() if can_write ~= true then return can_write end @@ -223,8 +237,12 @@ function PdfDocument:saveHighlight(pageno, item) elseif item.drawer == "strikeout" then annot_type = C.PDF_ANNOT_STRIKEOUT end - page:addMarkupAnnotation(quadpoints, n, annot_type) + page:addMarkupAnnotation(quadpoints, n, annot_type) -- may update/adjust quadpoints + -- Update pboxes with the possibly adjusted coordinates (this will have it updated + -- in self.view.highlight.saved[page]) + item.pboxes = _quadpointsToPboxes(quadpoints, n) page:close() + self:resetTileCacheValidity() end function PdfDocument:deleteHighlight(pageno, item) @@ -237,6 +255,7 @@ function PdfDocument:deleteHighlight(pageno, item) local annot = page:getMarkupAnnotation(quadpoints, n) if annot ~= nil then page:deleteMarkupAnnotation(annot) + self:resetTileCacheValidity() end page:close() end @@ -251,6 +270,7 @@ function PdfDocument:updateHighlightContents(pageno, item, contents) local annot = page:getMarkupAnnotation(quadpoints, n) if annot ~= nil then page:updateMarkupAnnotation(annot, contents) + self:resetTileCacheValidity() end page:close() end diff --git a/frontend/document/tilecacheitem.lua b/frontend/document/tilecacheitem.lua index 82c8b8c25..60b4b6214 100644 --- a/frontend/document/tilecacheitem.lua +++ b/frontend/document/tilecacheitem.lua @@ -17,6 +17,7 @@ function TileCacheItem:totable() size = self.size, pageno = self.pageno, excerpt = self.excerpt, + created_ts = self.created_ts, persistent = self.persistent, bb = { w = self.bb.w, @@ -51,6 +52,7 @@ function TileCacheItem:fromtable(t) self.size = t.size self.pageno = t.pageno self.excerpt = t.excerpt + self.created_ts = t.created_ts self.persistent = t.persistent self.bb = Blitbuffer.fromstring(t.bb.w, t.bb.h, t.bb.fmt, t.bb.data, t.bb.stride) end