2
0
mirror of https://github.com/koreader/koreader synced 2024-10-31 21:20:20 +00:00
koreader/frontend/document/djvudocument.lua
chrox 5983050d79 PDF free zoom mode revisit
this should implement feature request of zoom mode for multi-columns
page in #501
This PR depends on koreader/koreader-base#435

How to use?
1. Tap the top left corner of a PDF/Djvu page to get into the flipping
mode
2. Double-tap on text block will zoom in to that column
3. Double-tap on any area will zoom out to an overview of the page
4. repeat step 2 to focus to another page block

How does it work?
1. We first find the mask of text blocks in the page. (Pic 1)
2. Then we intersect page boxes with user tap to form a page block. (Pic 2)
3. Finally we zoom the page to the page block and center current view to
that block. (Pic 3)
2016-06-15 02:05:09 +08:00

126 lines
4.1 KiB
Lua

local KoptOptions = require("ui/data/koptoptions")
local Document = require("document/document")
local DrawContext = require("ffi/drawcontext")
local DjvuDocument = Document:new{
_document = false,
-- libdjvulibre manages its own additional cache, default value is hard written in c module.
is_djvu = true,
djvulibre_cache_size = nil,
dc_null = DrawContext.new(),
options = KoptOptions,
koptinterface = nil,
}
-- check DjVu magic string to validate
local function validDjvuFile(filename)
local f = io.open(filename, "r")
if not f then return false end
local magic = f:read(8)
f:close()
if not magic or magic ~= "AT&TFORM" then return false end
return true
end
function DjvuDocument:init()
local djvu = require("libs/libkoreader-djvu")
self.koptinterface = require("document/koptinterface")
self.configurable:loadDefaults(self.options)
if not validDjvuFile(self.file) then
error("Not a valid DjVu file")
end
local ok
ok, self._document = pcall(djvu.openDocument, self.file, self.djvulibre_cache_size)
if not ok then
error(self._document) -- will contain error message
end
self.is_open = true
self.info.has_pages = true
self.info.configurable = true
self:_readMetadata()
end
function DjvuDocument:getPageTextBoxes(pageno)
return self._document:getPageText(pageno)
end
function DjvuDocument:getWordFromPosition(spos)
return self.koptinterface:getWordFromPosition(self, spos)
end
function DjvuDocument:getTextFromPositions(spos0, spos1)
return self.koptinterface:getTextFromPositions(self, spos0, spos1)
end
function DjvuDocument:getPageBoxesFromPositions(pageno, ppos0, ppos1)
return self.koptinterface:getPageBoxesFromPositions(self, pageno, ppos0, ppos1)
end
function DjvuDocument:nativeToPageRectTransform(pageno, rect)
return self.koptinterface:nativeToPageRectTransform(self, pageno, rect)
end
function DjvuDocument:getOCRWord(pageno, wbox)
return self.koptinterface:getOCRWord(self, pageno, wbox)
end
function DjvuDocument:getOCRText(pageno, tboxes)
return self.koptinterface:getOCRText(self, pageno, tboxes)
end
function DjvuDocument:getPageBlock(pageno, x, y)
return self.koptinterface:getPageBlock(self, pageno, x, y)
end
function DjvuDocument:getUsedBBox(pageno)
-- djvu does not support usedbbox, so fake it.
local used = {}
local native_dim = self:getNativePageDimensions(pageno)
used.x0, used.y0, used.x1, used.y1 = 0, 0, native_dim.w, native_dim.h
return used
end
function DjvuDocument:clipPagePNGFile(pos0, pos1, pboxes, drawer, filename)
return self.koptinterface:clipPagePNGFile(self, pos0, pos1, pboxes, drawer, filename)
end
function DjvuDocument:clipPagePNGString(pos0, pos1, pboxes, drawer)
return self.koptinterface:clipPagePNGString(self, pos0, pos1, pboxes, drawer)
end
function DjvuDocument:getPageBBox(pageno)
return self.koptinterface:getPageBBox(self, pageno)
end
function DjvuDocument:getPageDimensions(pageno, zoom, rotation)
return self.koptinterface:getPageDimensions(self, pageno, zoom, rotation)
end
function DjvuDocument:getCoverPageImage()
return self.koptinterface:getCoverPageImage(self)
end
function DjvuDocument:findText(pattern, origin, reverse, caseInsensitive, page)
return self.koptinterface:findText(self, pattern, origin, reverse, caseInsensitive, page)
end
function DjvuDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode)
end
function DjvuDocument:hintPage(pageno, zoom, rotation, gamma, render_mode)
return self.koptinterface:hintPage(self, pageno, zoom, rotation, gamma, render_mode)
end
function DjvuDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
return self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
end
function DjvuDocument:register(registry)
registry:addProvider("djvu", "application/djvu", self)
registry:addProvider("djv", "application/djvu", self)
end
return DjvuDocument