summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt
diff options
context:
space:
mode:
authorSiep Kroonenberg <siepo@cybercomm.nl>2023-02-26 14:47:05 +0000
committerSiep Kroonenberg <siepo@cybercomm.nl>2023-02-26 14:47:05 +0000
commitf9897a2b35a4862f1f0ac5ea4e8702b3668588a5 (patch)
tree96ba243f29c1a3c8bb945d5f16b7996eb190b6ec /Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt
parent63fa9cdb45000fcd36ad5bd0d594fbd1f57ec16e (diff)
ConTeXt LMTX: tex
git-svn-id: svn://tug.org/texlive/trunk@66178 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt')
-rw-r--r--Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt585
1 files changed, 585 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt b/Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt
new file mode 100644
index 00000000000..0542228aace
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt
@@ -0,0 +1,585 @@
+if not modules then modules = { } end modules ['driv-shp'] = {
+ version = 1.001,
+ optimize = true,
+ comment = "companion to driv-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+
+local getdirection = nuts.getdirection
+local getlist = nuts.getlist
+local getoffsets = nuts.getoffsets
+local getorientation = nuts.getorientation
+local getanchors = nuts.getanchors
+local getgeometry = nuts.getgeometry
+local getwhd = nuts.getwhd
+local getkern = nuts.getkern
+local getwidth = nuts.getwidth
+local getheight = nuts.getheight
+local getdepth = nuts.getdepth
+local getnext = nuts.getnext
+local getid = nuts.getid
+local getshift = nuts.getshift
+local getprop = nuts.getprop
+local getreplace = nuts.getreplace
+local setreplace = nuts.setreplace
+----- getkerndimension = nuts.getkerndimension
+----- getglyphdimensions = nuts.getglyphdimensions
+
+local setdirection = nuts.setdirection
+local setlink = nuts.setlink
+
+local nextnode = nuts.traversers.node
+
+local effectiveglue = nuts.effectiveglue
+local dirdimensions = nuts.dirdimensions
+
+local nodecodes = nodes.nodecodes
+local whatsitcodes = nodes.whatsitcodes
+local dirvalues = nodes.dirvalues
+
+local lefttoright_code = dirvalues.lefttoright
+local righttoleft_code = dirvalues.righttoleft
+
+local glyph_code = nodecodes.glyph
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local dir_code = nodecodes.dir
+local disc_code = nodecodes.disc
+local math_code = nodecodes.math
+local rule_code = nodecodes.rule
+local whatsit_code = nodecodes.whatsit
+
+local userdefined_code = nodes.whatsitcodes.userdefined
+
+local drivers = drivers
+
+local report = logs.reporter("drivers")
+
+local magicconstants = tex.magicconstants
+local maxdimen = magicconstants.maxdimen
+
+local pos_h = 0
+local pos_v = 0
+local pos_r = lefttoright_code
+
+local applyorientation = drivers.applyorientation
+local applyanchor = drivers.applyanchor
+
+local initialize
+local finalize
+local userdefined
+
+local function reset_state()
+ pos_h = 0
+ pos_v = 0
+ pos_r = lefttoright_code
+end
+
+local dirstack = { }
+
+local function reset_dir_stack()
+ dirstack = { }
+end
+
+local function handlewhatsit(current,pos_h,pos_v)
+ local action = userdefined[getprop(current,"id")]
+ if action then
+ action(current,pos_h,pos_v)
+ end
+end
+
+local hlist_out, vlist_out -- todo: some can be combined
+
+hlist_out = function(this_box,current)
+ local ref_h = pos_h
+ local ref_v = pos_v
+ local ref_r = pos_r
+ pos_r = getdirection(this_box)
+ local cur_h = 0
+ local cur_b
+
+ for current, id, subtype in nextnode, current do
+ if id == glyph_code then -- or id == kern_code
+ local width, factor = getwidth(current,true)
+ if width ~= 0 then
+ if factor ~= 0 then
+ cur_h = cur_h + (1.0 + factor/1000000.0) * width
+ else
+ cur_h = cur_h + width
+ end
+ end
+ elseif id == glue_code then
+-- cur_h = cur_h + effectiveglue(current,this_box)
+cur_h = cur_h + effectiveglue(current,this_box,true)
+ elseif id == hlist_code or id == vlist_code then
+ local width, height, depth = getwhd(current)
+ local list = getlist(current)
+ if list then
+ local boxdir = getdirection(current) or lefttoright_code
+ local shift = getshift(current)
+ local geometry, hasoffset, hasorientation, hasanchor = getgeometry(current,true)
+ local anchor, source, target, targetdata, s_anchor, t_anchor
+ local anc_h, anc_v
+ local usedorientation = false
+ if hasanchor then
+ anchor, source, target, s_anchor, t_anchor = getanchors(current)
+ end
+ if hasorientation then
+ local orientation, xoffset, yoffset, woffset, hoffset, doffset = getorientation(current)
+ local orientation, basepoint_h, basepoint_v = applyorientation(orientation,0,shift,width,height,depth,woffset,hoffset,doffset,xoffset,yoffset)
+ if orientation == 1 then
+ basepoint_h = basepoint_h + doffset
+ if boxdir == pos_r then
+ basepoint_v = basepoint_v - height
+ end
+ usedorientation = orientation
+ elseif orientation == 2 then
+ if boxdir == pos_r then
+ basepoint_h = basepoint_h + width
+ end
+ usedorientation = orientation
+ elseif orientation == 3 then
+ basepoint_h = basepoint_h + hoffset
+ if boxdir ~= pos_r then
+ basepoint_v = basepoint_v - height
+ end
+ usedorientation = orientation
+ end
+ if target then
+ targetdata = anchors[target]
+ if targetdata then
+ anc_h = basepoint_h
+ anc_v = - basepoint_v
+ goto posdone
+ end
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - (cur_h + basepoint_h)
+ else
+ pos_h = ref_h + (cur_h + basepoint_h)
+ end
+ -- pos_v = ref_v - (cur_v + basepoint_v)
+ pos_v = ref_v - basepoint_v
+ elseif hasoffset then
+ local orientation, xoffset, yoffset = getorientation(current)
+ local basepoint_h = boxdir ~= pos_r and width or 0
+ local basepoint_v = shift
+ if target then
+ targetdata = anchors[target]
+ if targetdata then
+ anc_h = xoffset + basepoint_h
+ anc_v = yoffset - basepoint_v
+ goto posdone
+ end
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - (cur_h + basepoint_h + xoffset)
+ else
+ pos_h = ref_h + (cur_h + basepoint_h + xoffset)
+ end
+ pos_v = ref_v - (basepoint_v - yoffset)
+ elseif hasanchor then
+ local basepoint_h = boxdir ~= pos_r and width or 0
+ local basepoint_v = shift
+ if target then
+ targetdata = anchors[target]
+ if targetdata then
+ anc_h = basepoint_h
+ anc_v = - basepoint_v
+ goto posdone
+ end
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - (cur_h + basepoint_h)
+ else
+ pos_h = ref_h + (cur_h + basepoint_h)
+ end
+ pos_v = ref_v - basepoint_v
+ else
+ local basepoint_h = boxdir ~= pos_r and width or 0
+ local basepoint_v = shift
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - (cur_h + basepoint_h)
+ else
+ pos_h = ref_h + (cur_h + basepoint_h)
+ end
+ pos_v = ref_v - basepoint_v
+ end
+ goto process
+ ::posdone::
+ if pos_r == righttoleft_code then
+ pos_h = targetdata[1] - anc_h
+ else
+ pos_h = targetdata[1] + anc_h
+ end
+ pos_v = targetdata[2] + anc_v
+ if anchor and anchor > 0 then
+ pos_h, pos_v = applyanchor(t_anchor,true, pos_h,pos_v,targetdata[3],targetdata[4],targetdata[5])
+ pos_h, pos_v = applyanchor(s_anchor,false,pos_h,pos_v,width,height,depth)
+ end
+ ::process::
+ if source then
+ local anchor_h = pos_h
+ local anchor_v = pos_v
+ if usedorientation then
+ if usedorientation == 1 then
+ anchor_v = anchor_v - (width - height)
+ elseif usedorientation == 2 then
+ anchor_v = anchor_v - (depth - height)
+ elseif usedorientation == 3 then -- weird
+ anchor_v = anchor_v + (height - width)
+ end
+ end
+ anchors[source] = { anchor_h, anchor_v, width, height, depth }
+ end
+ -- if usedorientation then
+ -- pushorientation(usedorientation,pos_h,pos_v,pos_r)
+ -- end
+ if id == vlist_code then
+ vlist_out(current,list)
+ else
+ hlist_out(current,list)
+ end
+ -- if usedorientation then
+ -- poporientation(usedorientation,pos_h,pos_v,pos_r)
+ -- end
+ end
+ cur_h = cur_h + width
+
+ elseif id == kern_code then
+ local kern, factor = getkern(current,true)
+ if kern ~= 0 then
+ if factor ~= 0 then
+ cur_h = cur_h + (1.0 + factor/1000000.0) * kern
+ else
+ cur_h = cur_h + kern
+ end
+ end
+ elseif id == rule_code then
+ cur_h = cur_h + getwidth(current)
+ elseif id == math_code then
+-- cur_h = cur_h + effectiveglue(current,this_box)
+cur_h = cur_h + effectiveglue(current,this_box,true)
+ elseif id == dir_code then
+ local dir, cancel = getdirection(current)
+ if cancel then
+ local ds = dirstack[current]
+ if ds then
+ ref_h = ds.ref_h
+ ref_v = ds.ref_v
+ cur_h = ds.cur_h
+ end
+ pos_r = dir
+ else
+ local width, enddir = dirdimensions(this_box,current)
+ local new_h = cur_h + width
+ if dir ~= pos_r then
+ cur_h = new_h
+ end
+ if enddir ~= current then
+ dirstack[enddir] = {
+ cur_h = new_h,
+ ref_h = ref_h,
+ ref_v = ref_v,
+ }
+ setdirection(enddir,pos_r)
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - cur_h
+ else
+ pos_h = ref_h + cur_h
+ end
+ pos_v = ref_v
+ ref_h = pos_h
+ ref_v = pos_v
+ cur_h = 0
+ pos_r = dir
+ goto synced
+ end
+ elseif id == whatsit_code then
+ if subtype == userdefined_code then
+ local action = userdefined[getprop(current,"id")]
+ if action then
+ if not cur_b then
+ local wd, ht, dp = getwhd(this_box)
+ cur_b = { wd, ht, dp, ref_h, ref_v, ref_r }
+ end
+ action(current, pos_h,pos_v, cur_b)
+ end
+ end
+ elseif id == disc_code then
+ local replace, tail = getreplace(current)
+ if replace then
+ setlink(tail,getnext(current))
+ setlink(current,replace)
+ setreplace(current)
+ end
+ else
+ goto synced
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - cur_h
+ else
+ pos_h = ref_h + cur_h
+ end
+ pos_v = ref_v
+ ::synced::
+ end
+ pos_h = ref_h
+ pos_v = ref_v
+ pos_r = ref_r
+end
+
+vlist_out = function(this_box,current)
+ local ref_h = pos_h
+ local ref_v = pos_v
+ local ref_r = pos_r
+ pos_r = getdirection(this_box)
+ local cur_v = - getheight(this_box)
+ local top_edge = cur_v
+ pos_h = ref_h
+ pos_v = ref_v - cur_v
+ local cur_b
+
+ for current, id, subtype in nextnode, current do
+ if id == glue_code then
+-- cur_v = cur_v + effectiveglue(current,this_box)
+cur_v = cur_v + effectiveglue(current,this_box,true)
+ elseif id == hlist_code or id == vlist_code then
+ local width, height, depth = getwhd(current)
+ local list = getlist(current)
+ if list then
+ local boxdir = getdirection(current) or lefttoright_code
+ local shift = getshift(current)
+ local geometry, hasoffset, hasorientation, hasanchor = getgeometry(current,true)
+ local anchor, source, target, targetdata, s_anchor, t_anchor
+ local usedorientation = false
+ if hasanchor then
+ anchor, source, target, s_anchor, t_anchor = getanchors(current)
+ end
+ if hasorientation then
+ local orientation, xoffset, yoffset, woffset, hoffset, doffset = getorientation(current)
+ local orientation, basepoint_h, basepoint_v = applyorientation(orientation,shift,height,width,height,depth,woffset,hoffset,doffset,xoffset,yoffset)
+ if orientation == 1 then
+ basepoint_h = basepoint_h + width - height -- hm
+ basepoint_v = basepoint_v - height
+ usedorientation = orientation
+ elseif orientation == 2 then
+ basepoint_h = basepoint_h + width
+ basepoint_v = basepoint_v + depth - height
+ usedorientation = orientation
+ elseif orientation == 3 then -- weird
+ basepoint_h = basepoint_h + height
+ usedorientation = orientation
+ end
+ if target then
+ targetdata = anchors[target]
+ if targetdata then
+ if pos_r == righttoleft_code then
+ pos_h = targetdata[1] - basepoint_h
+ else
+ pos_h = targetdata[1] + basepoint_h
+ end
+ pos_v = targetdata[2] - basepoint_v
+ goto posdone
+ end
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - basepoint_h
+ else
+ pos_h = ref_h + basepoint_h
+ end
+ pos_v = ref_v - (cur_v + basepoint_v)
+ elseif hasoffset then
+ local orientation, xoffset, yoffset = getorientation(current)
+ -- local basepoint_h = shift
+ -- local basepoint_v = height
+ if boxdir ~= pos_r then
+ shift = shift + width
+ end
+ if target then
+ targetdata = anchors[target]
+ if targetdata then
+ if pos_r == righttoleft_code then
+ pos_h = targetdata[1] - (shift + xoffset)
+ else
+ pos_h = targetdata[1] + (shift + xoffset)
+ end
+ pos_v = targetdata[2] - (height - yoffset)
+ goto posdone
+ end
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - (shift + xoffset)
+ else
+ pos_h = ref_h + (shift + xoffset)
+ end
+ pos_v = ref_v - (cur_v + height - yoffset)
+ elseif hasanchor then
+ -- local basepoint_h = shift
+ -- local basepoint_v = height
+ if boxdir ~= pos_r then
+ shift = shift + width
+ end
+ if target then
+ local a = anchors[target]
+ if a then
+ if pos_r == righttoleft_code then
+ pos_h = targetdata[1] - shift
+ else
+ pos_h = targetdata[1] + shift
+ end
+ pos_v = targetdata[2] - height
+ goto posdone
+ end
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - shift
+ else
+ pos_h = ref_h + shift
+ end
+ pos_v = ref_v - (cur_v + height)
+ else
+ -- local basepoint_h = shift
+ -- local basepoint_v = height
+ if boxdir ~= pos_r then
+ shift = shift + width
+ end
+ if pos_r == righttoleft_code then
+ pos_h = ref_h - shift
+ else
+ pos_h = ref_h + shift
+ end
+ pos_v = ref_v - (cur_v + height)
+ end
+ goto process
+ ::posdone::
+ if anchor and anchor > 0 then
+ pos_h, pos_v = applyanchor(t_anchor,true, pos_h,pos_v,targetdata[3],targetdata[4],targetdata[5])
+ pos_h, pos_v = applyanchor(s_anchor,false,pos_h,pos_v,width,height,depth)
+ end
+ ::process::
+ if source then
+ -- move this into apply_anchor
+ local anchor_h = pos_h
+ local anchor_v = pos_v
+ if usedorientation then
+ if usedorientation == 1 then
+ anchor_v = anchor_v - (width - height)
+ elseif usedorientation == 2 then
+ anchor_v = anchor_v - (depth - height)
+ elseif usedorientation == 3 then -- weird
+ anchor_v = anchor_v + (height - width)
+ end
+ end
+ anchors[source] = { anchor_h, anchor_v, width, height, depth }
+ end
+ -- if usedorientation then
+ -- pushorientation(usedorientation,pos_h,pos_v,pos_r)
+ -- end
+ -- if source then
+ -- flushstored(current,source,true)
+ -- end
+ if id == vlist_code then
+ vlist_out(current,list)
+ else
+ hlist_out(current,list)
+ end
+ -- if source then
+ -- flushstored(current,source,false)
+ -- end
+ -- if usedorientation then
+ -- poporientation(usedorientation,pos_h,pos_v,pos_r)
+ -- end
+ end
+ cur_v = cur_v + height + depth
+
+ elseif id == kern_code then
+ cur_v = cur_v + getkern(current)
+ elseif id == rule_code then
+ local width, height, depth = getwhd(current)
+ cur_v = cur_v + height + depth
+ elseif id == whatsit_code then
+ if subtype == userdefined_code then
+ local action = userdefined[getprop(current,"id")]
+ if action then
+ if not cur_b then
+ local wd, ht, dp = getwhd(this_box)
+ cur_b = { wd, ht, dp, ref_h, ref_v, ref_r }
+ end
+ action(current,pos_h,pos_v)
+ end
+ end
+ else
+ goto synced
+ end
+ pos_h = ref_h
+ ::synced::
+ end
+ pos_h = ref_h
+ pos_v = ref_v
+ pos_r = ref_r
+end
+
+function drivers.converters.analyze(driver,box)
+
+ if not driver then
+ report("error in converter, no driver")
+ return
+ elseif box then
+ box = tonut(box)
+ else
+ report("error in converter, no box")
+ return
+ end
+
+ local width, height, depth = getwhd(box)
+ local total = height + depth
+
+ if height > maxdimen or depth > maxdimen or width > maxdimen or total > maxdimen then
+ report("error in converter, overflow")
+ return
+ end
+
+ local actions = driver.actions
+ local flushers = driver.flushers
+
+ initialize = actions.initialize
+ finalize = actions.finalize
+
+ userdefined = flushers.userdefined
+
+ reset_dir_stack()
+ reset_state()
+
+ pos_r = getdirection(box)
+ pos_v = depth
+ pos_h = pos_r == righttoleft_code and width or 0
+
+ local details = {
+ boundingbox = { 0, 0, width, total },
+ }
+
+ if initialize then
+ initialize(driver,details)
+ end
+
+ if getid(box) == vlist_code then
+ vlist_out(box,getlist(box))
+ else
+ hlist_out(box,getlist(box))
+ end
+
+ if finalize then
+ finalize(driver,details)
+ end
+
+end
+