Experimental support for GoTo actions

This commit is contained in:
Marcel Krüger 2020-06-05 17:38:30 +02:00
parent 581fbca92b
commit cb044ac8e4
1 changed files with 47 additions and 8 deletions

View File

@ -61,6 +61,12 @@ local function write_infodir(p)
end end
return p:indirect(nil, string.format("<<%s%s>>", infodir, additional)) return p:indirect(nil, string.format("<<%s%s>>", infodir, additional))
end end
local function pdf_string(s)
-- Emulate other engines here: If looks like an escaped string, treat it as such. Otherwise, add parenthesis.
return s:match("^%(.*%)$") or s:match("^<.*>$") or '(' .. s .. ')'
end
callback.register("stop_run", function() callback.register("stop_run", function()
if not pfile then if not pfile then
return return
@ -120,15 +126,46 @@ local function projected(m, x, y, w)
return x*m[1] + y*m[3] + w*m[5], x*m[2] + y*m[4] + w*m[6] return x*m[1] + y*m[3] + w*m[5], x*m[2] + y*m[4] + w*m[6]
end end
-- local function get_action_attr(p, action) local function get_action_attr(p, action)
-- if action.action_type == 3 then local action_type = action.action_type
-- return action.data if action_type == 3 then return action.data end
-- elseif action.action_type == 2 then local action_attr = "/Subtype/Link/A<<"
local file = action.file
if file then
action_attr = action_attr .. '/F' .. pdf_string(file)
local newwindow = action.new_window
if newwindow and newwindow > 0 then
action_attr = action_attr .. '/NewWindow ' .. (newwindow == 1 and 'true' or 'false')
end
end
if action_type == 2 then
error[[FIXME: Threads are currently unsupported]] -- TODO
elseif action_type == 0 then
error[[FIXME]]
elseif action_type == 1 then -- GoTo
local id = action.id
if file then
assert(type(id) == "string")
action_attr = action_attr .. "/S/GoToR/D" .. pdf_string(id)
else
local dest = dests[id]
if not dest then
dest = pfile:getobj()
dests[id] = dest
end
if type(id) == "string" then
action_attr = action_attr .. "/S/GoTo/D" .. pdf_string(id)
else
action_attr = string.format("%s/S/GoTo/D %i 0 R", action_attr, dest)
end
end
end
return action_attr
end
local function write_link(p, link) local function write_link(p, link)
local quads = link.quads local quads = link.quads
local minX, maxX, minY, maxY = math.huge, -math.huge, math.huge, -math.huge local minX, maxX, minY, maxY = math.huge, -math.huge, math.huge, -math.huge
assert(link.action.action_type == 3) -- TODO: Other types local attr = link.attr .. get_action_attr(link.action)
local attr = link.attr .. link.action.data
assert(#quads%8==0) assert(#quads%8==0)
local quadStr = {} local quadStr = {}
for i=1,#quads,8 do for i=1,#quads,8 do
@ -140,7 +177,7 @@ local function write_link(p, link)
maxX = math.max(maxX, x1, x2, x3, x4) maxX = math.max(maxX, x1, x2, x3, x4)
maxY = math.max(maxY, y1, y2, y3, y4) maxY = math.max(maxY, y1, y2, y3, y4)
end end
pfile:indirect(link.objnum, string.format("<</Rect[%f %f %f %f]/QuadPoints[%s]%s>>", minX-.2, minY-.2, maxX+.2, maxY+.2, table.concat(quadStr, ' '), attr)) pfile:indirect(link.objnum, string.format("<</Type/Annot/Rect[%f %f %f %f]/QuadPoints[%s]%s>>", minX-.2, minY-.2, maxX+.2, maxY+.2, table.concat(quadStr, ' '), attr))
for i=1,#quads do quads[i] = nil end for i=1,#quads do quads[i] = nil end
link.objnum = nil link.objnum = nil
end end
@ -344,7 +381,9 @@ local function scan_action()
end end
action.new_window = token.scan_keyword'newwindow' and 1 action.new_window = token.scan_keyword'newwindow' and 1
or token.scan_keyword'nonewwindow' and 2 or token.scan_keyword'nonewwindow' and 2
or 0 if action.new_window and not action.file then
error[[newwindow is only supported for external files]]
end
return action return action
end end
local function scan_literal_mode() local function scan_literal_mode()