2013-10-18 20:38:07 +00:00
|
|
|
|
local CacheItem = require("cacheitem")
|
2019-05-14 15:57:59 +00:00
|
|
|
|
local CanvasContext = require("document/canvascontext")
|
2021-05-04 21:13:24 +00:00
|
|
|
|
local DocCache = require("document/doccache")
|
2019-09-16 06:22:26 +00:00
|
|
|
|
local DocSettings = require("docsettings")
|
2013-10-18 20:38:07 +00:00
|
|
|
|
local Document = require("document/document")
|
2013-12-31 05:12:56 +00:00
|
|
|
|
local DrawContext = require("ffi/drawcontext")
|
2016-12-29 08:10:38 +00:00
|
|
|
|
local logger = require("logger")
|
2016-02-12 14:55:02 +00:00
|
|
|
|
local util = require("util")
|
2018-06-02 16:10:55 +00:00
|
|
|
|
local ffi = require("ffi")
|
|
|
|
|
local C = ffi.C
|
2017-10-01 17:23:06 +00:00
|
|
|
|
local pdf = nil
|
2013-10-18 20:38:07 +00:00
|
|
|
|
|
Clarify our OOP semantics across the codebase (#9586)
Basically:
* Use `extend` for class definitions
* Use `new` for object instantiations
That includes some minor code cleanups along the way:
* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since https://github.com/koreader/android-luajit-launcher/pull/283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
* ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
2022-10-06 00:14:48 +00:00
|
|
|
|
local PdfDocument = Document:extend{
|
2014-03-13 13:52:43 +00:00
|
|
|
|
_document = false,
|
2015-09-07 17:06:17 +00:00
|
|
|
|
is_pdf = true,
|
2014-03-13 13:52:43 +00:00
|
|
|
|
dc_null = DrawContext.new(),
|
|
|
|
|
koptinterface = nil,
|
2018-02-02 20:21:52 +00:00
|
|
|
|
provider = "mupdf",
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
provider_name = "MuPDF",
|
2012-05-18 23:13:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function PdfDocument:init()
|
2017-10-01 17:23:06 +00:00
|
|
|
|
if not pdf then pdf = require("ffi/mupdf") end
|
|
|
|
|
-- mupdf.color has to stay false for kopt to work correctly
|
|
|
|
|
-- and be accurate (including its job about showing highlight
|
|
|
|
|
-- boxes). We will turn it on and off in PdfDocument:preRenderPage()
|
|
|
|
|
-- and :postRenderPage() when mupdf is called without kopt involved.
|
|
|
|
|
pdf.color = false
|
|
|
|
|
self:updateColorRendering()
|
2014-03-13 13:52:43 +00:00
|
|
|
|
self.koptinterface = require("document/koptinterface")
|
2018-10-26 15:27:43 +00:00
|
|
|
|
self.koptinterface:setDefaultConfigurable(self.configurable)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
local ok
|
2014-10-18 22:22:35 +00:00
|
|
|
|
ok, self._document = pcall(pdf.openDocument, self.file)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
if not ok then
|
2014-08-29 09:17:08 +00:00
|
|
|
|
error(self._document) -- will contain error message
|
2014-03-13 13:52:43 +00:00
|
|
|
|
end
|
2019-08-30 11:47:51 +00:00
|
|
|
|
self.is_reflowable = self._document:isDocumentReflowable()
|
|
|
|
|
self.reflowable_font_size = self:convertKoptToReflowableFontSize()
|
2018-12-02 22:02:54 +00:00
|
|
|
|
-- no-op on PDF
|
2019-08-30 11:47:51 +00:00
|
|
|
|
self:layoutDocument()
|
2014-03-13 13:52:43 +00:00
|
|
|
|
self.is_open = true
|
|
|
|
|
self.info.has_pages = true
|
|
|
|
|
self.info.configurable = true
|
|
|
|
|
if self._document:needsPassword() then
|
|
|
|
|
self.is_locked = true
|
|
|
|
|
else
|
|
|
|
|
self:_readMetadata()
|
|
|
|
|
end
|
2012-05-18 23:13:53 +00:00
|
|
|
|
end
|
|
|
|
|
|
2019-08-30 11:47:51 +00:00
|
|
|
|
function PdfDocument:layoutDocument(font_size)
|
|
|
|
|
if font_size then
|
|
|
|
|
self.reflowable_font_size = font_size
|
|
|
|
|
end
|
|
|
|
|
self._document:layoutDocument(
|
|
|
|
|
CanvasContext:getWidth(),
|
|
|
|
|
CanvasContext:getHeight(),
|
|
|
|
|
CanvasContext:scaleBySize(self.reflowable_font_size))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local default_font_size = 22
|
|
|
|
|
-- the koptreader config goes from 0.1 to 3.0, but we want a regular font size
|
|
|
|
|
function PdfDocument:convertKoptToReflowableFontSize(font_size)
|
|
|
|
|
if font_size then
|
|
|
|
|
return font_size * default_font_size
|
|
|
|
|
end
|
|
|
|
|
|
2019-09-16 06:22:26 +00:00
|
|
|
|
local size
|
|
|
|
|
if DocSettings:hasSidecarFile(self.file) then
|
|
|
|
|
local doc_settings = DocSettings:open(self.file)
|
|
|
|
|
size = doc_settings:readSetting("kopt_font_size")
|
|
|
|
|
end
|
2019-08-30 11:47:51 +00:00
|
|
|
|
if size then
|
|
|
|
|
return size * default_font_size
|
|
|
|
|
elseif G_reader_settings:readSetting("kopt_font_size") then
|
|
|
|
|
return G_reader_settings:readSetting("kopt_font_size") * default_font_size
|
2022-09-27 23:10:50 +00:00
|
|
|
|
elseif G_defaults:readSetting("DKOPTREADER_CONFIG_FONT_SIZE") then
|
|
|
|
|
return G_defaults:readSetting("DKOPTREADER_CONFIG_FONT_SIZE") * default_font_size
|
2019-08-30 11:47:51 +00:00
|
|
|
|
else
|
|
|
|
|
return default_font_size
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2017-10-01 17:23:06 +00:00
|
|
|
|
function PdfDocument:preRenderPage()
|
|
|
|
|
pdf.color = self.render_color
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PdfDocument:postRenderPage()
|
|
|
|
|
pdf.color = false
|
|
|
|
|
end
|
|
|
|
|
|
2012-05-18 23:13:53 +00:00
|
|
|
|
function PdfDocument:unlock(password)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
if not self._document:authenticatePassword(password) then
|
2015-10-06 13:18:07 +00:00
|
|
|
|
return false
|
2014-03-13 13:52:43 +00:00
|
|
|
|
end
|
|
|
|
|
self.is_locked = false
|
2015-10-06 13:18:07 +00:00
|
|
|
|
self:_readMetadata()
|
|
|
|
|
return true
|
2012-05-18 23:13:53 +00:00
|
|
|
|
end
|
|
|
|
|
|
2022-01-06 19:54:33 +00:00
|
|
|
|
function PdfDocument:comparePositions(pos1, pos2)
|
|
|
|
|
return self.koptinterface:comparePositions(self, pos1, pos2)
|
|
|
|
|
end
|
|
|
|
|
|
2013-10-12 15:07:13 +00:00
|
|
|
|
function PdfDocument:getPageTextBoxes(pageno)
|
2023-05-18 20:08:50 +00:00
|
|
|
|
local hash = "textbox|"..self.file.."|"..pageno
|
|
|
|
|
local cached = DocCache:check(hash)
|
|
|
|
|
if not cached then
|
|
|
|
|
local page = self._document:openPage(pageno)
|
|
|
|
|
local text = page:getPageText()
|
|
|
|
|
page:close()
|
|
|
|
|
DocCache:insert(hash, CacheItem:new{text=text, size=text.size})
|
|
|
|
|
return text
|
|
|
|
|
else
|
|
|
|
|
return cached.text
|
|
|
|
|
end
|
2013-10-12 15:07:13 +00:00
|
|
|
|
end
|
|
|
|
|
|
2020-09-24 13:17:37 +00:00
|
|
|
|
function PdfDocument:getPanelFromPage(pageno, pos)
|
|
|
|
|
return self.koptinterface:getPanelFromPage(self, pageno, pos)
|
|
|
|
|
end
|
|
|
|
|
|
2013-10-12 15:07:13 +00:00
|
|
|
|
function PdfDocument:getWordFromPosition(spos)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getWordFromPosition(self, spos)
|
2013-10-12 15:07:13 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PdfDocument:getTextFromPositions(spos0, spos1)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getTextFromPositions(self, spos0, spos1)
|
2013-10-12 15:07:13 +00:00
|
|
|
|
end
|
|
|
|
|
|
2022-12-02 18:22:27 +00:00
|
|
|
|
function PdfDocument:getTextBoxes(pageno)
|
|
|
|
|
return self.koptinterface:getTextBoxes(self, pageno)
|
|
|
|
|
end
|
|
|
|
|
|
2013-10-12 15:07:13 +00:00
|
|
|
|
function PdfDocument:getPageBoxesFromPositions(pageno, ppos0, ppos1)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getPageBoxesFromPositions(self, pageno, ppos0, ppos1)
|
2013-04-23 22:59:52 +00:00
|
|
|
|
end
|
|
|
|
|
|
2014-05-02 08:50:43 +00:00
|
|
|
|
function PdfDocument:nativeToPageRectTransform(pageno, rect)
|
|
|
|
|
return self.koptinterface:nativeToPageRectTransform(self, pageno, rect)
|
|
|
|
|
end
|
|
|
|
|
|
2022-10-25 10:23:18 +00:00
|
|
|
|
function PdfDocument:getSelectedWordContext(word, nb_words, pos)
|
|
|
|
|
return self.koptinterface:getSelectedWordContext(word, nb_words, pos)
|
|
|
|
|
end
|
|
|
|
|
|
2013-10-14 15:05:58 +00:00
|
|
|
|
function PdfDocument:getOCRWord(pageno, wbox)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getOCRWord(self, pageno, wbox)
|
2013-10-14 15:05:58 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PdfDocument:getOCRText(pageno, tboxes)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getOCRText(self, pageno, tboxes)
|
2013-04-23 22:59:52 +00:00
|
|
|
|
end
|
|
|
|
|
|
2016-06-14 17:50:59 +00:00
|
|
|
|
function PdfDocument:getPageBlock(pageno, x, y)
|
|
|
|
|
return self.koptinterface:getPageBlock(self, pageno, x, y)
|
2014-01-02 03:08:06 +00:00
|
|
|
|
end
|
|
|
|
|
|
2012-05-18 23:13:53 +00:00
|
|
|
|
function PdfDocument:getUsedBBox(pageno)
|
2019-08-30 11:47:51 +00:00
|
|
|
|
local hash = "pgubbox|"..self.file.."|"..self.reflowable_font_size.."|"..pageno
|
2021-05-04 21:13:24 +00:00
|
|
|
|
local cached = DocCache:check(hash)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
if cached then
|
|
|
|
|
return cached.ubbox
|
|
|
|
|
end
|
|
|
|
|
local page = self._document:openPage(pageno)
|
|
|
|
|
local used = {}
|
|
|
|
|
used.x0, used.y0, used.x1, used.y1 = page:getUsedBBox()
|
|
|
|
|
local pwidth, pheight = page:getSize(self.dc_null)
|
|
|
|
|
-- clamp to page BBox
|
|
|
|
|
if used.x0 < 0 then used.x0 = 0 end
|
|
|
|
|
if used.x1 > pwidth then used.x1 = pwidth end
|
|
|
|
|
if used.y0 < 0 then used.y0 = 0 end
|
|
|
|
|
if used.y1 > pheight then used.y1 = pheight end
|
2021-05-04 21:13:24 +00:00
|
|
|
|
DocCache:insert(hash, CacheItem:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
|
ubbox = used,
|
2021-05-03 03:20:14 +00:00
|
|
|
|
size = 256, -- might be closer to 160
|
2014-03-13 13:52:43 +00:00
|
|
|
|
})
|
|
|
|
|
page:close()
|
|
|
|
|
return used
|
2012-05-18 23:13:53 +00:00
|
|
|
|
end
|
2014-01-18 07:04:24 +00:00
|
|
|
|
|
|
|
|
|
function PdfDocument:getPageLinks(pageno)
|
2019-09-07 15:15:12 +00:00
|
|
|
|
local hash = "pglinks|"..self.file.."|"..self.reflowable_font_size.."|"..pageno
|
2021-05-04 21:13:24 +00:00
|
|
|
|
local cached = DocCache:check(hash)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
if cached then
|
|
|
|
|
return cached.links
|
|
|
|
|
end
|
|
|
|
|
local page = self._document:openPage(pageno)
|
|
|
|
|
local links = page:getPageLinks()
|
2021-05-04 21:13:24 +00:00
|
|
|
|
DocCache:insert(hash, CacheItem:new{
|
2014-03-13 13:52:43 +00:00
|
|
|
|
links = links,
|
2021-05-03 03:20:14 +00:00
|
|
|
|
size = 64 + (8 * 32 * #links),
|
2014-03-13 13:52:43 +00:00
|
|
|
|
})
|
|
|
|
|
page:close()
|
|
|
|
|
return links
|
2014-01-18 07:04:24 +00:00
|
|
|
|
end
|
2014-01-21 03:59:17 +00:00
|
|
|
|
|
2021-03-29 03:11:02 +00:00
|
|
|
|
-- returns nil if file is not a pdf, true if document is a writable pdf, false else
|
|
|
|
|
function PdfDocument:_checkIfWritable()
|
|
|
|
|
local suffix = util.getFileNameSuffix(self.file)
|
|
|
|
|
if string.lower(suffix) ~= "pdf" then return nil end
|
|
|
|
|
if self.is_writable == nil then
|
|
|
|
|
local handle = io.open(self.file, 'r+b')
|
|
|
|
|
self.is_writable = handle ~= nil
|
|
|
|
|
if handle then handle:close() end
|
|
|
|
|
end
|
|
|
|
|
return self.is_writable
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function _quadpointsFromPboxes(pboxes)
|
|
|
|
|
-- will also need mupdf_h.lua to be evaluated once
|
|
|
|
|
-- but this is guaranteed at this point
|
|
|
|
|
local n = #pboxes
|
|
|
|
|
local quadpoints = ffi.new("float[?]", 8*n)
|
|
|
|
|
for i=1, n do
|
|
|
|
|
-- The order must be left bottom, right bottom, left top, right top.
|
|
|
|
|
-- https://bugs.ghostscript.com/show_bug.cgi?id=695130
|
|
|
|
|
quadpoints[8*i-8] = pboxes[i].x
|
|
|
|
|
quadpoints[8*i-7] = pboxes[i].y + pboxes[i].h
|
|
|
|
|
quadpoints[8*i-6] = pboxes[i].x + pboxes[i].w
|
|
|
|
|
quadpoints[8*i-5] = pboxes[i].y + pboxes[i].h
|
|
|
|
|
quadpoints[8*i-4] = pboxes[i].x
|
|
|
|
|
quadpoints[8*i-3] = pboxes[i].y
|
|
|
|
|
quadpoints[8*i-2] = pboxes[i].x + pboxes[i].w
|
|
|
|
|
quadpoints[8*i-1] = pboxes[i].y
|
|
|
|
|
end
|
|
|
|
|
return quadpoints, n
|
|
|
|
|
end
|
|
|
|
|
|
2021-07-18 17:56:19 +00:00
|
|
|
|
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
|
|
|
|
|
|
2014-02-01 16:16:51 +00:00
|
|
|
|
function PdfDocument:saveHighlight(pageno, item)
|
2021-03-23 09:31:52 +00:00
|
|
|
|
local can_write = self:_checkIfWritable()
|
|
|
|
|
if can_write ~= true then return can_write end
|
2019-05-14 15:57:59 +00:00
|
|
|
|
|
2014-08-24 07:16:01 +00:00
|
|
|
|
self.is_edited = true
|
2021-03-29 03:11:02 +00:00
|
|
|
|
local quadpoints, n = _quadpointsFromPboxes(item.pboxes)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
local page = self._document:openPage(pageno)
|
2018-06-02 16:10:55 +00:00
|
|
|
|
local annot_type = C.PDF_ANNOT_HIGHLIGHT
|
2014-03-13 13:52:43 +00:00
|
|
|
|
if item.drawer == "lighten" then
|
2018-06-02 16:10:55 +00:00
|
|
|
|
annot_type = C.PDF_ANNOT_HIGHLIGHT
|
2014-03-13 13:52:43 +00:00
|
|
|
|
elseif item.drawer == "underscore" then
|
2018-06-02 16:10:55 +00:00
|
|
|
|
annot_type = C.PDF_ANNOT_UNDERLINE
|
2014-03-13 13:52:43 +00:00
|
|
|
|
elseif item.drawer == "strikeout" then
|
2022-01-25 20:39:03 +00:00
|
|
|
|
annot_type = C.PDF_ANNOT_STRIKE_OUT
|
2014-03-13 13:52:43 +00:00
|
|
|
|
end
|
2021-07-18 17:56:19 +00:00
|
|
|
|
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)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
page:close()
|
2021-07-18 17:56:19 +00:00
|
|
|
|
self:resetTileCacheValidity()
|
2014-02-01 16:16:51 +00:00
|
|
|
|
end
|
|
|
|
|
|
2021-03-29 03:11:02 +00:00
|
|
|
|
function PdfDocument:deleteHighlight(pageno, item)
|
2021-03-23 09:31:52 +00:00
|
|
|
|
local can_write = self:_checkIfWritable()
|
|
|
|
|
if can_write ~= true then return can_write end
|
|
|
|
|
|
|
|
|
|
self.is_edited = true
|
2021-03-29 03:11:02 +00:00
|
|
|
|
local quadpoints, n = _quadpointsFromPboxes(item.pboxes)
|
2021-03-23 09:31:52 +00:00
|
|
|
|
local page = self._document:openPage(pageno)
|
|
|
|
|
local annot = page:getMarkupAnnotation(quadpoints, n)
|
|
|
|
|
if annot ~= nil then
|
|
|
|
|
page:deleteMarkupAnnotation(annot)
|
2021-07-18 17:56:19 +00:00
|
|
|
|
self:resetTileCacheValidity()
|
2021-03-23 09:31:52 +00:00
|
|
|
|
end
|
|
|
|
|
page:close()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PdfDocument:updateHighlightContents(pageno, item, contents)
|
|
|
|
|
local can_write = self:_checkIfWritable()
|
|
|
|
|
if can_write ~= true then return can_write end
|
|
|
|
|
|
|
|
|
|
self.is_edited = true
|
2021-03-29 03:11:02 +00:00
|
|
|
|
local quadpoints, n = _quadpointsFromPboxes(item.pboxes)
|
2021-03-23 09:31:52 +00:00
|
|
|
|
local page = self._document:openPage(pageno)
|
|
|
|
|
local annot = page:getMarkupAnnotation(quadpoints, n)
|
|
|
|
|
if annot ~= nil then
|
|
|
|
|
page:updateMarkupAnnotation(annot, contents)
|
2021-07-18 17:56:19 +00:00
|
|
|
|
self:resetTileCacheValidity()
|
2021-03-23 09:31:52 +00:00
|
|
|
|
end
|
|
|
|
|
page:close()
|
|
|
|
|
end
|
|
|
|
|
|
2014-02-01 16:16:51 +00:00
|
|
|
|
function PdfDocument:writeDocument()
|
2016-12-29 08:10:38 +00:00
|
|
|
|
logger.info("writing document to", self.file)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
self._document:writeDocument(self.file)
|
2014-02-01 16:16:51 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PdfDocument:close()
|
2021-05-20 17:09:54 +00:00
|
|
|
|
-- NOTE: We can't just rely on Document:close's return code for that, as we need self._document
|
|
|
|
|
-- in :writeDocument, and it would have been destroyed.
|
|
|
|
|
local DocumentRegistry = require("document/documentregistry")
|
|
|
|
|
if DocumentRegistry:getReferenceCount(self.file) == 1 then
|
|
|
|
|
-- We're the final reference to this Document instance.
|
|
|
|
|
if self.is_edited then
|
|
|
|
|
self:writeDocument()
|
|
|
|
|
end
|
2014-03-13 13:52:43 +00:00
|
|
|
|
end
|
2021-05-20 17:09:54 +00:00
|
|
|
|
|
2014-03-13 13:52:43 +00:00
|
|
|
|
Document.close(self)
|
2014-02-01 16:16:51 +00:00
|
|
|
|
end
|
|
|
|
|
|
2016-02-12 14:55:02 +00:00
|
|
|
|
function PdfDocument:getProps()
|
|
|
|
|
local props = self._document:getMetadata()
|
|
|
|
|
if props.title == "" then
|
|
|
|
|
local startPos = util.lastIndexOf(self.file, "%/")
|
|
|
|
|
if startPos > 0 then
|
|
|
|
|
props.title = string.sub(self.file, startPos + 1, -5) --remove extension .pdf
|
|
|
|
|
else
|
|
|
|
|
props.title = string.sub(self.file, 0, -5)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
props.authors = props.author
|
|
|
|
|
props.series = ""
|
|
|
|
|
props.language = ""
|
2017-07-01 09:41:27 +00:00
|
|
|
|
props.keywords = props.keywords
|
|
|
|
|
props.description = props.subject
|
2016-02-12 14:55:02 +00:00
|
|
|
|
return props
|
|
|
|
|
end
|
|
|
|
|
|
2014-01-21 03:59:17 +00:00
|
|
|
|
function PdfDocument:getLinkFromPosition(pageno, pos)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getLinkFromPosition(self, pageno, pos)
|
2014-01-21 03:59:17 +00:00
|
|
|
|
end
|
2012-05-18 23:13:53 +00:00
|
|
|
|
|
2014-05-15 08:10:45 +00:00
|
|
|
|
function PdfDocument:clipPagePNGFile(pos0, pos1, pboxes, drawer, filename)
|
|
|
|
|
return self.koptinterface:clipPagePNGFile(self, pos0, pos1, pboxes, drawer, filename)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function PdfDocument:clipPagePNGString(pos0, pos1, pboxes, drawer)
|
|
|
|
|
return self.koptinterface:clipPagePNGString(self, pos0, pos1, pboxes, drawer)
|
|
|
|
|
end
|
|
|
|
|
|
2013-04-14 07:16:42 +00:00
|
|
|
|
function PdfDocument:getPageBBox(pageno)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getPageBBox(self, pageno)
|
2013-04-14 07:16:42 +00:00
|
|
|
|
end
|
|
|
|
|
|
2013-01-03 14:24:38 +00:00
|
|
|
|
function PdfDocument:getPageDimensions(pageno, zoom, rotation)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:getPageDimensions(self, pageno, zoom, rotation)
|
2013-01-03 14:24:38 +00:00
|
|
|
|
end
|
|
|
|
|
|
2014-08-27 03:07:25 +00:00
|
|
|
|
function PdfDocument:getCoverPageImage()
|
|
|
|
|
return self.koptinterface:getCoverPageImage(self)
|
|
|
|
|
end
|
|
|
|
|
|
2014-11-17 09:58:25 +00:00
|
|
|
|
function PdfDocument:findText(pattern, origin, reverse, caseInsensitive, page)
|
|
|
|
|
return self.koptinterface:findText(self, pattern, origin, reverse, caseInsensitive, page)
|
|
|
|
|
end
|
|
|
|
|
|
2021-09-23 15:13:18 +00:00
|
|
|
|
function PdfDocument:renderPage(pageno, rect, zoom, rotation, gamma, render_mode, hinting)
|
|
|
|
|
return self.koptinterface:renderPage(self, pageno, rect, zoom, rotation, gamma, render_mode, hinting)
|
2013-01-03 14:24:38 +00:00
|
|
|
|
end
|
|
|
|
|
|
2013-03-12 12:26:02 +00:00
|
|
|
|
function PdfDocument:hintPage(pageno, zoom, rotation, gamma, render_mode)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:hintPage(self, pageno, zoom, rotation, gamma, render_mode)
|
2013-03-12 12:26:02 +00:00
|
|
|
|
end
|
|
|
|
|
|
2013-02-20 06:32:51 +00:00
|
|
|
|
function PdfDocument:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
|
2014-03-13 13:52:43 +00:00
|
|
|
|
return self.koptinterface:drawPage(self, target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
|
2013-01-03 14:24:38 +00:00
|
|
|
|
end
|
|
|
|
|
|
2013-10-18 20:38:07 +00:00
|
|
|
|
function PdfDocument:register(registry)
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
--- Document types ---
|
|
|
|
|
registry:addProvider("cbt", "application/vnd.comicbook+tar", self, 100)
|
|
|
|
|
registry:addProvider("cbz", "application/vnd.comicbook+zip", self, 100)
|
2021-02-07 18:11:45 +00:00
|
|
|
|
registry:addProvider("cbz", "application/x-cbz", self, 100) -- Alternative mimetype for OPDS.
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
registry:addProvider("epub", "application/epub+zip", self, 50)
|
2020-03-29 12:38:07 +00:00
|
|
|
|
registry:addProvider("epub3", "application/epub+zip", self, 50)
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
registry:addProvider("fb2", "application/fb2", self, 80)
|
|
|
|
|
registry:addProvider("htm", "text/html", self, 90)
|
|
|
|
|
registry:addProvider("html", "text/html", self, 90)
|
|
|
|
|
registry:addProvider("pdf", "application/pdf", self, 100)
|
|
|
|
|
registry:addProvider("tar", "application/x-tar", self, 10)
|
2020-10-03 13:07:07 +00:00
|
|
|
|
registry:addProvider("xhtml", "application/xhtml+xml", self, 90)
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
registry:addProvider("xml", "application/xml", self, 10)
|
|
|
|
|
registry:addProvider("xps", "application/oxps", self, 100)
|
2018-02-02 20:21:52 +00:00
|
|
|
|
registry:addProvider("zip", "application/zip", self, 20)
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
|
|
|
|
|
--- Picture types ---
|
|
|
|
|
registry:addProvider("gif", "image/gif", self, 90)
|
|
|
|
|
-- MS HD Photo == JPEG XR
|
|
|
|
|
registry:addProvider("hdp", "image/vnd.ms-photo", self, 90)
|
|
|
|
|
registry:addProvider("j2k", "image/jp2", self, 90)
|
|
|
|
|
registry:addProvider("jp2", "image/jp2", self, 90)
|
|
|
|
|
registry:addProvider("jpeg", "image/jpeg", self, 90)
|
|
|
|
|
registry:addProvider("jpg", "image/jpeg", self, 90)
|
|
|
|
|
-- JPEG XR
|
|
|
|
|
registry:addProvider("jxr", "image/jxr", self, 90)
|
|
|
|
|
registry:addProvider("pam", "image/x-portable-arbitrarymap", self, 90)
|
|
|
|
|
registry:addProvider("pbm", "image/x‑portable‑bitmap", self, 90)
|
|
|
|
|
registry:addProvider("pgm", "image/x‑portable‑bitmap", self, 90)
|
|
|
|
|
registry:addProvider("png", "image/png", self, 90)
|
|
|
|
|
registry:addProvider("pnm", "image/x‑portable‑bitmap", self, 90)
|
2018-02-02 20:21:52 +00:00
|
|
|
|
registry:addProvider("ppm", "image/x‑portable‑bitmap", self, 90)
|
2022-09-11 17:53:07 +00:00
|
|
|
|
registry:addProvider("svg", "image/svg+xml", self, 80)
|
[feat] DocumentRegistry: add getProviders() and preferred by weight (#3651)
This is step one toward "open with".
References https://github.com/koreader/koreader/issues/3345
* Fix up some mimetypes
* Add XHTML to supported filetypes
* Add a few image files to MuPDF
* ".bmp",
* ".gif",
* ".hdp",
* ".j2k",
* ".jp2",
* ".jpeg",
* ".jpg",
* ".jpx",
* ".jxr",
* ".pam",
* ".pbm",
* ".pgm",
* ".png",
* ".pnm",
* ".ppm",
* ".tif",
* ".tiff",
* ".wdp",
2018-01-31 19:49:21 +00:00
|
|
|
|
registry:addProvider("tif", "image/tiff", self, 90)
|
|
|
|
|
registry:addProvider("tiff", "image/tiff", self, 90)
|
|
|
|
|
-- Windows Media Photo == JPEG XR
|
|
|
|
|
registry:addProvider("wdp", "image/vnd.ms-photo", self, 90)
|
2013-10-18 20:38:07 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return PdfDocument
|