Initial attempt at vf library
This commit is contained in:
parent
32c9fec9cc
commit
05c1977d9a
@ -375,46 +375,48 @@ function nodehandler.glue(p, n, x, y, outer, origin, level) -- Naturally this is
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local vf_state
|
||||||
|
|
||||||
local pdf_escape = require'luametalatex-pdf-escape'.escape_raw
|
local pdf_escape = require'luametalatex-pdf-escape'.escape_raw
|
||||||
local match = lpeg.match
|
local match = lpeg.match
|
||||||
local function do_commands(p, c, f, fid, x, y, outer, ...)
|
local function do_commands(p, c, f, cid, fid, x, y, outer, x0, level, direction)
|
||||||
local fonts = f.fonts
|
local fonts = f.fonts
|
||||||
local stack, current_font = {}, fonts[1]
|
local stack, current_font = {}, fonts and fonts[1] and fonts[1].id or fid
|
||||||
for _, cmd in ipairs(c.commands) do
|
for _, cmd in ipairs(c.commands) do
|
||||||
if cmd[1] == "node" then
|
if cmd[1] == "node" then
|
||||||
local cmd = cmd[2]
|
local cmd = cmd[2]
|
||||||
assert(node.type(cmd))
|
assert(node.type(cmd))
|
||||||
cmd = todirect(cmd)
|
cmd = todirect(cmd)
|
||||||
nodehandler[getid(cmd)](p, cmd, x, y, nil, ...)
|
nodehandler[getid(cmd)](p, cmd, x, y, outer, x0, level, direction)
|
||||||
x = x + getwidth(cmd)
|
x = x + getwidth(cmd)
|
||||||
elseif cmd[1] == "font" then
|
elseif cmd[1] == "font" then
|
||||||
current_font = assert(fonts[cmd[2]], "invalid font requested")
|
current_font = assert(fonts[cmd[2]], "invalid font requested").id
|
||||||
elseif cmd[1] == "char" then
|
elseif cmd[1] == "char" then
|
||||||
local n = direct.new'glyph'
|
local n = direct.new'glyph'
|
||||||
setsubtype(n, 256)
|
setsubtype(n, 256)
|
||||||
setfont(n, current_font.id, cmd[2])
|
setfont(n, current_font, cmd[2])
|
||||||
nodehandler.glyph(p, n, x, y, outer, ...)
|
nodehandler.glyph(p, n, x, y, outer, x0, level, direction)
|
||||||
x = x + getwidth(n)
|
x = x + getwidth(n)
|
||||||
direct.free(n)
|
direct.free(n)
|
||||||
elseif cmd[1] == "slot" then
|
elseif cmd[1] == "slot" then
|
||||||
current_font = assert(fonts[cmd[2]], "invalid font requested")
|
current_font = assert(fonts[cmd[2]], "invalid font requested").id
|
||||||
local n = direct.new'glyph'
|
local n = direct.new'glyph'
|
||||||
setsubtype(n, 256)
|
setsubtype(n, 256)
|
||||||
setfont(n, current_font.id, cmd[3])
|
setfont(n, current_font, cmd[3])
|
||||||
nodehandler.glyph(p, n, x, y, outer, ...)
|
nodehandler.glyph(p, n, x, y, outer, x0, level, direction)
|
||||||
x = x + getwidth(n)
|
x = x + getwidth(n)
|
||||||
direct.free(n)
|
direct.free(n)
|
||||||
elseif cmd[1] == "rule" then
|
elseif cmd[1] == "rule" then
|
||||||
local n = direct.new'rule'
|
local n = direct.new'rule'
|
||||||
setheight(n, cmd[2])
|
setheight(n, cmd[3])
|
||||||
setwidth(n, cmd[3])
|
setwidth(n, cmd[2])
|
||||||
nodehandler.rule(p, n, x, y, outer, ...)
|
nodehandler.rule(p, n, x, y, outer, x0, level, direction)
|
||||||
x = x + getwidth(n)
|
x = x + getwidth(n)
|
||||||
direct.free(n)
|
direct.free(n)
|
||||||
elseif cmd[1] == "left" then
|
elseif cmd[1] == "right" then
|
||||||
x = x + cmd[2]
|
x = x + cmd[2]
|
||||||
elseif cmd[1] == "down" then
|
elseif cmd[1] == "down" then
|
||||||
y = y + cmd[2]
|
y = y - cmd[2] -- TODO: Review sign
|
||||||
elseif cmd[1] == "push" then
|
elseif cmd[1] == "push" then
|
||||||
stack[#stack + 1] = {x, y}
|
stack[#stack + 1] = {x, y}
|
||||||
elseif cmd[1] == "pop" then
|
elseif cmd[1] == "pop" then
|
||||||
@ -424,12 +426,18 @@ local function do_commands(p, c, f, fid, x, y, outer, ...)
|
|||||||
elseif cmd[1] == "special" then
|
elseif cmd[1] == "special" then
|
||||||
error[[specials aren't supported yet]] -- TODO
|
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)
|
local mode, literal = cmd[2], cmd[3]
|
||||||
|
if not literal then mode, literal = "origin", mode end
|
||||||
|
pdf.write(mode, literal, 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)
|
local old_vf_state = vf_state -- This can be triggered recursivly in odd cases
|
||||||
|
vf_state = {p, stack, current_font, x, y, outer, x0, level, direction}
|
||||||
|
pdf._latelua(p, x, y, cmd, fid, cid)
|
||||||
|
current_font, x, y = vf_state[3], vf_state[4], vf_state[5]
|
||||||
|
vf_state = old_vf_state
|
||||||
elseif cmd[1] == "image" then
|
elseif cmd[1] == "image" then
|
||||||
error[[images aren't supported yet]] -- TODO
|
error[[images aren't supported yet]] -- TODO
|
||||||
-- ???
|
-- ???
|
||||||
@ -438,18 +446,75 @@ local function do_commands(p, c, f, fid, x, y, outer, ...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- Now we basically duplicate all of that for the `vf` library...
|
||||||
|
vf = {
|
||||||
|
char = function(cid)
|
||||||
|
local n = direct.new'glyph'
|
||||||
|
setsubtype(n, 256)
|
||||||
|
setfont(n, vf_state[3], cid)
|
||||||
|
local x = vf_state[4]
|
||||||
|
nodehandler.glyph(vf_state[1], n, x, vf_state[5], vf_state[6], vf_state[7], vf_state[8], vf_state[9])
|
||||||
|
vf_state[4] = x + getwidth(n)
|
||||||
|
direct.free(n)
|
||||||
|
end,
|
||||||
|
down = function(dy)
|
||||||
|
vf_state[5] = vf_state[5] - dy -- TODO: Review sign
|
||||||
|
end,
|
||||||
|
fontid = function(fid)
|
||||||
|
vf_state[3] = fid
|
||||||
|
end,
|
||||||
|
-- image = function(img) -- TODO
|
||||||
|
node = function(n)
|
||||||
|
assert(node.type(n))
|
||||||
|
cmd = todirect(n)
|
||||||
|
local x = vf_state[4]
|
||||||
|
nodehandler[getid(n)](vf_state[1], n, x, vf_state[5], vf_state[6], vf_state[7], vf_state[8], vf_state[9])
|
||||||
|
vf_state[4] = x + getwidth(n)
|
||||||
|
end,
|
||||||
|
nop = function() end,
|
||||||
|
pop = function()
|
||||||
|
local stack = vf_state[2]
|
||||||
|
local top = stack[#stack]
|
||||||
|
stack[#stack] = nil
|
||||||
|
vf_state[4], vf_state[5] = top[1], top[2]
|
||||||
|
end,
|
||||||
|
push = function()
|
||||||
|
local stack = vf_state[2]
|
||||||
|
stack[#stack + 1] = vf_state[4], vf_state[5]
|
||||||
|
end,
|
||||||
|
right = function(dx)
|
||||||
|
vf_state[4] = vf_state[4] + dx
|
||||||
|
end,
|
||||||
|
rule = function(width, height)
|
||||||
|
local n = direct.new'rule'
|
||||||
|
setheight(n, height)
|
||||||
|
setwidth(n, width)
|
||||||
|
local x = vf_state[4]
|
||||||
|
nodehandler.rule(vf_state[1], n, x, vf_state[5], vf_state[6], vf_state[7], vf_state[8], vf_state[9])
|
||||||
|
vf_state[4] = x + getwidth(n)
|
||||||
|
direct.free(n)
|
||||||
|
end,
|
||||||
|
special = function()
|
||||||
|
error[[specials aren't supported yet]] -- TODO
|
||||||
|
end,
|
||||||
|
pdf = function(mode, literal)
|
||||||
|
if not literal then mode, literal = "origin", mode end
|
||||||
|
pdf.write(mode, literal, vf_state[4], vf_state[5], vf_state[1])
|
||||||
|
end,
|
||||||
|
}
|
||||||
function nodehandler.glyph(p, n, x, y, outer, x0, level, direction)
|
function nodehandler.glyph(p, n, x, y, outer, x0, level, direction)
|
||||||
if getfont(n) ~= p.vfont.fid then
|
if getfont(n) ~= p.vfont.fid then
|
||||||
p.vfont.fid = getfont(n)
|
p.vfont.fid = getfont(n)
|
||||||
p.vfont.font = font.getfont(getfont(n)) or font.fonts[getfont(n)]
|
p.vfont.font = font.getfont(getfont(n)) or font.fonts[getfont(n)]
|
||||||
end
|
end
|
||||||
local f, fid = p.vfont.font, p.vfont.fid
|
local f, fid = p.vfont.font, p.vfont.fid
|
||||||
local c = f.characters[getchar(n)]
|
local cid = getchar(n)
|
||||||
|
local c = f.characters[cid]
|
||||||
if not c then
|
if not c then
|
||||||
texio.write_nl("Missing character")
|
texio.write_nl("Missing character")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if c.commands then return do_commands(p, c, f, fid, x, y, outer, x0, level, direction) end
|
if c.commands then return do_commands(p, c, f, cid, fid, x, y, outer, x0, level, direction) end
|
||||||
local xoffset, yoffset = getoffsets(n)
|
local xoffset, yoffset = getoffsets(n)
|
||||||
toglyph(p, getfont(n), x + (direction == 1 and -xoffset or xoffset), y + yoffset, getexpansion(n))
|
toglyph(p, getfont(n), x + (direction == 1 and -xoffset or xoffset), y + yoffset, getexpansion(n))
|
||||||
local index = c.index
|
local index = c.index
|
||||||
|
Loading…
Reference in New Issue
Block a user