Literal support + fixes

This commit is contained in:
Marcel Krüger 2019-07-20 14:53:24 +02:00
parent 3aacd0fddb
commit 047997b46d
2 changed files with 40 additions and 22 deletions

View File

@ -63,6 +63,9 @@ function pdf.newcolorstack(default, mode, page)
} }
return idx return idx
end end
local function do_literal(prop, p, n, x, y)
pdf.write(prop.mode, prop.data, x, y, p)
end
local function do_colorstack(prop, p, n, x, y) local function do_colorstack(prop, p, n, x, y)
local colorstack = prop.colorstack local colorstack = prop.colorstack
local stack local stack
@ -111,13 +114,19 @@ local function write_colorstack()
}) })
node.write(whatsit) node.write(whatsit)
end end
local function scan_literal_mode()
return token.scan_keyword"direct" and "direct"
or token.scan_keyword"page" and "page"
or token.scan_keyword"text" and "text"
or token.scan_keyword"direct" and "direct"
or token.scan_keyword"raw" and "raw"
or "origin"
end
token.luacmd("pdffeedback", function() token.luacmd("pdffeedback", function()
if token.scan_keyword"colorstackinit" then if token.scan_keyword"colorstackinit" then
local page = token.scan_keyword'page' local page = token.scan_keyword'page'
or (token.scan_keyword'nopage' and false) -- If you want to pass "page" as mode or (token.scan_keyword'nopage' and false) -- If you want to pass "page" as mode
local mode = token.scan_keyword'direct' and 'direct' local mode = scan_literal_mode()
or token.scan_keyword'page' and 'page'
or 'origin'
local default = token.scan_string() local default = token.scan_string()
tex.sprint(tostring(pdf.newcolorstack(default, mode, page))) tex.sprint(tostring(pdf.newcolorstack(default, mode, page)))
else else
@ -129,9 +138,19 @@ end)
token.luacmd("pdfextension", function() token.luacmd("pdfextension", function()
if token.scan_keyword"colorstack" then if token.scan_keyword"colorstack" then
write_colorstack() write_colorstack()
elseif token.scan_keyword"literal" then
local mode = scan_literal_mode()
local literal = token.scan_string()
local whatsit = node.new(whatsit_id, whatsits.pdf_literal)
node.setproperty(whatsit, {
handle = do_literal,
mode = mode,
data = literal,
})
node.write(whatsit)
else else
-- The following error message gobbles the next word as a side effect. -- The following error message gobbles the next word as a side effect.
-- This is intentional to make error-recovery easier. -- This is intentional to make error-recovery easier.
error(string.format("Unknown PDF extension %s", token.scan_word())) error(string.format("Unknown PDF extension %s", token.scan_word()))
end end
end) end, "protected")

View File

@ -83,7 +83,7 @@ local function totext(p, fid)
end end
local inspect = require'inspect' local inspect = require'inspect'
local function show(t) print(inspect(t)) end local function show(t) print(inspect(t)) end
local function topage(p) function topage(p)
local last = p.mode local last = p.mode
if last == page then return end if last == page then return end
if last <= text then if last <= text then
@ -372,14 +372,16 @@ local function do_commands(p, c, f, fid, x, y, outer, ...)
stack[#stack] = nil stack[#stack] = nil
x, y = top[1], top[2] x, y = top[1], top[2]
elseif cmd[1] == "special" then elseif cmd[1] == "special" then
-- ??? error[[specials aren't supported yet]] -- TODO
elseif cmd[1] == "pdf" then elseif cmd[1] == "pdf" then
-- ??? pdf.write(cmd[3] and cmd[2] or "origin", cmd[3], x, y, p)
elseif cmd[1] == "lua" then elseif cmd[1] == "lua" then
cmd = cmd[2] cmd = cmd[2]
if type(cmd) == "string" then cmd = load(cmd) end if type(cmd) == "string" then cmd = load(cmd) end
assert(type(cmd) == "function") assert(type(cmd) == "function")
pdf._latelua(p, x, y, cmd, fid, c)
elseif cmd[1] == "image" then elseif cmd[1] == "image" then
error[[images aren't supported yet]] -- TODO
-- ??? -- ???
-- else -- else
-- NOP, comment and invalid commands ignored -- NOP, comment and invalid commands ignored
@ -431,19 +433,7 @@ end
function nodehandler.whatsit(p, n, ...) -- Whatsit? function nodehandler.whatsit(p, n, ...) -- Whatsit?
return whatsithandler[n.subtype](p, n, ...) return whatsithandler[n.subtype](p, n, ...)
end end
function whatsithandler.pdf_literal(p, n, x, y) --[[ -- These use the old whatsit handling system which might get removed.
if n.mode == 2 then
topage(p)
p.strings[#p.strings + 1] = n.data
elseif n.mode == 0 then
write_matrix(p, 1, 0, 0, 1, x, y)
topage(p)
p.strings[#p.strings + 1] = n.data
write_matrix(p, 1, 0, 0, 1, -x, -y)
else
write(format('Literal type %i', n.mode))
end
end
function whatsithandler.pdf_save(p, n, x, y, outer) function whatsithandler.pdf_save(p, n, x, y, outer)
topage(p) topage(p)
p.strings[#p.strings + 1] = 'q' p.strings[#p.strings + 1] = 'q'
@ -471,9 +461,10 @@ function whatsithandler.pdf_end_link(p, n, x, y, outer, _, level)
local links = p.linkcontext local links = p.linkcontext
local link = links[#links] local link = links[#links]
links[#links] = nil links[#links] = nil
if link.level ~= level then error[[Wrong link level]] end if link.level ~= level then error"Wrong link level" end
addlinkpoint(p, link, x, y, outer, true) addlinkpoint(p, link, x, y, outer, true)
end end
]]
local global_p, global_x, global_y local global_p, global_x, global_y
function pdf._latelua(p, x, y, func, ...) function pdf._latelua(p, x, y, func, ...)
global_p, global_x, global_y = p, x, y global_p, global_x, global_y = p, x, y
@ -481,9 +472,17 @@ function pdf._latelua(p, x, y, func, ...)
end end
function pdf.write(mode, text, x, y, p) function pdf.write(mode, text, x, y, p)
x, y, p = x or global_x, y or global_y, p or global_p x, y, p = x or global_x, y or global_y, p or global_p
if mode == "direct" then if mode == "page" then
topage(p) topage(p)
p.strings[#p.strings + 1] = text p.strings[#p.strings + 1] = text
elseif mode == "text" then
topage(p)
p.strings[#p.strings + 1] = text
elseif mode == "direct" then
if p.mode ~= page then
totext(p, p.font.fid)
end
p.strings[#p.strings + 1] = text
elseif mode == "origin" then elseif mode == "origin" then
write_matrix(p, 1, 0, 0, 1, x, y) write_matrix(p, 1, 0, 0, 1, x, y)
topage(p) topage(p)