diff options
author | Karl Berry <karl@freefriends.org> | 2021-03-06 21:58:15 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-03-06 21:58:15 +0000 |
commit | 974640d66e61e81cb197ad96fdff7b08343e4c5a (patch) | |
tree | 2e1f75f32f312b7f24ba82b4590ae230bcd6f399 /Master/texmf-dist/tex/context/base/mkxl/pack-obj.lmt | |
parent | b4fa72e61230aca75f7f6fbf988821f71edfb6b2 (diff) |
context
git-svn-id: svn://tug.org/texlive/trunk@58167 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/pack-obj.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/pack-obj.lmt | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/pack-obj.lmt b/Master/texmf-dist/tex/context/base/mkxl/pack-obj.lmt new file mode 100644 index 00000000000..f021339b472 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/pack-obj.lmt @@ -0,0 +1,305 @@ +if not modules then modules = { } end modules ['pack-obj'] = { + version = 1.001, + comment = "companion to pack-obj.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>We save object references in the main utility table. jobobjects are +reusable components.</p> +--ldx]]-- + +local context = context +local codeinjections = backends.codeinjections +local ctx_doifelse = commands.doifelse + +local report = logs.reporter("objects") +local trace = false trackers.register("objects",function(v) trace = v end) + +local nuts = nodes.nuts + +local setlink = nuts.setlink +local getlist = nuts.getlist +local setbox = nuts.setbox + +local new_latelua = nuts.pool.latelua + +local settexdimen = tokens.setters.dimen + +local getcount = tex.getcount + +local implement = interfaces.implement +local setmacro = interfaces.setmacro + +local allocate = utilities.storage.allocate + +local collected = allocate() +local tobesaved = allocate() + +local jobobjects = { + collected = collected, + tobesaved = tobesaved, +} + +job.objects = jobobjects + +local function initializer() + collected = jobobjects.collected + tobesaved = jobobjects.tobesaved +end + +job.register('job.objects.collected', tobesaved, initializer, nil) + +local function saveobject(tag,number,page) + local data = { number, page } + tobesaved[tag] = data + collected[tag] = data +end + +local function saveobjectspec(specification) + local tag = specification.tag + local data = { specification.number, specification.page } + tobesaved[tag] = data + collected[tag] = data +end + +local function setobject(tag,number,page) + collected[tag] = { number, page } +end + +local function getobject(tag) + return collected[tag] or tobesaved[tag] +end + +local function getobjectnumber(tag,default) + local o = collected[tag] or tobesaved[tag] + return o and o[1] or default +end + +local function getobjectpage(tag,default) + local o = collected[tag] or tobesaved[tag] + return o and o[2] or default +end + +jobobjects.save = saveobject +jobobjects.set = setobject +jobobjects.get = getobject +jobobjects.number = getobjectnumber +jobobjects.page = getobjectpage + +-- implement { +-- name = "saveobject", +-- actions = saveobject +-- } +-- +-- implement { +-- name = "setobject", +-- actions = setobject, +-- arguments = { "string", "integer", "integer" } +-- } +-- +-- implement { +-- name = "objectnumber", +-- actions = { getobjectnumber, context }, +-- arguments = "2 strings", +-- } +-- +-- implement { +-- name = "objectpage", +-- actions = { getobjectpage, context }, +-- arguments = "2 strings", +-- } +-- +-- implement { +-- name = "doifelseobjectreferencefound", +-- actions = { getobject, commands.doifelse }, +-- arguments = "string" +-- } + +-- if false then +-- -- we can flush the inline ref ourselves now if we want +-- local flush = new_latelua("pdf.flushxform("..index..")") +-- flush.next = list +-- next.prev = flush +-- end + +local data = table.setmetatableindex("table") + +objects = { + data = data, + n = 0, +} + +local objects = objects + +function objects.register(ns,id,b,referenced,offset,mode) + local n = objects.n + 1 + objects.n = n + nodes.handlers.finalizebox(b) + if mode == 0 then + -- tex + data[ns][id] = { + codeinjections.registerboxresource(b), -- a box number + offset, + referenced or false, + mode, + } + else + -- box (backend) + data[ns][id] = { + codeinjections.registerboxresource(b,offset), -- a box number + false, + referenced, + mode, + } + end + if trace then + report("registering object %a (n=%i)",id,n) + end +end + +function objects.restore(ns,id) -- why not just pass a box number here too (ok, we also set offset) + local d = data[ns][id] + if d then + local index = d[1] + local offset = d[2] + local status = d[3] + local mode = d[4] + local hbox = codeinjections.restoreboxresource(index) -- a nut ! + if status then + local list = getlist(hbox) + local page = new_latelua { + action = saveobjectspec, + tag = ns .. "::" .. id, + number = index, + page = getcount("realpageno"), + } + -- list is a rule + setlink(list,page) + end + setbox("objectbox",hbox) + settexdimen("objectoff",offset or 0) + else + setbox("objectbox",nil) + settexdimen("objectoff",0) -- for good old times + end + if trace then + report("restoring object %a",id) + end +end + +function objects.dimensions(index) + local d = data[ns][id] + if d then + return codeinjections.boxresourcedimensions(d[1]) + else + return 0, 0, 0, 0 + end +end + +function objects.reference(ns,id) + local d = data[ns][id] + if d then + return d[1] + else + return getobjectnumber(ns .."::" .. id,0) + end +end + +function objects.page(ns,id) + return getobjectpage(ns .."::" .. id,getcount("realpageno")) +end + +function objects.found(ns,id) + return data[ns][id] +end + +implement { + name = "registerreferencedobject", + arguments = { "string", "string", "integer", true, "dimension", "integer" }, + actions = objects.register, +} + +implement { + name = "registerobject", + arguments = { "string", "string", "integer", false, "dimension", "integer" }, + actions = objects.register, +} + +implement { + name = "restoreobject", + arguments = "2 strings", + actions = objects.restore, +} + +implement { + name = "doifelseobjectfound", + arguments = "2 arguments", + public = true, + protected = true, + actions = function(ns,id) + ctx_doifelse(data[ns][id]) + -- ctx_doifelse(objects.reference(ns,id)) + end, +} + +implement { + name = "doifelseobjectreferencefound", + arguments = "2 arguments", + public = true, + protected = true, + actions = function(ns,id) + -- ctx_doifelse(data[ns][id]) + ctx_doifelse(objects.reference(ns,id)) + end, +} + +implement { + name = "getobjectreference", + arguments = { "argument", "argument", "csname" }, + public = true, + protected = true, + actions = function(ns,id,target) + setmacro(target,objects.reference(ns,id),"global") + end +} + +implement { + name = "getobjectreferencepage", + arguments = { "argument", "argument", "csname" }, + public = true, + protected = true, + actions = function(ns,id,target) + setmacro(target,objects.page(ns,id),"global") + end +} + +implement { + name = "getobjectdimensions", + arguments = "2 arguments", + public = true, + protected = true, + actions = function(ns,id) + local object = data[ns][id] + local w, h, d, o = 0, 0, 0, 0 + if object then + w, h, d, o = codeinjections.boxresourcedimensions(object[1]) + end + settexdimen("objectwd",w or 0) + settexdimen("objectht",h or 0) + settexdimen("objectdp",d or 0) + settexdimen("objectoff",o or #objects > 2 and object[2] or 0) + end +} + +-- for the moment here: + +implement { + name = "registerbackendsymbol", + arguments = { "string", "integer" }, + actions = function(...) + codeinjections.registersymbol(...) + end +} |