summaryrefslogtreecommitdiff
path: root/tex/context/base/trac-vis.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/trac-vis.lua')
-rw-r--r--tex/context/base/trac-vis.lua299
1 files changed, 182 insertions, 117 deletions
diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua
index 25ec59886..b88981fdd 100644
--- a/tex/context/base/trac-vis.lua
+++ b/tex/context/base/trac-vis.lua
@@ -85,6 +85,7 @@ local getlist = nuts.getlist
local getleader = nuts.getleader
local getnext = nuts.getnext
local getprev = nuts.getprev
+local getboth = nuts.getboth
local getdisc = nuts.getdisc
local hpack_nodes = nuts.hpack
@@ -100,8 +101,7 @@ local linked_nodes = nuts.linked
local effectiveglue = nuts.effective_glue
-local fast_hpack = nuts.fasthpack
-local fast_hpack_string = nuts.typesetters.fast_hpack
+local hpack_string = nuts.typesetters.tohpack
local texgetattribute = tex.getattribute
local texsetattribute = tex.setattribute
@@ -160,38 +160,37 @@ local trace_italic
local report_visualize = logs.reporter("visualize")
local modes = {
- hbox = 1,
- vbox = 2,
- vtop = 4,
- kern = 8,
- glue = 16,
- penalty = 32,
- fontkern = 64,
- strut = 128,
- whatsit = 256,
- glyph = 512,
- simple = 1024,
- simplehbox = 1024 + 1,
- simplevbox = 1024 + 2,
- simplevtop = 1024 + 4,
- user = 2048,
- math = 4096,
- italic = 8192,
+ hbox = 1,
+ vbox = 2,
+ vtop = 4,
+ kern = 8,
+ glue = 16,
+ penalty = 32,
+ fontkern = 64,
+ strut = 128,
+ whatsit = 256,
+ glyph = 512,
+ simple = 1024,
+ simplehbox = 1024 + 1,
+ simplevbox = 1024 + 2,
+ simplevtop = 1024 + 4,
+ user = 2048,
+ math = 4096,
+ italic = 8192,
+ origin = 16384,
}
-local modes_makeup = { "hbox", "vbox", "kern", "glue", "penalty" }
-local modes_boxes = { "hbox", "vbox" }
-local modes_all = { "hbox", "vbox", "kern", "glue", "penalty", "fontkern", "whatsit", "glyph", "user", "math" }
-
local usedfont, exheight, emwidth
-local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic
+local l_penalty, l_glue, l_kern, l_fontkern, l_hbox, l_vbox, l_vtop, l_strut, l_whatsit, l_glyph, l_user, l_math, l_italic, l_origin
local enabled = false
local layers = { }
-local preset_boxes = modes.hbox + modes.vbox
-local preset_makeup = preset_boxes + modes.kern + modes.glue + modes.penalty
-local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.glyph + modes.user + modes.math
+local preset_boxes = modes.hbox + modes.vbox + modes.origin
+local preset_makeup = preset_boxes
+ + modes.kern + modes.glue + modes.penalty
+local preset_all = preset_makeup
+ + modes.fontkern + modes.whatsit + modes.glyph + modes.user + modes.math
function visualizers.setfont(id)
usedfont = id or current_font()
@@ -230,6 +229,7 @@ local function enable()
l_user = layers.user
l_math = layers.math
l_italic = layers.italic
+ l_origin = layers.origin
nodes.tasks.enableaction("shipouts","nodes.visualizers.handler")
report_visualize("enabled")
enabled = true
@@ -325,6 +325,7 @@ local c_glyph = "trace:o"
local c_ligature = "trace:s"
local c_white = "trace:w"
local c_math = "trace:r"
+local c_origin = "trace:o"
local c_positive_d = "trace:db"
local c_negative_d = "trace:dr"
@@ -337,9 +338,10 @@ local c_glyph_d = "trace:do"
local c_ligature_d = "trace:ds"
local c_white_d = "trace:dw"
local c_math_d = "trace:dr"
+local c_origin_d = "trace:do"
local function sometext(str,layer,color,textcolor,lap) -- we can just paste verbatim together .. no typesteting needed
- local text = fast_hpack_string(str,usedfont)
+ local text = hpack_string(str,usedfont)
local size = getfield(text,"width")
local rule = new_rule(size,2*exheight,exheight/2)
local kern = new_kern(-size)
@@ -351,17 +353,14 @@ local function sometext(str,layer,color,textcolor,lap) -- we can just paste verb
end
local info = linked_nodes(rule,kern,text)
setlisttransparency(info,c_zero)
- info = fast_hpack(info)
+ info = new_hlist(info)
local width = getfield(info,"width")
if lap then
- info = fast_hpack(linked_nodes(new_kern(-width),info))
+ info = new_hlist(linked_nodes(new_kern(-width),info))
end
if layer then
setattr(info,a_layer,layer)
end
- setfield(info,"width",0)
- setfield(info,"height",0)
- setfield(info,"depth",0)
return info, width
end
@@ -373,7 +372,7 @@ local function fontkern(head,current)
if info then
-- print("hit fontkern")
else
- local text = fast_hpack_string(formatters[" %0.3f"](kern*pt_factor),usedfont)
+ local text = hpack_string(formatters[" %0.3f"](kern*pt_factor),usedfont)
local rule = new_rule(emwidth/fraction,6*exheight,2*exheight)
local list = getlist(text)
if kern > 0 then
@@ -386,11 +385,8 @@ local function fontkern(head,current)
setlisttransparency(list,c_text_d)
settransparency(rule,c_text_d)
setfield(text,"shift",-5 * exheight)
- info = fast_hpack(linked_nodes(rule,text))
+ info = new_hlist(linked_nodes(rule,text))
setattr(info,a_layer,l_fontkern)
- setfield(info,"width",0)
- setfield(info,"height",0)
- setfield(info,"depth",0)
f_cache[kern] = info
end
head = insert_node_before(head,current,copy_list(info))
@@ -479,7 +475,17 @@ end
local b_cache = { }
-local function ruledbox(head,current,vertical,layer,what,simple,previous)
+local o_cache = table.setmetatableindex(function(t,size)
+ local rule = new_rule(2*size,size,size)
+ origin = hpack_nodes(rule)
+ setcolor(rule,c_origin_d)
+ settransparency(rule,c_origin_d)
+ setattr(rule,a_layer,l_origin)
+ t[size] = origin
+ return origin
+end)
+
+local function ruledbox(head,current,vertical,layer,what,simple,previous,trace_origin,parent)
local wd = getfield(current,"width")
if wd ~= 0 then
local ht = getfield(current,"height")
@@ -490,6 +496,7 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous)
-- local prev = getprev(current) -- prev can be wrong in math mode < 0.78.3
setboth(current)
local linewidth = emwidth/fraction
+ local size = 2*linewidth
local baseline, baseskip
if dp ~= 0 and ht ~= 0 then
if wd > 20*linewidth then
@@ -497,43 +504,37 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous)
if not baseline then
-- due to an optimized leader color/transparency we need to set the glue node in order
-- to trigger this mechanism
- local leader = linked_nodes(new_glue(2*linewidth),new_rule(6*linewidth,linewidth,0),new_glue(2*linewidth))
- -- setlisttransparency(leader,c_text)
- leader = fast_hpack(leader)
- -- setlisttransparency(leader,c_text)
+ local leader = linked_nodes(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size))
+ leader = hpack_nodes(leader)
baseline = new_glue(0)
setfield(baseline,"leader",leader)
setfield(baseline,"subtype",cleaders_code)
- local spec = getfield(baseline,"spec")
- setfield(spec,"stretch",65536)
- setfield(spec,"stretch_order",2)
+ setfield(baseline,"stretch",65536)
+ setfield(baseline,"stretch_order",2)
setlisttransparency(baseline,c_text)
b_cache.baseline = baseline
end
baseline = copy_list(baseline)
- baseline = fast_hpack(baseline,wd-2*linewidth)
- -- or new hpack node, set head and also:
+ baseline = hpack_nodes(baseline,wd-size)
+ -- or new_hlist, set head and also:
-- baseline.width = wd
-- baseline.glue_set = wd/65536
-- baseline.glue_order = 2
-- baseline.glue_sign = 1
baseskip = new_kern(-wd+linewidth)
else
- baseline = new_rule(wd-2*linewidth,linewidth,0)
- baseskip = new_kern(-wd+2*linewidth)
+ baseline = new_rule(wd-size,linewidth,0)
+ baseskip = new_kern(-wd+size)
end
end
local this
if not simple then
this = b_cache[what]
if not this then
- local text = fast_hpack_string(what,usedfont)
+ local text = hpack_string(what,usedfont)
this = linked_nodes(new_kern(-getfield(text,"width")),text)
setlisttransparency(this,c_text)
- this = fast_hpack(this)
- setfield(this,"width",0)
- setfield(this,"height",0)
- setfield(this,"depth",0)
+ this = new_hlist(this)
b_cache[what] = this
end
end
@@ -541,23 +542,68 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous)
local info = linked_nodes(
this and copy_list(this) or nil,
new_rule(linewidth,ht,dp),
- new_rule(wd-2*linewidth,-dp+linewidth,dp),
+ new_rule(wd-size,-dp+linewidth,dp),
new_rule(linewidth,ht,dp),
new_kern(-wd+linewidth),
- new_rule(wd-2*linewidth,ht,-ht+linewidth)
+ new_rule(wd-size,ht,-ht+linewidth)
)
if baseskip then
info = linked_nodes(info,baseskip,baseline) -- could be in previous linked
end
setlisttransparency(info,c_text)
- info = fast_hpack(info)
- setfield(info,"width",0)
- setfield(info,"height",0)
- setfield(info,"depth",0)
+ info = new_hlist(info)
+ --
setattr(info,a_layer,layer)
- local info = linked_nodes(current,new_kern(-wd),info)
- setfield(current,"shift",0)
- info = (vertical and new_vlist or new_hlist)(info,wd,ht,dp,shift)
+ if vertical then
+ if shift == 0 then
+ info = linked_nodes(current,info)
+ elseif trace_origin then
+ local size = 2*size
+ local origin = o_cache[size]
+ origin = copy_list(origin)
+ if getid(parent) == vlist_code then
+ setfield(origin,"shift",-shift)
+ info = linked_nodes(current,new_kern(-size),origin,new_kern(-size),info)
+ else
+ -- todo .. i need an example
+ info = linked_nodes(current,info)
+ end
+ setfield(current,"shift",0)
+ else
+ info = linked_nodes(current,info)
+ setfield(current,"shift",0)
+ end
+ info = new_vlist(info,wd,ht,dp,shift)
+ else
+ if shift == 0 then
+ info = linked_nodes(current,new_kern(-wd),info)
+ elseif trace_origin then
+ local size = 2*size
+ local origin = o_cache[size]
+ origin = copy_list(origin)
+ if getid(parent) == vlist_code then
+ info = linked_nodes(current,new_kern(-wd-size-shift),origin,new_kern(-size+shift),info)
+ else
+ setfield(origin,"shift",-shift)
+ info = linked_nodes(current,new_kern(-wd-size),origin,new_kern(-size),info)
+ end
+ setfield(current,"shift",0)
+ else
+ info = linked_nodes(current,new_kern(-wd),info)
+ setfield(current,"shift",0)
+ end
+ info = new_hlist(info,wd,ht,dp,shift)
+ end
+
+-- how about dir, so maybe just copy the node
+--
+-- local l = getlist(current)
+-- setfield(current,"list",nil)
+-- local c = copy_node(current)
+-- setfield(current,"list",l)
+-- setfield(c,"list",info)
+-- info = c
+
if next then
setlink(info,next)
end
@@ -579,6 +625,13 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous)
end
end
+local bpfactor = number.dimenfactors.bp
+
+callback.register("process_rule",function(n,h,v)
+ local p = string.formatters["0 0 %0.6F %0.6F re f"](h*bpfactor,v*bpfactor)
+ pdf.print("direct",p)
+end)
+
local function ruledglyph(head,current,previous)
local wd = getfield(current,"width")
-- local wd = chardata[getfont(current)][getchar(current)].width
@@ -605,21 +658,27 @@ local function ruledglyph(head,current,previous)
new_kern(-wd+doublelinewidth),
baseline
)
+
+-- local rule = new_rule(wd,ht,dp)
+-- setfield(rule,"subtype",4) -- todo
+-- local info = linked_nodes(
+-- rule,
+-- new_kern(-wd),
+-- baseline
+-- )
+
local char = chardata[getfont(current)][getchar(current)]
- if char and char.tounicode and #char.tounicode > 4 then -- hack test
+ if char and type(char.unicode) == "table" then -- hackery test
setlistcolor(info,c_ligature)
setlisttransparency(info,c_ligature_d)
else
setlistcolor(info,c_glyph)
setlisttransparency(info,c_glyph_d)
end
- info = fast_hpack(info)
- setfield(info,"width",0)
- setfield(info,"height",0)
- setfield(info,"depth",0)
+ info = new_hlist(info)
setattr(info,a_layer,l_glyph)
local info = linked_nodes(current,new_kern(-wd),info)
- info = fast_hpack(info)
+ info = hpack_nodes(info)
setfield(info,"width",wd)
if next then
setlink(info,next)
@@ -671,8 +730,6 @@ local tags = {
-- we sometimes pass previous as we can have issues in math (not watertight for all)
local function ruledglue(head,current,vertical,parent)
- ----- spec = getfield(current,"spec")
- ----- width = getfield(spec,"width")
local subtype = getsubtype(current)
local width = effectiveglue(current,parent)
local amount = formatters["%s:%0.3f"](tags[subtype] or (vertical and "VS") or "HS",width*pt_factor)
@@ -797,6 +854,7 @@ local function visualize(head,vertical,forced,parent)
local trace_user = false
local trace_math = false
local trace_italic = false
+ local trace_origin = false
local current = head
local previous = nil
local attr = unsetvalue
@@ -821,21 +879,23 @@ local function visualize(head,vertical,forced,parent)
trace_user = false
trace_math = false
trace_italic = false
+ trace_origin = false
else -- dead slow:
- trace_hbox = hasbit(a, 1)
- trace_vbox = hasbit(a, 2)
- trace_vtop = hasbit(a, 4)
- trace_kern = hasbit(a, 8)
- trace_glue = hasbit(a, 16)
- trace_penalty = hasbit(a, 32)
- trace_fontkern = hasbit(a, 64)
- trace_strut = hasbit(a, 128)
- trace_whatsit = hasbit(a, 256)
- trace_glyph = hasbit(a, 512)
- trace_simple = hasbit(a,1024)
- trace_user = hasbit(a,2048)
- trace_math = hasbit(a,4096)
- trace_italic = hasbit(a,8192)
+ trace_hbox = hasbit(a, 1)
+ trace_vbox = hasbit(a, 2)
+ trace_vtop = hasbit(a, 4)
+ trace_kern = hasbit(a, 8)
+ trace_glue = hasbit(a, 16)
+ trace_penalty = hasbit(a, 32)
+ trace_fontkern = hasbit(a, 64)
+ trace_strut = hasbit(a, 128)
+ trace_whatsit = hasbit(a, 256)
+ trace_glyph = hasbit(a, 512)
+ trace_simple = hasbit(a, 1024)
+ trace_user = hasbit(a, 2048)
+ trace_math = hasbit(a, 4096)
+ trace_italic = hasbit(a, 8192)
+ trace_origin = hasbit(a,16384)
end
attr = a
end
@@ -888,7 +948,7 @@ local function visualize(head,vertical,forced,parent)
setfield(current,"list",visualize(content,false,nil,current))
end
if trace_hbox then
- head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple,previous)
+ head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple,previous,trace_origin,parent)
end
elseif id == vlist_code then
local content = getlist(current)
@@ -896,9 +956,9 @@ local function visualize(head,vertical,forced,parent)
setfield(current,"list",visualize(content,true,nil,current))
end
if trace_vtop then
- head, current = ruledbox(head,current,true,l_vtop,"_T_",trace_simple,previous)
+ head, current = ruledbox(head,current,true,l_vtop,"_T_",trace_simple,previous,trace_origin,parent)
elseif trace_vbox then
- head, current = ruledbox(head,current,true,l_vbox,"__V",trace_simple,previous)
+ head, current = ruledbox(head,current,true,l_vbox,"__V",trace_simple,previous,trace_origin,parent)
end
elseif id == whatsit_code then
if trace_whatsit then
@@ -937,14 +997,15 @@ local function cleanup()
nf, f_cache = freed(f_cache)
nw, w_cache = freed(w_cache)
nb, b_cache = freed(b_cache)
+ no, o_cache = freed(o_cache)
ng_v, g_cache_v = freed(g_cache_v)
ng_h, g_cache_h = freed(g_cache_h)
np_v, p_cache_v = freed(p_cache_v)
np_h, p_cache_h = freed(p_cache_h)
nk_v, k_cache_v = freed(k_cache_v)
nk_h, k_cache_h = freed(k_cache_h)
- -- report_visualize("cache cleanup: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",
- -- nf,ng_v+ng_h,np_v+np_h,nk_v+nk_h,nw,nb)
+ -- report_visualize("cache cleanup: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes, %s origins",
+ -- nf,ng_v+ng_h,np_v+np_h,nk_v+nk_h,nw,nb,no)
end
local function handler(head)
@@ -981,36 +1042,40 @@ function visualizers.box(n)
end
end
-local last = nil
-local used = nil
-
-local mark = {
- "trace:1", "trace:2", "trace:3",
- "trace:4", "trace:5", "trace:6",
- "trace:7",
-}
-
-local function markfonts(list)
- for n in traverse_nodes(list) do
- local id = getid(n)
- if id == glyph_code then
- local font = getfont(n)
- local okay = used[font]
- if not okay then
- last = last + 1
- okay = mark[last]
- used[font] = okay
+do
+
+ local last = nil
+ local used = nil
+
+ local mark = {
+ "trace:1", "trace:2", "trace:3",
+ "trace:4", "trace:5", "trace:6",
+ "trace:7",
+ }
+
+ local function markfonts(list)
+ for n in traverse_nodes(list) do
+ local id = getid(n)
+ if id == glyph_code then
+ local font = getfont(n)
+ local okay = used[font]
+ if not okay then
+ last = last + 1
+ okay = mark[last]
+ used[font] = okay
+ end
+ setcolor(n,okay)
+ elseif id == hlist_code or id == vlist_code then
+ markfonts(getlist(n))
end
- setcolor(n,okay)
- elseif id == hlist_code or id == vlist_code then
- markfonts(getlist(n))
end
end
-end
-function visualizers.markfonts(list)
- last, used = 0, { }
- markfonts(type(n) == "number" and getlist(getbox(n)) or n)
+ function visualizers.markfonts(list)
+ last, used = 0, { }
+ markfonts(type(n) == "number" and getlist(getbox(n)) or n)
+ end
+
end
luatex.registerstopactions(cleanup)