summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/trac-vis.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/trac-vis.lua')
-rw-r--r--tex/context/base/mkiv/trac-vis.lua366
1 files changed, 199 insertions, 167 deletions
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 0e37752db..b61dadb51 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -28,8 +28,6 @@ local compactfloat = number.compactfloat
-- todo: inline concat (more efficient)
-- todo: tags can also be numbers (just add to hash)
--- todo: dir and localpar nodes
-
local nodecodes = nodes.nodecodes
local nuts = nodes.nuts
@@ -47,12 +45,10 @@ local setattr = nuts.setattr
local setwidth = nuts.setwidth
local setshift = nuts.setshift
-local getfield = nuts.getfield
local getid = nuts.getid
local getfont = nuts.getfont
local getattr = nuts.getattr
local getsubtype = nuts.getsubtype
-local getchar = nuts.getchar
local getbox = nuts.getbox
local getlist = nuts.getlist
local getleader = nuts.getleader
@@ -63,22 +59,26 @@ local getdisc = nuts.getdisc
local getwhd = nuts.getwhd
local getkern = nuts.getkern
local getpenalty = nuts.getpenalty
-local getdir = nuts.getdir
local getwidth = nuts.getwidth
local getdepth = nuts.getdepth
local getshift = nuts.getshift
+local getexpansion = nuts.getexpansion
+
+local isglyph = nuts.isglyph
local hpack_nodes = nuts.hpack
local vpack_nodes = nuts.vpack
local copy_list = nuts.copy_list
+local copy_node = nuts.copy_node
local flush_node_list = nuts.flush_list
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
-local traverse_nodes = nuts.traverse
local apply_to_nodes = nuts.apply
local find_tail = nuts.tail
local effectiveglue = nuts.effective_glue
+local nextnode = nuts.traversers.node
+
local hpack_string = nuts.typesetters.tohpack
local texgetattribute = tex.getattribute
@@ -188,13 +188,16 @@ end
-- we can preset a bunch of bits
-local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
+local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
+local outlinerule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule")
-local function enable()
+local function initialize()
+ --
if not usedfont then
-- we use a narrow monospaced font -- infofont ?
visualizers.setfont(fonts.definers.define { name = "lmmonoltcond10regular", size = tex.sp("4pt") })
end
+ --
for mode, value in next, modes do
local tag = formatters["v_%s"](mode)
attributes.viewerlayers.define {
@@ -225,14 +228,25 @@ local function enable()
l_line = layers.line
l_space = layers.space
l_depth = layers.depth
- enableaction("shipouts","nodes.visualizers.handler")
- report_visualize("enabled")
- enabled = true
- tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end
--
if not userrule then
userrule = nuts.rules.userrule
end
+ --
+ if not outlinerule then
+ outlinerule = nuts.pool.outlinerule
+ end
+ initialize = false
+end
+
+local function enable()
+ if initialize then
+ initialize()
+ end
+ enableaction("shipouts","nodes.visualizers.handler")
+ report_visualize("enabled")
+ enabled = true
+ tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end
end
local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in
@@ -454,7 +468,7 @@ local fontkern, italickern do
local function somekern(head,current,cache,color,layer)
local width = getkern(current)
- local extra = getfield(current,"expansion_factor")
+ local extra = getexpansion(current)
local kern = width + extra
local info = cache[kern]
if not info then
@@ -495,7 +509,7 @@ local glyphexpansion do
local f_cache = caches["glyphexpansion"]
glyphexpansion = function(head,current)
- local extra = getfield(current,"expansion_factor")
+ local extra = getexpansion(current)
if extra ~= 0 then
extra = extra / 1000
local info = f_cache[extra]
@@ -529,7 +543,7 @@ local kernexpansion do
local f_cache = caches["kernexpansion"]
kernexpansion = function(head,current)
- local extra = getfield(current,"expansion_factor")
+ local extra = getexpansion(current)
if extra ~= 0 then
extra = extra / 1000
local info = f_cache[extra]
@@ -564,29 +578,17 @@ local whatsit do
local w_cache = caches["whatsit"]
local tags = {
- open = "FIC",
- write = "FIW",
- close = "FIC",
- special = "SPE",
- latelua = "LUA",
- savepos = "POS",
- userdefined = "USR",
- -- backend stuff
- pdfliteral = "PDF",
- pdfrefobj = "PDF",
- pdfannot = "PDF",
- pdfstartlink = "PDF",
- pdfendlink = "PDF",
- pdfdest = "PDF",
- pdfthread = "PDF",
- pdfstartthread = "PDF",
- pdfendthread = "PDF",
- pdfthreaddata = "PDF",
- pdflinkdata = "PDF",
- pdfcolorstack = "PDF",
- pdfsetmatrix = "PDF",
- pdfsave = "PDF",
- pdfrestore = "PDF",
+ open = "OPN",
+ write = "WRI",
+ close = "CLS",
+ special = "SPE",
+ latelua = "LUA",
+ savepos = "POS",
+ userdefined = "USR",
+ literal = "LIT",
+ setmatrix = "MAT",
+ save = "SAV",
+ restore = "RES",
}
whatsit = function(head,current)
@@ -700,40 +702,11 @@ local ruledbox do
local wd, ht, dp = getwhd(current)
if wd ~= 0 then
local shift = getshift(current)
- local dir = getdir(current)
- -- if dir == "LTL" or dir == "RRT" then
- -- wd, ht, dp = ht + dp, wd, 0
- -- end
local next = getnext(current)
local prev = 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
- -- local targetsize = wd - size
- -- baseline = b_cache[targetsize]
- -- 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 = setlink(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size))
- -- leader = hpack_nodes(leader)
- -- baseline = new_glue(0,65536,0,2,0)
- -- setleader(baseline,leader)
- -- setsubtype(baseline,cleaders_code)
- -- setlisttransparency(baseline,c_text)
- -- baseline = hpack_nodes(baseline,targetsize)
- -- b_cache[targetsize] = baseline
- -- end
- -- baseline = copy_list(baseline)
- -- baseskip = new_kern(-wd+linewidth)
- -- else
- -- baseline = new_rule(wd-size,linewidth,0)
- -- baseskip = new_kern(-wd+size)
- -- end
- -- end
local this
if not simple then
this = b_cache[what]
@@ -746,22 +719,9 @@ local ruledbox do
end
end
-- we need to trigger the right mode (else sometimes no whatits)
- -- local info = setlink(
- -- this and copy_list(this) or nil,
- -- new_rule(linewidth,ht,dp),
- -- new_rule(wd-size,-dp+linewidth,dp),
- -- new_rule(linewidth,ht,dp),
- -- new_kern(-wd+linewidth),
- -- new_rule(wd-size,ht,-ht+linewidth),
- -- baseskip,
- -- baseskip and baseline or nil
- -- )
- --
- -- userrules:
- --
local info = setlink(
this and copy_list(this) or nil,
- userrule {
+ (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
@@ -772,7 +732,7 @@ local ruledbox do
)
--
setlisttransparency(info,c_text)
- info = new_hlist(info)
+ info = new_hlist(info) -- important
--
setattr(info,a_layer,layer)
if vertical then
@@ -846,56 +806,16 @@ local ruledglyph do
ruledglyph = function(head,current,previous) -- wrong for vertical glyphs
local wd = getwidth(current)
- -- local wd = chardata[getfont(current)][getchar(current)].width
if wd ~= 0 then
local wd, ht, dp = getwhd(current)
- -- local dir = getdir(current)
- -- if dir == "LTL" or dir = "RTT" then
- -- wd, ht, dp = ht + dp, wd, 0
- -- end
local next = getnext(current)
local prev = previous
setboth(current)
local linewidth = emwidth/(2*fraction)
local info
--
- -- original
- --
- -- local baseline
- -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then
- -- baseline = new_rule(wd-2*linewidth,linewidth,0)
- -- end
- -- local doublelinewidth = 2*linewidth
- -- -- could be a pdf rule (or a user rule now)
- -- info = setlink(
- -- new_rule(linewidth,ht,dp),
- -- new_rule(wd-doublelinewidth,-dp+linewidth,dp),
- -- new_rule(linewidth,ht,dp),
- -- new_kern(-wd+linewidth),
- -- new_rule(wd-doublelinewidth,ht,-ht+linewidth),
- -- new_kern(-wd+doublelinewidth),
- -- baseline
- -- )
- --
- -- experiment with subtype outline
- --
- -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then
- -- baseline = new_rule(wd,linewidth/2,0)
- -- end
- -- local r = new_rule(wd-linewidth,ht-linewidth/4,dp-linewidth/4)
- -- setsubtype(r,nodes.rulecodes.outline)
- -- setfield(r,"transform",linewidth)
- -- info = setlink(
- -- new_kern(linewidth/4),
- -- r,
- -- new_kern(-wd+linewidth/2),
- -- baseline
- -- )
- --
- -- userrules:
- --
info = setlink(
- userrule {
+ (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule {
width = wd,
height = ht,
depth = dp,
@@ -905,7 +825,8 @@ local ruledglyph do
new_kern(-wd)
)
--
- local char = chardata[getfont(current)][getchar(current)]
+ local c, f = isglyph(current)
+ local char = chardata[f][c]
if char and type(char.unicode) == "table" then -- hackery test
setlistcolor(info,c_ligature)
setlisttransparency(info,c_ligature_d)
@@ -942,19 +863,22 @@ end
local ruledglue do
- local gluecodes = nodes.gluecodes
- local cleaders_code = gluecodes.cleaders
- local userskip_code = gluecodes.userskip
- local space_code = gluecodes.spaceskip
- local xspace_code = gluecodes.xspaceskip
- local leftskip_code = gluecodes.leftskip
- local rightskip_code = gluecodes.rightskip
+ local gluecodes = nodes.gluecodes
+ local leadercodes = nodes.gluecodes
+
+ local userskip_code = gluecodes.userskip
+ local spaceskip_code = gluecodes.spaceskip
+ local xspaceskip_code = gluecodes.xspaceskip
+ local leftskip_code = gluecodes.leftskip
+ local rightskip_code = gluecodes.rightskip
+
+ local cleaders_code = leadercodes.cleaders
local g_cache_v = caches["vglue"]
local g_cache_h = caches["hglue"]
local tags = {
- -- userskip = "US",
+ -- [gluecodes.userskip] = "US",
[gluecodes.lineskip] = "LS",
[gluecodes.baselineskip] = "BS",
[gluecodes.parskip] = "PS",
@@ -973,12 +897,12 @@ local ruledglue do
[gluecodes.thinmuskip] = "MS",
[gluecodes.medmuskip] = "MM",
[gluecodes.thickmuskip] = "ML",
- [gluecodes.leaders] = "NL",
- [gluecodes.cleaders] = "CL",
- [gluecodes.xleaders] = "XL",
- [gluecodes.gleaders] = "GL",
- -- true = "VS",
- -- false = "HS",
+ [leadercodes.leaders] = "NL",
+ [leadercodes.cleaders] = "CL",
+ [leadercodes.xleaders] = "XL",
+ [leadercodes.gleaders] = "GL",
+ -- true = "VS",
+ -- false = "HS",
}
-- we sometimes pass previous as we can have issues in math (not watertight for all)
@@ -991,7 +915,7 @@ local ruledglue do
if info then
-- print("glue hit")
else
- if subtype == space_code or subtype == xspace_code then
+ if subtype == spaceskip_code or subtype == xspaceskip_code then
info = sometext(amount,l_glue,c_space)
elseif subtype == leftskip_code or subtype == rightskip_code then
info = sometext(amount,l_glue,c_skip_a)
@@ -1018,7 +942,7 @@ local ruledglue do
-- ruledspace = function(head,current,parent)
-- local subtype = getsubtype(current)
- -- if subtype == space_code or subtype == xspace_code then
+ -- if subtype == spaceskip_code or subtype == xspaceskip_code then
-- local width = effectiveglue(current,parent)
-- local amount = formatters["%s:%0.3f"](tags[subtype] or "HS",width*pt_factor)
-- local info = g_cache_h[amount]
@@ -1041,10 +965,10 @@ local ruledglue do
ruledspace = function(head,current,parent)
local subtype = getsubtype(current)
- if subtype == space_code or subtype == xspace_code then -- not yet all space
+ if subtype == spaceskip_code or subtype == xspaceskip_code then -- not yet all space
local width = effectiveglue(current,parent)
local info
- if subtype == space_code then
+ if subtype == spaceskip_code then
info = g_cache_s[width]
if not info then
info = someblob("SP",l_glue,c_space,nil,width)
@@ -1179,24 +1103,26 @@ end
do
- local disc_code = nodecodes.disc
- local kern_code = nodecodes.kern
- local glyph_code = nodecodes.glyph
- local glue_code = nodecodes.glue
- local penalty_code = nodecodes.penalty
- local whatsit_code = nodecodes.whatsit
- local user_code = nodecodes.user
- local math_code = nodecodes.math
- local hlist_code = nodecodes.hlist
- local vlist_code = nodecodes.vlist
-
- local kerncodes = nodes.kerncodes
- local font_kern_code = kerncodes.fontkern
- local italic_kern_code = kerncodes.italiccorrection
- ----- user_kern_code = kerncodes.userkern
-
- local listcodes = nodes.listcodes
- local line_code = listcodes.line
+ local disc_code = nodecodes.disc
+ local kern_code = nodecodes.kern
+ local glyph_code = nodecodes.glyph
+ local glue_code = nodecodes.glue
+ local penalty_code = nodecodes.penalty
+ local whatsit_code = nodecodes.whatsit
+ local user_code = nodecodes.user
+ local math_code = nodecodes.math
+ local hlist_code = nodecodes.hlist
+ local vlist_code = nodecodes.vlist
+
+ local kerncodes = nodes.kerncodes
+ local fontkern_code = kerncodes.fontkern
+ local italickern_code = kerncodes.italiccorrection
+ ----- userkern_code = kerncodes.userkern
+
+ local listcodes = nodes.listcodes
+ local linelist_code = listcodes.line
+
+ local cache
local function visualize(head,vertical,forced,parent)
local trace_hbox = false
@@ -1225,6 +1151,58 @@ do
local prev_trace_fontkern = nil
local prev_trace_italic = nil
local prev_trace_expansion = nil
+
+ -- local function setthem(t,k)
+ -- local v_trace_hbox = band(k, 1) ~= 0
+ -- local v_trace_vbox = band(k, 2) ~= 0
+ -- local v_trace_vtop = band(k, 4) ~= 0
+ -- local v_trace_kern = band(k, 8) ~= 0
+ -- local v_trace_glue = band(k, 16) ~= 0
+ -- local v_trace_penalty = band(k, 32) ~= 0
+ -- local v_trace_fontkern = band(k, 64) ~= 0
+ -- local v_trace_strut = band(k, 128) ~= 0
+ -- local v_trace_whatsit = band(k, 256) ~= 0
+ -- local v_trace_glyph = band(k, 512) ~= 0
+ -- local v_trace_simple = band(k, 1024) ~= 0
+ -- local v_trace_user = band(k, 2048) ~= 0
+ -- local v_trace_math = band(k, 4096) ~= 0
+ -- local v_trace_italic = band(k, 8192) ~= 0
+ -- local v_trace_origin = band(k, 16384) ~= 0
+ -- local v_trace_discretionary = band(k, 32768) ~= 0
+ -- local v_trace_expansion = band(k, 65536) ~= 0
+ -- local v_trace_line = band(k,131072) ~= 0
+ -- local v_trace_space = band(k,262144) ~= 0
+ -- local v_trace_depth = band(k,524288) ~= 0
+ -- local v = function()
+ -- trace_hbox = v_trace_hbox
+ -- trace_vbox = v_trace_vbox
+ -- trace_vtop = v_trace_vtop
+ -- trace_kern = v_trace_kern
+ -- trace_glue = v_trace_glue
+ -- trace_penalty = v_trace_penalty
+ -- trace_fontkern = v_trace_fontkern
+ -- trace_strut = v_trace_strut
+ -- trace_whatsit = v_trace_whatsit
+ -- trace_glyph = v_trace_glyph
+ -- trace_simple = v_trace_simple
+ -- trace_user = v_trace_user
+ -- trace_math = v_trace_math
+ -- trace_italic = v_trace_italic
+ -- trace_origin = v_trace_origin
+ -- trace_discretionary = v_trace_discretionary
+ -- trace_expansion = v_trace_expansion
+ -- trace_line = v_trace_line
+ -- trace_space = v_trace_space
+ -- trace_depth = v_trace_depth
+ -- end
+ -- t[k] = v
+ -- return v
+ -- end
+ --
+ -- if not cache then
+ -- cache = setmetatableindex(setthem)
+ -- end
+
while current do
local id = getid(current)
local a = forced or getattr(current,a_visual) or unsetvalue
@@ -1254,6 +1232,7 @@ do
trace_space = false
trace_depth = false
else -- dead slow:
+ -- cache[a]()
trace_hbox = band(a, 1) ~= 0
trace_vbox = band(a, 2) ~= 0
trace_vtop = band(a, 4) ~= 0
@@ -1303,14 +1282,14 @@ do
setdisc(current,pre,post,replace)
elseif id == kern_code then
local subtype = getsubtype(current)
- if subtype == font_kern_code then
+ if subtype == fontkern_code then
if trace_fontkern or prev_trace_fontkern then
head, current = fontkern(head,current)
end
if trace_expansion or prev_trace_expansion then
head, current = kernexpansion(head,current)
end
- elseif subtype == italic_kern_code then
+ elseif subtype == italickern_code then
if trace_italic or prev_trace_italic then
head, current = italickern(head,current)
elseif trace_kern then
@@ -1342,7 +1321,7 @@ do
if trace_depth then
ruleddepth(current)
end
- if trace_line and getsubtype(current) == line_code then
+ if trace_line and getsubtype(current) == linelist_code then
head, current = ruledbox(head,current,false,l_line,"L__",trace_simple,previous,trace_origin,parent)
elseif trace_hbox then
head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple,previous,trace_origin,parent)
@@ -1390,9 +1369,9 @@ do
local function handler(head)
if usedfont then
starttiming(visualizers)
- head = visualize(tonut(head),true)
+ head = visualize(head,true)
stoptiming(visualizers)
- return tonode(head), true
+ return head, true
else
return head, false
end
@@ -1433,8 +1412,7 @@ do
}
local function markfonts(list)
- for n in traverse_nodes(list) do
- local id = getid(n)
+ for n, id in nextnode, list do
if id == glyph_code then
local font = getfont(n)
local okay = used[font]
@@ -1507,3 +1485,57 @@ do
}
end
+
+-- Here for now:
+
+do
+
+ local function make(str,forecolor,rulecolor,layer)
+ if initialize then
+ initialize()
+ end
+ local rule = new_rule(emwidth/fraction,exheight,4*exheight)
+ setcolor(rule,rulecolor)
+ settransparency(rule,rulecolor)
+ local info
+ if str == "" then
+ info = new_hlist(rule)
+ else
+ local text = hpack_string(str,usedfont)
+ local list = getlist(text)
+ setlistcolor(list,textcolor)
+ setlisttransparency(list,textcolor)
+ setshift(text,3.5 * exheight)
+ info = new_hlist(setlink(rule,text))
+ end
+ setattr(info,a_layer,layer)
+ return info
+ end
+
+ function visualizers.register(name,textcolor,rulecolor)
+ if rawget(layers,name) then
+ -- message
+ return
+ end
+ local cache = caches[name]
+ local layer = layers[name]
+ if not textcolor then
+ textcolor = c_text_d
+ end
+ if not rulecolor then
+ rulecolor = c_origin_d
+ end
+ return function(str)
+ if not str then
+ str = ""
+ end
+ local info = cache[str]
+ if not info then
+ info = make(str,textcolor,rulecolor,layer)
+ cache[str] = info
+ end
+ return copy_node(info)
+ end
+ end
+
+end