More compact float representation
This commit is contained in:
parent
7ffc299c16
commit
463f240670
@ -1,9 +1,15 @@
|
|||||||
local pdf = pdf
|
local pdf = pdf
|
||||||
local pdfvariable = pdf.variable
|
local pdfvariable = pdf.variable
|
||||||
|
|
||||||
local writer = require'luametalatex-nodewriter'
|
local writer = require'luametalatex-nodewriter'
|
||||||
local newpdf = require'luametalatex-pdf'
|
local newpdf = require'luametalatex-pdf'
|
||||||
local nametree = require'luametalatex-pdf-nametree'
|
local nametree = require'luametalatex-pdf-nametree'
|
||||||
local build_fontdir = require'luametalatex-pdf-font'
|
local build_fontdir = require'luametalatex-pdf-font'
|
||||||
|
|
||||||
|
local utils = require'luametalatex-pdf-utils'
|
||||||
|
local strip_floats = utils.strip_floats
|
||||||
|
local to_bp = utils.to_bp
|
||||||
|
|
||||||
local pdfname, pfile
|
local pdfname, pfile
|
||||||
local fontdirs = setmetatable({}, {__index=function(t, k)t[k] = pfile:getobj() return t[k] end})
|
local fontdirs = setmetatable({}, {__index=function(t, k)t[k] = pfile:getobj() return t[k] end})
|
||||||
local usedglyphs = {}
|
local usedglyphs = {}
|
||||||
@ -62,7 +68,7 @@ token.luacmd("shipout", function()
|
|||||||
local out, resources, annots = writer(pfile, list, fontdirs, usedglyphs, colorstacks)
|
local out, resources, annots = writer(pfile, list, fontdirs, usedglyphs, colorstacks)
|
||||||
cur_page = nil
|
cur_page = nil
|
||||||
local content = pfile:stream(nil, '', out)
|
local content = pfile:stream(nil, '', out)
|
||||||
pfile:indirect(page, string.format([[<</Type/Page/Parent %i 0 R/Contents %i 0 R/MediaBox[0 %i %i %i]/Resources<<%s%s>>%s%s>>]], parent, content, -math.ceil(list.depth/65781.76), math.ceil(list.width/65781.76), math.ceil(list.height/65781.76), resources, pdfvariable.pageresources, annots, pdfvariable.pageattr))
|
pfile:indirect(page, string.format([[<</Type/Page/Parent %i 0 R/Contents %i 0 R/MediaBox[0 %i %i %i]/Resources<<%s%s>>%s%s>>]], parent, content, -math.ceil(to_bp(list.depth)), math.ceil(to_bp(list.width)), math.ceil(to_bp(list.height)), resources, pdfvariable.pageresources, annots, pdfvariable.pageattr))
|
||||||
node.flush_list(list)
|
node.flush_list(list)
|
||||||
token.put_next(reset_deadcycles)
|
token.put_next(reset_deadcycles)
|
||||||
token.scan_token()
|
token.scan_token()
|
||||||
@ -190,9 +196,6 @@ function pdf.newcolorstack(default, mode, page)
|
|||||||
}
|
}
|
||||||
return idx
|
return idx
|
||||||
end
|
end
|
||||||
local function sp2bp(sp)
|
|
||||||
return sp/65781.76
|
|
||||||
end
|
|
||||||
local function projected(m, x, y, w)
|
local function projected(m, x, y, w)
|
||||||
w = w or 1
|
w = w or 1
|
||||||
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]
|
||||||
@ -253,14 +256,15 @@ local function write_link(p, link)
|
|||||||
local quadStr = {}
|
local quadStr = {}
|
||||||
for i=1,#quads,8 do
|
for i=1,#quads,8 do
|
||||||
local x1, y1, x4, y4, x2, y2, x3, y3 = table.unpack(quads, i, i+7)
|
local x1, y1, x4, y4, x2, y2, x3, y3 = table.unpack(quads, i, i+7)
|
||||||
x1, y1, x2, y2, x3, y3, x4, y4 = sp2bp(x1), sp2bp(y1), sp2bp(x2), sp2bp(y2), sp2bp(x3), sp2bp(y3), sp2bp(x4), sp2bp(y4)
|
x1, y1, x2, y2, x3, y3, x4, y4 = to_bp(x1), to_bp(y1), to_bp(x2), to_bp(y2), to_bp(x3), to_bp(y3), to_bp(x4), to_bp(y4)
|
||||||
quadStr[i//8+1] = string.format("%f %f %f %f %f %f %f %f", x1, y1, x2, y2, x3, y3, x4, y4)
|
quadStr[i//8+1] = string.format("%f %f %f %f %f %f %f %f", x1, y1, x2, y2, x3, y3, x4, y4)
|
||||||
minX = math.min(minX, x1, x2, x3, x4)
|
minX = math.min(minX, x1, x2, x3, x4)
|
||||||
minY = math.min(minY, y1, y2, y3, y4)
|
minY = math.min(minY, y1, y2, y3, y4)
|
||||||
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("<</Type/Annot/Rect[%f %f %f %f]/QuadPoints[%s]%s>>", minX-.2, minY-.2, maxX+.2, maxY+.2, table.concat(quadStr, ' '), attr))
|
local boxes = strip_floats(string.format("/Rect[%f %f %f %f]/QuadPoints[%s]", minX-.2, minY-.2, maxX+.2, maxY+.2, table.concat(quadStr, ' ')))
|
||||||
|
pfile:indirect(link.objnum, string.format("<</Type/Annot%s%s>>", boxes, 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
|
||||||
@ -387,9 +391,9 @@ local dest_whatsit = declare_whatsit('pdf_dest', function(prop, p, n, x, y)
|
|||||||
local x, y = projected(p.matrix, x, y)
|
local x, y = projected(p.matrix, x, y)
|
||||||
local zoom = prop.xyz_zoom
|
local zoom = prop.xyz_zoom
|
||||||
if zoom then
|
if zoom then
|
||||||
data = string.format("[%i 0 R/XYZ %.5f %.5f %.3f]", cur_page, sp2bp(x-off), sp2bp(y+off), prop.zoom/1000)
|
data = string.format("[%i 0 R/XYZ %.5f %.5f %.3f]", cur_page, to_bp(x-off), to_bp(y+off), prop.zoom/1000)
|
||||||
else
|
else
|
||||||
data = string.format("[%i 0 R/XYZ %.5f %.5f null]", cur_page, sp2bp(x-off), sp2bp(y+off))
|
data = string.format("[%i 0 R/XYZ %.5f %.5f null]", cur_page, to_bp(x-off), to_bp(y+off))
|
||||||
end
|
end
|
||||||
elseif dest_type == "fitr" then
|
elseif dest_type == "fitr" then
|
||||||
local m = p.matrix
|
local m = p.matrix
|
||||||
@ -399,28 +403,28 @@ local dest_whatsit = declare_whatsit('pdf_dest', function(prop, p, n, x, y)
|
|||||||
local urx, ury = projected(x+prop.width, x + prop.height)
|
local urx, ury = projected(x+prop.width, x + prop.height)
|
||||||
local left, lower, right, upper = math.min(llx, lrx, ulx, urx), math.min(lly, lry, uly, ury),
|
local left, lower, right, upper = math.min(llx, lrx, ulx, urx), math.min(lly, lry, uly, ury),
|
||||||
math.max(llx, lrx, ulx, urx), math.max(lly, lry, uly, ury)
|
math.max(llx, lrx, ulx, urx), math.max(lly, lry, uly, ury)
|
||||||
data = string.format("[%i 0 R/FitR %.5f %.5f %.5f %.5f]", cur_page, sp2bp(left-off), sp2bp(lower-off), sp2bp(right+off), sp2bp(upper+off))
|
data = string.format("[%i 0 R/FitR %.5f %.5f %.5f %.5f]", cur_page, to_bp(left-off), to_bp(lower-off), to_bp(right+off), to_bp(upper+off))
|
||||||
elseif dest_type == "fit" then
|
elseif dest_type == "fit" then
|
||||||
data = string.format("[%i 0 R/Fit]", cur_page)
|
data = string.format("[%i 0 R/Fit]", cur_page)
|
||||||
elseif dest_type == "fith" then
|
elseif dest_type == "fith" then
|
||||||
local x, y = projected(p.matrix, x, y)
|
local x, y = projected(p.matrix, x, y)
|
||||||
data = string.format("[%i 0 R/FitH %.5f]", cur_page, sp2bp(y+off))
|
data = string.format("[%i 0 R/FitH %.5f]", cur_page, to_bp(y+off))
|
||||||
elseif dest_type == "fitv" then
|
elseif dest_type == "fitv" then
|
||||||
local x, y = projected(p.matrix, x, y)
|
local x, y = projected(p.matrix, x, y)
|
||||||
data = string.format("[%i 0 R/FitV %.5f]", cur_page, sp2bp(x-off))
|
data = string.format("[%i 0 R/FitV %.5f]", cur_page, to_bp(x-off))
|
||||||
elseif dest_type == "fitb" then
|
elseif dest_type == "fitb" then
|
||||||
data = string.format("[%i 0 R/FitB]", cur_page)
|
data = string.format("[%i 0 R/FitB]", cur_page)
|
||||||
elseif dest_type == "fitbh" then
|
elseif dest_type == "fitbh" then
|
||||||
local x, y = projected(p.matrix, x, y)
|
local x, y = projected(p.matrix, x, y)
|
||||||
data = string.format("[%i 0 R/FitBH %.5f]", cur_page, sp2bp(y+off))
|
data = string.format("[%i 0 R/FitBH %.5f]", cur_page, to_bp(y+off))
|
||||||
elseif dest_type == "fitbv" then
|
elseif dest_type == "fitbv" then
|
||||||
local x, y = projected(p.matrix, x, y)
|
local x, y = projected(p.matrix, x, y)
|
||||||
data = string.format("[%i 0 R/FitBV %.5f]", cur_page, sp2bp(x-off))
|
data = string.format("[%i 0 R/FitBV %.5f]", cur_page, to_bp(x-off))
|
||||||
end
|
end
|
||||||
if pfile:written(dests[id]) then
|
if pfile:written(dests[id]) then
|
||||||
texio.write_nl(string.format("Duplicate destination %q", id))
|
texio.write_nl(string.format("Duplicate destination %q", id))
|
||||||
else
|
else
|
||||||
dests[id] = pfile:indirect(dests[id], data)
|
dests[id] = pfile:indirect(dests[id], strip_floats(data))
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
local refobj_whatsit = declare_whatsit('pdf_refobj', function(prop, p, n, x, y)
|
local refobj_whatsit = declare_whatsit('pdf_refobj', function(prop, p, n, x, y)
|
||||||
|
@ -31,6 +31,10 @@ local rangedimensions = direct.rangedimensions
|
|||||||
local traverse_id = direct.traverse_id
|
local traverse_id = direct.traverse_id
|
||||||
local getdata = direct.getdata
|
local getdata = direct.getdata
|
||||||
|
|
||||||
|
local utils = require'luametalatex-pdf-utils'
|
||||||
|
local strip_floats = utils.strip_floats
|
||||||
|
local to_bp = utils.to_bp
|
||||||
|
|
||||||
local pdf_font_map = require'luametalatex-pdf-font-deduplicate'
|
local pdf_font_map = require'luametalatex-pdf-font-deduplicate'
|
||||||
local get_whatsit_handler = require'luametalatex-whatsits'.handler
|
local get_whatsit_handler = require'luametalatex-whatsits'.handler
|
||||||
|
|
||||||
@ -72,14 +76,11 @@ local whatsithandler = (function()
|
|||||||
end)
|
end)
|
||||||
end)()
|
end)()
|
||||||
local glyph, text, page, cm_pending = 1, 2, 3, 4
|
local glyph, text, page, cm_pending = 1, 2, 3, 4
|
||||||
local gsub = string.gsub
|
|
||||||
local function projected_point(m, x, y, w)
|
local function projected_point(m, x, y, w)
|
||||||
w = w or 1
|
w = w or 1
|
||||||
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 sp2bp(sp)
|
|
||||||
return sp/65781.76
|
|
||||||
end
|
|
||||||
local fontnames = setmetatable({}, {__index = function(t, k) local res = format("F%i", k) t[k] = res return res end})
|
local fontnames = setmetatable({}, {__index = function(t, k) local res = format("F%i", k) t[k] = res return res end})
|
||||||
local topage
|
local topage
|
||||||
local function totext(p, fid)
|
local function totext(p, fid)
|
||||||
@ -98,7 +99,7 @@ local function totext(p, fid)
|
|||||||
|
|
||||||
local pdf_fid = pdf_font_map[fid]
|
local pdf_fid = pdf_font_map[fid]
|
||||||
p.resources.Font[fontnames[pdf_fid]] = p.fontdirs[pdf_fid]
|
p.resources.Font[fontnames[pdf_fid]] = p.fontdirs[pdf_fid]
|
||||||
p.strings[#p.strings+1] = format("/F%i %f Tf 0 Tr", pdf_fid, sp2bp(f.size)) -- TODO: Setting the mode, width, etc.
|
p.strings[#p.strings+1] = strip_floats(format("/F%i %f Tf 0 Tr", pdf_fid, to_bp(f.size))) -- TODO: Setting the mode, width, etc.
|
||||||
p.font.usedglyphs = p.usedglyphs[pdf_fid]
|
p.font.usedglyphs = p.usedglyphs[pdf_fid]
|
||||||
|
|
||||||
p.font.fid = fid
|
p.font.fid = fid
|
||||||
@ -127,7 +128,7 @@ function topage(p)
|
|||||||
elseif last == cm_pending then
|
elseif last == cm_pending then
|
||||||
local pending = p.pending_matrix
|
local pending = p.pending_matrix
|
||||||
if pending[1] ~= 1 or pending[2] ~= 0 or pending[3] ~= 0 or pending[4] ~= 1 or pending[5] ~= 0 or pending[6] ~= 0 then
|
if pending[1] ~= 1 or pending[2] ~= 0 or pending[3] ~= 0 or pending[4] ~= 1 or pending[5] ~= 0 or pending[6] ~= 0 then
|
||||||
p.strings[#p.strings+1] = format("%f %f %f %f %f %f cm", pending[1], pending[2], pending[3], pending[4], sp2bp(pending[5]), sp2bp(pending[6]))
|
p.strings[#p.strings+1] = strip_floats(format("%f %f %f %f %f %f cm", pending[1], pending[2], pending[3], pending[4], to_bp(pending[5]), to_bp(pending[6])))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error[[Unknown mode]]
|
error[[Unknown mode]]
|
||||||
@ -147,14 +148,14 @@ local function toglyph(p, fid, x, y, exfactor)
|
|||||||
end
|
end
|
||||||
if totext(p, fid) or exfactor ~= p.font.exfactor then
|
if totext(p, fid) or exfactor ~= p.font.exfactor then
|
||||||
p.font.exfactor = exfactor
|
p.font.exfactor = exfactor
|
||||||
p.strings[#p.strings+1] = gsub(format("%f 0.0 %f %f %f %f Tm", p.font.extend * (1+exfactor/1000000), p.font.slant, p.font.squeeze, sp2bp(x), sp2bp(y)), '%.?0+ ', ' ')
|
p.strings[#p.strings+1] = strip_floats(format("%f 0.0 %f %f %f %f Tm", p.font.extend * (1+exfactor/1000000), p.font.slant, p.font.squeeze, to_bp(x), to_bp(y)))
|
||||||
else
|
else
|
||||||
-- To invert the text transformation matrix (extend 0 0;slant squeeze 0;0 0 1)
|
-- To invert the text transformation matrix (extend 0 0;slant squeeze 0;0 0 1)
|
||||||
-- we have to apply (extend^-1 0 0;-slant*extend^-1*squeeze^-1 squeeze^-1 0;0 0 1). (extend has to include expansion)
|
-- we have to apply (extend^-1 0 0;-slant*extend^-1*squeeze^-1 squeeze^-1 0;0 0 1). (extend has to include expansion)
|
||||||
-- We optimize slightly by separating some steps
|
-- We optimize slightly by separating some steps
|
||||||
local dx, dy = sp2bp((x - p.pos.lx)), sp2bp(y - p.pos.ly) / p.font.squeeze
|
local dx, dy = to_bp((x - p.pos.lx)), to_bp(y - p.pos.ly) / p.font.squeeze
|
||||||
dx = (dx-p.font.slant*dy) / (p.font.extend * (1+exfactor/1000000))
|
dx = (dx-p.font.slant*dy) / (p.font.extend * (1+exfactor/1000000))
|
||||||
p.strings[#p.strings+1] = gsub(format("%f %f Td", dx, dy), '%.?0+ ', ' ')
|
p.strings[#p.strings+1] = strip_floats(format("%f %f Td", dx, dy))
|
||||||
end
|
end
|
||||||
p.pos.lx, p.pos.ly, p.pos.x, p.pos.y = x, y, x, y
|
p.pos.lx, p.pos.ly, p.pos.x, p.pos.y = x, y, x, y
|
||||||
p.mode = glyph
|
p.mode = glyph
|
||||||
@ -287,7 +288,7 @@ function nodehandler.rule(p, n, x, y, outer)
|
|||||||
error[[We can't handle outline rules yet]]
|
error[[We can't handle outline rules yet]]
|
||||||
else
|
else
|
||||||
topage(p)
|
topage(p)
|
||||||
p.strings[#p.strings+1] = gsub(format("%f %f %f %f re f", sp2bp(x), sp2bp(y - getdepth(n)), sp2bp(getwidth(n)), sp2bp(getdepth(n) + getheight(n))), '%.?0+ ', ' ')
|
p.strings[#p.strings+1] = strip_floats(format("%f %f %f %f re f", to_bp(x), to_bp(y - getdepth(n)), to_bp(getwidth(n)), to_bp(getdepth(n) + getheight(n))))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -13,9 +13,10 @@ local boxmap = {
|
|||||||
art = "ArtBox",
|
art = "ArtBox",
|
||||||
}
|
}
|
||||||
|
|
||||||
-- FIXME:
|
local utils = require'luametalatex-pdf-utils'
|
||||||
local function to_sp(bp) return bp*65781.76//1 end
|
local strip_floats = utils.strip_floats
|
||||||
local function to_bp(sp) return sp/65781.76 end
|
local to_sp = utils.to_sp
|
||||||
|
local to_bp = utils.to_bp
|
||||||
|
|
||||||
local function get_box(page, box)
|
local function get_box(page, box)
|
||||||
box = boxmap[box]
|
box = boxmap[box]
|
||||||
@ -74,7 +75,8 @@ function pdf_functions.write(pfile, img)
|
|||||||
local file = open_pdfe(img)
|
local file = open_pdfe(img)
|
||||||
local page = pdfe.getpage(file, img.page)
|
local page = pdfe.getpage(file, img.page)
|
||||||
local bbox = img.bbox
|
local bbox = img.bbox
|
||||||
local dict = string.format("/Subtype/Form/BBox[%f %f %f %f]/Resources %s", to_bp(bbox[1]), to_bp(bbox[2]), to_bp(bbox[3]), to_bp(bbox[4]), pdfe_deepcopy(file, img.filepath, pfile, pdfe.getfromdictionary(page, 'Resources')))
|
local dict = strip_floats(string.format("/Subtype/Form/BBox[%f %f %f %f]/Resources ", to_bp(bbox[1]), to_bp(bbox[2]), to_bp(bbox[3]), to_bp(bbox[4])))
|
||||||
|
dict = dict .. pdfe_deepcopy(file, img.filepath, pfile, pdfe.getfromdictionary(page, 'Resources'))
|
||||||
local content, raw = page.Contents
|
local content, raw = page.Contents
|
||||||
-- Three cases: Contents is a stream, so copy the stream (Remember to copy filter if necessary)
|
-- Three cases: Contents is a stream, so copy the stream (Remember to copy filter if necessary)
|
||||||
-- Contents is an array of streams, so append all the streams as a new stream
|
-- Contents is an array of streams, so append all the streams as a new stream
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
local strip_floats = require'luametalatex-pdf-utils'.strip_floats
|
||||||
|
|
||||||
local function ignore() end
|
local function ignore() end
|
||||||
local parse = setmetatable({
|
local parse = setmetatable({
|
||||||
-- IHDR = below,
|
-- IHDR = below,
|
||||||
@ -131,11 +133,11 @@ function parse.cHRM(buf, i, after, ctxt)
|
|||||||
local X_C, Z_C = Y_C*x_B/y_B, Y_C*((1-x_B)/y_B-1)
|
local X_C, Z_C = Y_C*x_B/y_B, Y_C*((1-x_B)/y_B-1)
|
||||||
|
|
||||||
local X_W, Y_W, Z_W = X_A+X_B+X_C, Y_A+Y_B+Y_C, Z_A+Z_B+Z_C
|
local X_W, Y_W, Z_W = X_A+X_B+X_C, Y_A+Y_B+Y_C, Z_A+Z_B+Z_C
|
||||||
ctxt.cHRM = string.format("/WhitePoint[%f %f %f]/Matrix[%f %f %f %f %f %f %f %f %f]",
|
ctxt.cHRM = strip_floats(string.format("/WhitePoint[%f %f %f]/Matrix[%f %f %f %f %f %f %f %f %f]",
|
||||||
X_W, Y_W, Z_W,
|
X_W, Y_W, Z_W,
|
||||||
X_A, Y_A, Z_A,
|
X_A, Y_A, Z_A,
|
||||||
X_B, Y_B, Z_B,
|
X_B, Y_B, Z_B,
|
||||||
X_C, Y_C, Z_C)
|
X_C, Y_C, Z_C))
|
||||||
end
|
end
|
||||||
function parse.IDAT(buf, i, after, ctxt)
|
function parse.IDAT(buf, i, after, ctxt)
|
||||||
ctxt.IDAT = ctxt.IDAT or {}
|
ctxt.IDAT = ctxt.IDAT or {}
|
||||||
@ -277,7 +279,7 @@ function png_functions.write(pfile, img)
|
|||||||
elseif colortype & 2 == 2 then -- RGB
|
elseif colortype & 2 == 2 then -- RGB
|
||||||
if t.cHRM then
|
if t.cHRM then
|
||||||
local gamma = t.gAMA or 2.2
|
local gamma = t.gAMA or 2.2
|
||||||
gamma = gamma and string.format("/Gamma[%f %f %f]", gamma, gamma, gamma) or ''
|
gamma = gamma and strip_floats(string.format("/Gamma[%f %f %f]", gamma, gamma, gamma)) or ''
|
||||||
colorspace = string.format("[/CalRGB<<%s%s>>]", t.cHRM, gamma)
|
colorspace = string.format("[/CalRGB<<%s%s>>]", t.cHRM, gamma)
|
||||||
else
|
else
|
||||||
if t.gAMA then
|
if t.gAMA then
|
||||||
|
@ -17,9 +17,9 @@ local imagetypes = setmetatable({}, {__index = function(t, k)
|
|||||||
return module
|
return module
|
||||||
end})
|
end})
|
||||||
|
|
||||||
-- FIXME:
|
local utils = require'luametalatex-pdf-utils'
|
||||||
local function to_sp(bp) return bp*65781.76//1 end
|
local strip_floats = utils.strip_floats
|
||||||
local function to_bp(sp) return sp/65781.76 end
|
local to_bp = utils.to_bp
|
||||||
|
|
||||||
local liberal_keys = {height = true, width = true, depth = true, transform = true}
|
local liberal_keys = {height = true, width = true, depth = true, transform = true}
|
||||||
local real_images = {}
|
local real_images = {}
|
||||||
@ -171,7 +171,7 @@ local function do_img(data, p, n, x, y)
|
|||||||
b, d, f = b*yscale, d*yscale, f*yscale
|
b, d, f = b*yscale, d*yscale, f*yscale
|
||||||
e, f = to_bp(x + e), to_bp(y - depth + f)
|
e, f = to_bp(x + e), to_bp(y - depth + f)
|
||||||
p.resources.XObject['Im' .. tostring(img.objnum)] = img.objnum
|
p.resources.XObject['Im' .. tostring(img.objnum)] = img.objnum
|
||||||
pdf.write('page', string.format('q %f %f %f %f %f %f cm /Im%i Do Q', a, b, c, d, e, f, img.objnum), nil, nil, p)
|
pdf.write('page', strip_floats(string.format('q %f %f %f %f %f %f cm /Im%i Do Q', a, b, c, d, e, f, img.objnum)), nil, nil, p)
|
||||||
end
|
end
|
||||||
local ruleid = node.id'rule'
|
local ruleid = node.id'rule'
|
||||||
local ruletypes = node.subtypes'rule'
|
local ruletypes = node.subtypes'rule'
|
||||||
|
@ -4,7 +4,9 @@ local pdfvariable = pdf.variable
|
|||||||
-- XForms currently have the form {width, height, depth, objnum, attributes, list, margin}
|
-- XForms currently have the form {width, height, depth, objnum, attributes, list, margin}
|
||||||
local xforms = {}
|
local xforms = {}
|
||||||
|
|
||||||
local function to_bp(sp) return sp/65781.76 end
|
local utils = require'luametalatex-pdf-utils'
|
||||||
|
local strip_floats = utils.strip_floats
|
||||||
|
local to_bp = utils.to_bp
|
||||||
|
|
||||||
local function shipout(pfile, xform, fontdirs, usedglyphs)
|
local function shipout(pfile, xform, fontdirs, usedglyphs)
|
||||||
local list, margin = xform.list, xform.margin
|
local list, margin = xform.list, xform.margin
|
||||||
@ -16,7 +18,8 @@ local function shipout(pfile, xform, fontdirs, usedglyphs)
|
|||||||
if pdfvariable.xformattr ~= '' or pdfvariable.xformresources ~= '' then
|
if pdfvariable.xformattr ~= '' or pdfvariable.xformresources ~= '' then
|
||||||
texio.write_nl('term and log', 'WARNING (savedboxresource shipout): Ignoring unsupported PDF variables xformattr and xformresources. Specify resources and attributes for specific XForms instead.')
|
texio.write_nl('term and log', 'WARNING (savedboxresource shipout): Ignoring unsupported PDF variables xformattr and xformresources. Specify resources and attributes for specific XForms instead.')
|
||||||
end
|
end
|
||||||
local dict = string.format('/Subtype/Form/BBox[%f %f %f %f]/Resources<<%s%s>>%s', -to_bp(margin), -to_bp(list.depth+margin), to_bp(list.width+margin), to_bp(list.height+margin), resources, xform.resources or '', xform.attributes or '')
|
local bbox = strip_floats(string.format('/BBox[%f %f %f %f]', -to_bp(margin), -to_bp(list.depth+margin), to_bp(list.width+margin), to_bp(list.height+margin)))
|
||||||
|
local dict = string.format('/Subtype/Form%s/Resources<<%s%s>>%s', bbox, resources, xform.resources or '', xform.attributes or '')
|
||||||
node.flush_list(list)
|
node.flush_list(list)
|
||||||
xform.list = nil
|
xform.list = nil
|
||||||
local objnum = pfile:stream(xform.objnum, dict, out)
|
local objnum = pfile:stream(xform.objnum, dict, out)
|
||||||
@ -89,10 +92,10 @@ local function do_box(data, p, n, x, y)
|
|||||||
local width, height, depth = node.direct.getwhd(n)
|
local width, height, depth = node.direct.getwhd(n)
|
||||||
local xscale, yscale = width / xform.width, (height+depth) / (xform.height+xform.depth)
|
local xscale, yscale = width / xform.width, (height+depth) / (xform.height+xform.depth)
|
||||||
p.resources.XObject['Fm' .. tostring(data)] = objnum
|
p.resources.XObject['Fm' .. tostring(data)] = objnum
|
||||||
pdf.write('page', string.format('q %f 0 0 %f %f %f cm /Fm%i Do Q',
|
pdf.write('page', strip_floats(string.format('q %f 0 0 %f %f %f cm /Fm%i Do Q',
|
||||||
xscale, yscale,
|
xscale, yscale,
|
||||||
to_bp(x), to_bp(y-depth+yscale*xform.depth),
|
to_bp(x), to_bp(y-depth+yscale*xform.depth),
|
||||||
data), nil, nil, p)
|
data)), nil, nil, p)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
23
luametalatex-pdf-utils.lua
Normal file
23
luametalatex-pdf-utils.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
local l = lpeg or require'lpeg'
|
||||||
|
local trailing_zeros = l.P'0'^0 * -l.R'09'
|
||||||
|
local strip_floats_patt = l.Cs((1-l.R'09' +
|
||||||
|
(l.R'09')^1 * (l.P'.' * trailing_zeros / '' + l.P'.' * (l.R'09'-trailing_zeros)^1 * (trailing_zeros/''))^-1)^0)
|
||||||
|
local match = l.match
|
||||||
|
|
||||||
|
local function strip_floats(s)
|
||||||
|
return match(strip_floats_patt, s)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function to_bp(sp)
|
||||||
|
return sp/65781.76
|
||||||
|
end
|
||||||
|
|
||||||
|
local function to_sp(bp)
|
||||||
|
return (bp*65781.76+.5)//1
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
strip_floats = strip_floats,
|
||||||
|
to_bp = to_bp,
|
||||||
|
to_sp = to_sp,
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
local format = string.format
|
local format = string.format
|
||||||
local gsub = string.gsub
|
|
||||||
local byte = string.byte
|
local byte = string.byte
|
||||||
local pack = string.pack
|
local pack = string.pack
|
||||||
local error = error
|
local error = error
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local format = string.format
|
local format = string.format
|
||||||
|
local strip_floats = require'luametalatex-pdf-utils'.strip_floats
|
||||||
local pdfe = pdfe
|
local pdfe = pdfe
|
||||||
local l = lpeg
|
local l = lpeg
|
||||||
local regularchar = 1-l.S'\0\t\n\r\f ()<>[]{}/%#'
|
local regularchar = 1-l.S'\0\t\n\r\f ()<>[]{}/%#'
|
||||||
@ -17,7 +18,7 @@ local deepcopy_lookup deepcopy_lookup = {
|
|||||||
return format("%d", i)
|
return format("%d", i)
|
||||||
end,
|
end,
|
||||||
function(_, pdf, f) -- 4: number
|
function(_, pdf, f) -- 4: number
|
||||||
return format("%f", f)
|
return strip_floats(format("%f", f), "%.?0+[ %]]", "")
|
||||||
end,
|
end,
|
||||||
function(_, pdf, name) -- 5: name
|
function(_, pdf, name) -- 5: name
|
||||||
return nameescape:match(name)
|
return nameescape:match(name)
|
||||||
|
Loading…
Reference in New Issue
Block a user