diff --git a/luametalatex-pdf-font-node.lua b/luametalatex-pdf-font-node.lua new file mode 100644 index 0000000..8b6016a --- /dev/null +++ b/luametalatex-pdf-font-node.lua @@ -0,0 +1,42 @@ +local writer = require'luametalatex-nodewriter' +local utils = require'luametalatex-pdf-utils' +local to_bp, strip_floats = utils.to_bp, utils.strip_floats +local prepared = {} +return { + buildfont = function(pdf, fontdir, usedcids) + local designsize = fontdir.designsize + local scale = 1/to_bp(designsize) + local bbox = {0, 0, 0, 0} + local matrix = {scale, 0, 0, scale, 0, 0} + local widths = {} + local first_cid = usedcids[1][1]-1 + local charprocs = {} + local prev = 0 + local characters = fontdir.characters + local prepared = assert(prepared[fontdir]) + for i=1,#usedcids do + local used = usedcids[i] + local glyph = characters[used[1]] + for j=prev+1,used[1]-first_cid-1 do + widths[j] = 0 + end + prev = used[1]-first_cid + widths[prev] = to_bp(glyph.width) + charprocs[i] = string.format("/G%i %i 0 R", used[1], prepared[used[1]]) + end + return bbox, matrix, pdf:indirect(nil, strip_floats('[' .. table.concat(widths, ' ') .. ']')), '<<' .. table.concat(charprocs) .. '>>' + end, + prepare = function(fontdir, usedglyphs, pdf, fontdirs, allusedglyphs) + local state = prepared[fontdir] + if not state then + state = {} + prepared[fontdir] = state + end + for gid in next, usedglyphs do if tonumber(gid) and not state[gid] then + local stream, annots + stream, state.resources, annots = writer(pdf, fontdir.characters[gid].node, fontdirs, allusedglyphs, nil, state.resources) + state[gid] = pdf:stream(nil, '', stream) + assert(annots == '') + end end + end, +} diff --git a/luametalatex-pdf-resources.lua b/luametalatex-pdf-resources.lua new file mode 100644 index 0000000..54eac47 --- /dev/null +++ b/luametalatex-pdf-resources.lua @@ -0,0 +1,37 @@ +local format = string.format +local concat = table.concat +local next = next + +local temp_table = {} +local resources_meta = { + __index = function(t, k) + local v = {} + t[k] = v + return v + end, + __call = function(t, additional) + local temp_table = temp_table + local i=1 + local next_init = '<>/%s<<' + i = i+1 + for name, entry in next, entries do + temp_table[i] = format('/%s %i 0 R', name, entry) + i = i+1 + end + end + if i == 1 then return format('<<%s>>', additional or '') end + temp_table[i] = format('>>%s>>', additional or '') + local result = concat(temp_table) + for j=1,i do + temp_table[j] = nil + end + return result + end, +} + +return function(t) + return setmetatable(t or {}, resources_meta) +end