diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt b/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt new file mode 100644 index 00000000000..aa6658606e1 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/trac-riv.lmt @@ -0,0 +1,320 @@ +if not modules then modules = { } end modules ['trac-riv'] = { + version = 1.001, + optimize = true, + comment = "companion to trac-riv.mkxl", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local concat = table.concat +local floor, ceiling = math.floor, math.ceiling +local newindex = lua.newindex + +local nuts = nodes.nuts + +local getbox = nuts.getbox + +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getnext = nuts.getnext +local getwhd = nuts.getwhd +local getwidth = nuts.getwidth +local getkern = nuts.getkern +local getlist = nuts.getlist +local getleader = nuts.getleader +local getreplace = nuts.getreplace +local getheight = nuts.getheight +local getdepth = nuts.getdepth + +local setlink = nuts.setlink +local setlist = nuts.setlist +local setoffsets = nuts.setoffsets +local setkern = nuts.setkern + +local effectiveglue = nuts.effectiveglue + +local setcolor = nodes.tracers.colors.set + +local newrule = nuts.pool.rule +local newkern = nuts.pool.kern + +local nextnode = nuts.traversers.node + +local nodecodes = nodes.nodecodes +local gluecodes = nodes.gluecodes + +local glyph_code <const> = nodecodes.glyph +local disc_code <const> = nodecodes.disc +local penalty_code <const> = nodecodes.penalty +local kern_code <const> = nodecodes.kern +local glue_code <const> = nodecodes.glue +local hlist_code <const> = nodecodes.hlist +local vlist_code <const> = nodecodes.vlist +local math_code <const> = nodecodes.math +local rule_code <const> = nodecodes.rule + +local spaceskip_code <const> = gluecodes.spaceskip +local xspaceskip_code <const> = gluecodes.xspaceskip +local lineskip_code <const> = gluecodes.lineskip +local baselineskip_code <const> = gluecodes.baselineskip + +local fontkern_code <const> = nodes.kerncodes.fontkern +local linelist_code <const> = nodes.listcodes.line + +local unit = 65536 +local step = 2 * unit +local margin = -1 * unit +local skip = 10 * unit +local height = 2 * unit +local depth = 2 * unit + +local function analyze(line,max) + + local width = 0 + local position = 0 + local profile = newindex(max+2,0) + local wd = 0 + local state = 0 + + local function process(current) -- called nested in disc replace + for current, id, subtype in nextnode, current do + if id == glyph_code then + -- wd = getwidth(current) + local w, h, d = getwhd(current) + wd = w + if d <= depth and h <= height then + local n = getnext(current) + if n and getid(n) == glue_code then + local s = getsubtype(n) + if s == spaceskip_code or s == xspaceskip_code then + state = 1 + end + end + end + elseif id == kern_code then + wd = getkern(current) + if wd > 0 and subtype ~= fontkern_code then + state = 1 + end + elseif id == disc_code then + local replace = getreplace(current) + if replace then + process(replace) + end + goto done + elseif id == glue_code then + wd = effectiveglue(current,line) + if wd > 0 and subtype == spaceskip_code or subtype == xspaceskip_code then + state = 1 + end + elseif id == hlist_code then + wd = getwidth(current) + elseif id == vlist_code then + wd = getwidth(current) + elseif id == rule_code then + wd = getwidth(current) + elseif id == math_code then + wd = getkern(current) + getwidth(current) -- surround + state = 1 + else + goto done + end + -- progress + position = width + width = position + wd + p = floor((position - margin)/step + 0.5) + w = floor((width + margin)/step - 0.5) + if p < 0 then + p = 0 + end + if w < 0 then + w = 0 + end + if p > w then + w, p = p, w + end + if state == 1 then + for i=p+1,w+1 do + profile[i] = state + end + state = 0 + end + ::done:: + end + end + + process(getlist(line)) + + return profile + +end + +function builders.profiling.getrivers(specification) + local box = getbox(specification.box) + local head = getlist(box) + if head then + + step = (specification.step or 2 * unit) + margin = (specification.margin or -1 * unit) + skip = (specification.gluethreshold or 10 * unit) + height = (specification.height or 2 * unit) + depth = (specification.depth or 2 * unit) + + local profiles = { } + local max = ceiling(getwidth(box)/step) + 1 + + local p = 0 + + p = p + 1 ; profiles[p] = newindex(max+2,1) + p = p + 1 ; profiles[p] = newindex(max+2,0) + + for current, id, subtype in nextnode, head do + if id == hlist_code then + local amount = getwidth(current) + if amount > 0 then + p = p + 1 ; profiles[p] = analyze(current,max) + end + elseif id == glue_code then + if subtype == baselineskip_code or subtype == lineskip_code then + -- okay + elseif getwidth(current) > skip then + p = p + 1 ; profiles[p] = newindex(max+2,0) + end + elseif id == vlist_code then + p = p + 1 ; profiles[p] = newindex(max+2,0) + end + end + + p = p + 1 ; profiles[p] = newindex(max+2,0) + p = p + 1 ; profiles[p] = newindex(max+2,1) + + for i=1,p do + local pi = profiles[i] + pi[0] = 1 ; pi[max ] = 1 + pi[1] = 1 ; pi[max+1] = 1 + profiles[i] = concat(pi,"",0,max+1) + end + profiles = concat(profiles,"\n") + potrace.setbitmap("profile", profiles) + end +end + +function builders.profiling.addrivers(specification) + local box = getbox(specification.box) + local head = getlist(box) + if head then + + step = (specification.step or 2 * unit) + margin = (specification.margin or -1 * unit) + skip = (specification.gluethreshold or 10 * unit) + height = (specification.height or 2 * unit) + depth = (specification.depth or 2 * unit) + + local profiles = { } + local max = ceiling(getwidth(box)/step) + 1 + + local previous = false + local spacing = 0 + + local topline = false + local botline = false + + local list = newindex(max+2,false) + + for current, id, subtype in nextnode, head do + if id == hlist_code then + local amount = getwidth(current) + if amount > 0 then + botline = analyze(current,max) + if topline then + local head = false + local tail = false + for i=1,max do + if topline[i] ~= 0 and botline[i] ~= 0 then + local _, hp, dp = getwhd(previous) + local _, hc, dc = getwhd(previous) + local rule = newrule(step,hp + dp + spacing + hc,dc) + local kern = newkern() + setkern(kern,-step) + setoffsets(rule,i*step,0) + setlink(rule,kern) + if tail then + setlink(tail,rule) + else + head = rule + end + tail = kern + local li = list[i] + if li then + li[#li+1] = rule + for i=1,#li do + setcolor(li[i],"darkred") + end + else + list[i] = { rule } + setcolor(rule,"darkblue") + end + else + list[i] = false + end + end + if head then + setlink(tail,getlist(current)) + setlist(current,head) + end + end + topline = botline + botline = false + previous = current + end + elseif id == glue_code then + local width = getwidth(current) + if subtype == baselineskip_code or subtype == lineskip_code then + spacing = width + elseif width > skip then + topline = false + botline = false + end + elseif id == vlist_code then + topline = false + botline = false + end + end + + end +end + +interfaces.implement { + name = "getrivers", + protected = true, + actions = builders.profiling.getrivers, + arguments = { + { + { "box", "integer" }, + { "height", "dimension" }, + { "depth", "dimension" }, + { "step", "dimension" }, + { "margin", "dimension" }, + { "skip", "dimension" }, + } + } +} + +-- can become option + +interfaces.implement { + name = "addrivers", + protected = true, + actions = builders.profiling.addrivers, + arguments = { + { + { "box", "integer" }, + { "height", "dimension" }, + { "depth", "dimension" }, + { "step", "dimension" }, + { "margin", "dimension" }, + { "skip", "dimension" }, + } + } +} |