diff options
author | Siep Kroonenberg <siepo@cybercomm.nl> | 2023-02-26 14:47:05 +0000 |
---|---|---|
committer | Siep Kroonenberg <siepo@cybercomm.nl> | 2023-02-26 14:47:05 +0000 |
commit | f9897a2b35a4862f1f0ac5ea4e8702b3668588a5 (patch) | |
tree | 96ba243f29c1a3c8bb945d5f16b7996eb190b6ec /Master/texmf-dist/tex/context/base/mkxl/driv-usr.lmt | |
parent | 63fa9cdb45000fcd36ad5bd0d594fbd1f57ec16e (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.lmt | 585 |
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 + |