diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua b/Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua new file mode 100644 index 00000000000..e1c0de74f37 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/meta-blb.lua @@ -0,0 +1,322 @@ +if not modules then modules = { } end modules ['meta-blb'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- This could be integrated in other modules but for me it also serves +-- as an example of usign the plugin mechanism. + +local tonumber = tonumber + +local setmetatableindex = table.setmetatableindex +local insert, remove = table.insert, table.remove +local formatters = string.formatters + +local topoints = number.topoints +local mpprint = mp.print +local mpinteger = mp.integer +local mppoints = mp.points +local mptriplet = mp.triplet +local mptripletpoints = mp.tripletpoints + +local nuts = nodes.nuts +local hpack = nuts.hpack +local setbox = nuts.setbox +local getwhd = nuts.getwhd +local getwidth = nuts.getwidth +local toutf = nuts.toutf + +local trace = false +local report = logs.reporter("metapost","blobs") + +trackers.register("metapost.blobs", function(v) trace = v end) + +local allblobs = { } + +local function newcategory(t,k) + if trace then + report("new category %a",k) + end + local v = { + name = k, + text = "", + blobs = { }, + } + t[k] = v + return v +end + +local texblobs = setmetatableindex(newcategory) + +local function blob_raw_reset(category) + -- we need to keep the allblobs + if category then + if trace then + report("reset category %a",category) + end + texblobs[category] = nil + else + if trace then + report("reset all") + end + texblobs = setmetatableindex(newcategory) + end +end + +local function blob_raw_dimensions(i) + local blob = allblobs[i] + if blob then + return getwhd(blob) + else + return 0, 0, 0 + end +end + +local function blob_raw_content(i) + return allblobs[i] +end + +local function blob_raw_toutf(i) + return toutf(allblobs[i]) +end + +local function blob_raw_wipe(i) + allblobs[i] = false +end + +mp.mf_blob_raw_dimensions = blob_raw_dimensions +mp.mf_blob_raw_content = blob_raw_content +mp.mf_blob_raw_reset = blob_raw_reset +mp.mf_blob_raw_wipe = blob_raw_wipe +mp.mf_blob_raw_toutf = blob_raw_toutf + +function mp.mf_blob_new(category,text) + if trace then + report("category %a, text %a",category,text) + end + texblobs[category].text = text +end + +function mp.mf_blob_add(category,blob) + local tb = texblobs[category].blobs + local tn = #allblobs + 1 + blob = hpack(blob) + allblobs[tn] = blob + tb[#tb+1] = tn + if trace then + report("category %a, blob %a set, content %a",category,tn,blob_raw_toutf(tn)) + end +end + +function mp.mf_blob_width(category,i) + local index = texblobs[category].blobs[i] + local blob = allblobs[index] + if blob then + mppoints(getwidth(blob) or 0) + else + mpinteger(0) + end +end + +function mp.mf_blob_size(category,i) + mpprint(#texblobs[category].blobs or 0) +end + +function mp.mf_blob_index(category,i) + mpprint(texblobs[category].blobs[i] or 0) +end + +function mp.mf_blob_dimensions(category,i) + local index = texblobs[category].blobs[i] + local blob = allblobs[index] + if blob then + mptripletpoints(getwhd(blob)) + else + mptriplet(0,0,0) + end +end + +local sxsy = metapost.sxsy +local cm = metapost.cm + +local f_f = formatters["%.6F"] + +directives.register("pdf.stripzeros",function() + f_f = formatters["%.6N"] +end) + +local function injectblob(object,blob) + local sx, rx, ry, sy, tx, ty = cm(object) + local wd, ht, dp = blob_raw_dimensions(blob) + if wd then + object.path = false + object.color = false + object.grouped = true + object.istext = true + return function() + if trace then + report("injecting blob %a, width %p, heigth %p, depth %p, text %a",blob,wd,ht,dp,blob_raw_toutf(blob)) + end + context.MPLIBgetblobscaledcm(blob, + f_f(sx), f_f(rx), f_f(ry), + f_f(sy), f_f(tx), f_f(ty), + sxsy(wd,ht,dp)) + end + end +end + +-- mp.mf_blob_inject = injectblob + +local function getblob(box,blob) + setbox(box,blob_raw_content(blob)) + blob_raw_wipe(blob) +end + +interfaces.implement { + name = "mpgetblob", + actions = getblob, + arguments = { "integer", "integer" }, +} + +-- the plug: + + +local function reset() + blob_raw_reset() +end + +local function process(object,prescript,before,after) +-- if prescript.tb_stage == "inject" then + local tb_blob = tonumber(prescript.tb_blob) + if tb_blob then + before[#before+1] = injectblob(object,tb_blob) + end +-- end +end + +metapost.installplugin { + name = "texblob", + reset = reset, + process = process, +} + +-- Here follows an example of usage of the above: a more modern +-- version of followokens (in meta-imp-txt.mkiv). + +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes + +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern + +local fontkern_code = kerncodes.fontkern +local italickern_code = kerncodes.italickern + +local a_fontkern = attributes.private("fontkern") + +local nuts = nodes.nuts +local takebox = nuts.takebox +local getlist = nuts.getlist +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local setlink = nuts.setlink +local setlist = nuts.setlist +local getnext = nuts.getnext +local flatten_list = nuts.flatten_discretionaries +local remove_node = nuts.remove +local flush_node = nuts.flush + +local addblob = mp.mf_blob_add +local newblob = mp.mf_blob_new + +local visible_codes = { + [nodecodes.glyph] = true, + [nodecodes.glue] = true, + [nodecodes.hlist] = true, + [nodecodes.vlist] = true, + [nodecodes.rule] = true, +} + +local function initialize(category,box) + local wrap = takebox(box) + if wrap then + local head = getlist(wrap) + local tail = nil + local temp = nil + if head then + local n = { } + local s = 0 + head = flatten_list(head) + local current = head + while current do + local id = getid(current) + if visible_codes[id] then + head, current, tail = remove_node(head,current) + s = s + 1 + n[s] = tail + elseif id == kern_code then + local subtype = getsubtype(current) + if subtype == fontkern_code or subtype == italickern_code then -- or current[a_fontkern] + head, current, temp = remove_node(head,current) + setlink(tail,temp) + else + head, current, temp = remove_node(head,current) + s = s + 1 + n[s] = temp + end + elseif id == glue_code then + head, current, temp = remove_node(head,current) + s = s + 1 + n[s] = temp + else + current = getnext(current) + end + end + for i=1,s do + n[i] = addblob(category,n[i]) + end + setlist(wrap,head) + end + flush_node(wrap) + end +end + +interfaces.implement { + name = "MPLIBconvertfollowtext", + arguments = { "integer","integer" }, + actions = initialize, +} + +local mp_category = 0 +local mp_str = "" + +function mp.mf_inject_blob(category,str) + newblob(category,str) -- only for tracing + mp_category = category + mp_str = str + tex.runtoks("mpblobtext") +end + +interfaces.implement { + name = "mpblobtext", + actions = function() + context.MPLIBfollowtext(mp_category,mp_str) + end +} + +local process = function(object,prescript,before,after) + if prescript.ft_category then + object.path = false + object.color = false + object.grouped = true + object.istext = true + end +end + +metapost.installplugin { + name = "followtext", + process = process, +} |