From 9a3e7e7772d6615d513f1536a3456c6cf2b1cedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20Fabian=20Kr=C3=BCger?= Date: Thu, 4 Jun 2020 23:30:46 +0200 Subject: [PATCH] Update pdf_{save,restore,matrix} --- luametalatex-back-pdf.lua | 52 +++++++++++++++++++++++++++++ luametalatex-nodewriter.lua | 65 +++++++++---------------------------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/luametalatex-back-pdf.lua b/luametalatex-back-pdf.lua index a4e490c..2cf54d1 100644 --- a/luametalatex-back-pdf.lua +++ b/luametalatex-back-pdf.lua @@ -114,6 +114,38 @@ end local function sp2bp(sp) return sp/65781.76 end +local function projected(m, x, y, w) + w = w or 1 + return x*m[1] + y*m[3] + w*m[5], x*m[2] + y*m[4] + w*m[6] +end +local do_setmatrix do + local numberpattern = (lpeg.R'09'^0 * ('.' * lpeg.R'09'^0)^-1)/tonumber + local matrixpattern = numberpattern * ' ' * numberpattern * ' ' * numberpattern * ' ' * numberpattern + function whatsithandler.pdf_setmatrix(p, n, x, y, outer) + write_matrix(p, a, b, c, d, e, f) + end + local function do_setmatrix(prop, p, n, x, y, outer) + local m = p.matrix + local a, b, c, d = matrixpattern:match(prop.data) + local e, f = (1-a)*x-c*y, (1-d)*y-b*x -- Emulate that the origin is at x, y for this transformation + -- (We could also first translate by (-x, -y), then apply the matrix + -- and translate back, but this is more direct) + a, b = projected(m, a, b, 0) + c, d = projected(m, c, d, 0) + e, f = projected(m, e, f, 1) + m[1], m[2], m[3], m[4], m[5], m[6] = a, b, c, d, e, f + end +end +local function do_save(prop, p, n, x, y, outer) + pdf.write('page', 'q', x, y, p) + local lastmatrix = p.matrix + p.matrix = {[0] = lastmatrix, table.unpack(lastmatrix)} +end +local function do_restore(prop, p, n, x, y, outer) + -- TODO: Check x, y + pdf.write('page', 'Q', x, y, p) + p.matrix = p.matrix[0] +end local function do_dest(prop, p, n, x, y) -- TODO: Apply matrix assert(cur_page, "Destinations can not appear outside of a page") @@ -246,6 +278,26 @@ token.luacmd("pdfextension", function(_, imm) data = literal, }) node.write(whatsit) + elseif token.scan_keyword"push" then + local whatsit = node.new(whatsit_id, whatsits.pdf_push) + node.setproperty(whatsit, { + handle = do_push, + }) + node.write(whatsit) + elseif token.scan_keyword"setmatrix" then + local matrix = token.scan_string() + local whatsit = node.new(whatsit_id, whatsits.pdf_setmatrix) + node.setproperty(whatsit, { + handle = do_setmatrix, + data = matrix, + }) + node.write(whatsit) + elseif token.scan_keyword"pop" then + local whatsit = node.new(whatsit_id, whatsits.pdf_pop) + node.setproperty(whatsit, { + handle = do_pop, + }) + node.write(whatsit) elseif token.scan_keyword"info" then infodir = infodir .. token.scan_string() elseif token.scan_keyword"catalog" then diff --git a/luametalatex-nodewriter.lua b/luametalatex-nodewriter.lua index c2269a5..5ddbce1 100644 --- a/luametalatex-nodewriter.lua +++ b/luametalatex-nodewriter.lua @@ -74,21 +74,6 @@ local function projected_point(m, x, y, w) w = w or 1 return x*m[1] + y*m[3] + w*m[5], x*m[2] + y*m[4] + w*m[6] end -local function pdfsave(p, x, y) - local lastmatrix = p.matrix - p.matrix = {[0] = lastmatrix, table.unpack(lastmatrix)} -end -local function pdfmatrix(p, a, b, c, d, e, f) - local m = p.matrix - a, b = projected_point(m, a, b, 0) - c, d = projected_point(m, c, d, 0) - e, f = projected_point(m, e, f, 1) - m[1], m[2], m[3], m[4], m[5], m[6] = a, b, c, d, e, f -end -local function pdfrestore(p, x, y) - -- TODO: Check x, y - p.matrix = p.matrix[0] -end local function sp2bp(sp) return sp/65781.76 end @@ -151,21 +136,6 @@ local function toglyph(p, fid, x, y, exfactor) p.mode = glyph p.pending[1] = "[(" end -local function write_matrix(p, a, b, c, d, e, f) - local pending = p.pending_matrix - if p.mode ~= cm_pending then - topage(p) - p.mode = cm_pending - pending[1], pending[2], pending[3], pending[4], pending[5], pending[6] = a, b, c, d, e, f - return - else - a, b = projected_point(pending, a, b, 0) - c, d = projected_point(pending, c, d, 0) - e, f = projected_point(pending, e, f, 1) - pending[1], pending[2], pending[3], pending[4], pending[5], pending[6] = a, b, c, d, e, f - return - end -end local linkcontext = {} -- local function get_action_attr(p, action) -- if action.action_type == 3 then @@ -508,23 +478,6 @@ function nodehandler.whatsit(p, n, ...) -- Whatsit? return whatsithandler[getsubtype(n)](p, n, ...) end --[[ -- These use the old whatsit handling system which might get removed. -function whatsithandler.pdf_save(p, n, x, y, outer) - topage(p) - p.strings[#p.strings + 1] = 'q' - pdfsave(p, x, y) -end -function whatsithandler.pdf_restore(p, n, x, y, outer) - topage(p) - p.strings[#p.strings + 1] = 'Q' - pdfrestore(p, x, y) -end -local numberpattern = (lpeg.R'09'^0 * ('.' * lpeg.R'09'^0)^-1)/tonumber -local matrixpattern = numberpattern * ' ' * numberpattern * ' ' * numberpattern * ' ' * numberpattern -function whatsithandler.pdf_setmatrix(p, n, x, y, outer) - local a, b, c, d = matrixpattern:match(n.data) - local e, f = (1-a)*x-c*y, (1-d)*y-b*x - write_matrix(p, a, b, c, d, e, f) -end function whatsithandler.pdf_start_link(p, n, x, y, outer, _, level) local links = p.linkcontext local link = {quads = {}, attr = n.link_attr, action = n.action, level = level, force_separate = false} -- force_separate should become an option @@ -544,6 +497,20 @@ function pdf._latelua(p, x, y, func, ...) global_p, global_x, global_y = p, x, y return func(...) end +function pdf.write_matrix(a, b, c, d, e, f, p) + e, f, p = e or 0, f or 0, p or global_p + local pending = p.pending_matrix + if p.mode ~= cm_pending then + topage(p) + p.mode = cm_pending + else + a, b = projected_point(pending, a, b, 0) + c, d = projected_point(pending, c, d, 0) + e, f = projected_point(pending, e, f, 1) + end + pending[1], pending[2], pending[3], pending[4], pending[5], pending[6] = a, b, c, d, e, f +end +local write_matrix = pdf.write_matrix function pdf.write(mode, text, x, y, p) x, y, p = x or global_x, y or global_y, p or global_p if mode == "page" then @@ -558,10 +525,10 @@ function pdf.write(mode, text, x, y, p) end p.strings[#p.strings + 1] = text elseif mode == "origin" then - write_matrix(p, 1, 0, 0, 1, x, y) + write_matrix(1, 0, 0, 1, x, y, p) topage(p) p.strings[#p.strings + 1] = text - write_matrix(p, 1, 0, 0, 1, -x, -y) + write_matrix(1, 0, 0, 1, -x, -y, p) else write(format('Literal type %s unsupported', mode)) end