diff options
Diffstat (limited to 'tex/context/base/mkiv/driv-shp.lmt')
-rw-r--r-- | tex/context/base/mkiv/driv-shp.lmt | 1360 |
1 files changed, 0 insertions, 1360 deletions
diff --git a/tex/context/base/mkiv/driv-shp.lmt b/tex/context/base/mkiv/driv-shp.lmt deleted file mode 100644 index 8e3a936bb..000000000 --- a/tex/context/base/mkiv/driv-shp.lmt +++ /dev/null @@ -1,1360 +0,0 @@ -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 type, next = type, next -local round = math.round - -local setmetatableindex = table.setmetatableindex -local formatters = string.formatters -local concat = table.concat -local keys = table.keys -local sortedhash = table.sortedhash -local splitstring = string.split -local idiv = number.idiv -local extract = bit32.extract -local nuts = nodes.nuts - -local tonut = nodes.tonut -local tonode = nodes.tonode - -local getdirection = nuts.getdirection -local getlist = nuts.getlist -local getoffsets = nuts.getoffsets -local getorientation = nuts.getorientation -local getfield = nuts.getfield -local getwhd = nuts.getwhd -local getkern = nuts.getkern -local getheight = nuts.getheight -local getdepth = nuts.getdepth ------ getwidth = nuts.getwidth -local getnext = nuts.getnext -local getsubtype = nuts.getsubtype -local getid = nuts.getid -local getleader = nuts.getleader ------ getglue = nuts.getglue -local getshift = nuts.getshift -local getdata = nuts.getdata ------ getexpansion = nuts.getexpansion -local getreplace = nuts.getreplace -local setreplace = nuts.setreplace -local getfont = nuts.getfont -local getkerndimension = nuts.getkerndimension - -local setdirection = nuts.setdirection -local setfield = nuts.setfield -local setlink = nuts.setlink - -local isglyph = nuts.isglyph -local findtail = nuts.tail -local nextdir = nuts.traversers.dir -local nextnode = nuts.traversers.node - -local rangedimensions = node.direct.rangedimensions -- nuts ? -local effectiveglue = nuts.effective_glue -local start_of_par = nuts.start_of_par -local dirdimensions = nuts.dirdimensions - -local texget = tex.get - -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local characters = fonthashes.characters -local parameters = fonthashes.parameters - -local nodecodes = nodes.nodecodes -local whatsitcodes = nodes.whatsitcodes -local gluecodes = nodes.gluecodes -local dircodes = nodes.dircodes -local dirvalues = nodes.dirvalues -local subtypes = nodes.subtypes - -local normaldir_code = dircodes.normal - -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 ------ penalty_code = nodecodes.penalty ------ boundary_code = nodecodes.boundary - -local leaders_code = gluecodes.leaders -local cleaders_code = gluecodes.cleaders -local xleaders_code = gluecodes.xleaders -local gleaders_code = gluecodes.gleaders - -local spaceskip_code = gluecodes.spaceskip - -local saveposwhatsit_code = whatsitcodes.savepos -local userdefinedwhatsit_code = whatsitcodes.userdefined -local openwhatsit_code = whatsitcodes.open -local writewhatsit_code = whatsitcodes.write -local closewhatsit_code = whatsitcodes.close -local lateluawhatsit_code = whatsitcodes.latelua -local literalwhatsit_code = whatsitcodes.literal -local setmatrixwhatsit_code = whatsitcodes.setmatrix -local savewhatsit_code = whatsitcodes.save -local restorewhatsit_code = whatsitcodes.restore - -local getpagedimensions getpagedimensions = function() - getpagedimensions = backends.codeinjections.getpagedimensions - return getpagedimensions() -end - -local drivers = drivers -local instances = drivers.instances - -local report = logs.reporter("drivers") - ---------------------------------------------------------------------------------------- - -local lastfont = nil -local fontcharacters = nil - -local magicconstants = tex.magicconstants -local trueinch = magicconstants.trueinch -local maxdimen = magicconstants.maxdimen -local running = magicconstants.running - -local pos_h = 0 -local pos_v = 0 -local pos_r = lefttoright_code -local shippingmode = "none" - -local abs_max_v = 0 -local abs_max_h = 0 - -local shipbox_h = 0 -local shipbox_v = 0 -local page_size_h = 0 -local page_size_v = 0 ------ page_h_origin = 0 -- trueinch ------ page_v_origin = 0 -- trueinch - -local initialize -local finalize -local updatefontstate -local pushorientation -local poporientation -local flushcharacter -local flushfontchar -local flushrule -local flushliteral -local flushsetmatrix -local flushsave -local flushrestore -local flushspecial ------ flushimage - --- make local - -function drivers.getpos () return round(pos_h), round(pos_v) end -function drivers.getrpos() return round(pos_h), round(pos_v), pos_r end -function drivers.gethpos() return round(pos_h) end -function drivers.getvpos() return round(pos_v) end - --- characters - -local flush_character - -local stack = setmetatableindex("table") -local level = 0 -local nesting = 0 -local main = 0 - --- experiment (smaller page stream but might be fragile) - -local tospace = false directives.register("backends.spaces", function(v) tospace = v end) - --- todo: cache streams - -local default = 16384 * number.dimenfactors.bp -- 65536 // 4 - -local function flush_vf_packet(pos_h,pos_v,pos_r,font,char,data,factor,vfcommands) - - if nesting > 100 then - return - elseif nesting == 0 then - main = font - end - - nesting = nesting + 1 - - local saved_h = pos_h - local saved_v = pos_v - local saved_r = pos_r - pos_r = lefttoright_code - - local data = fontdata[font] - local fnt = font - local fonts = data.fonts - local siz = (data.parameters.factor or 1)/65536 - - local function flushchar(font,char,fnt,chr,f,e) - if fnt then - local nest = char ~= chr or font ~= fnt - if fnt == 0 then - fnt = main - end - return flush_character(false,fnt,chr,factor,nest,pos_h,pos_v,pos_r,f,e) - else - return 0 - end - end - - -- we assume resolved fonts: id mandate but maybe also size - - for i=1,#vfcommands do - local packet = vfcommands[i] - local command = packet[1] - if command == "char" then - local chr = packet[2] - local f = packet[3] - local e = packet[4] - pos_h = pos_h + flushchar(font,char,fnt,chr,f,e) - elseif command == "slot" then - local index = packet[2] - local chr = packet[3] - local f = packet[4] - local e = packet[5] - if index == 0 then - pos_h = pos_h + flushchar(font,char,font,chr,f,e) - else - local okay = fonts and fonts[index] - if okay then - local fnt = okay.id - if fnt then - pos_h = pos_h + flushchar(font,char,fnt,chr,f,e) - end - else - -- safeguard, we assume the font itself (often index 1) - pos_h = pos_h + flushchar(font,char,font,chr,f,e) - end - end - elseif command == "use" then - local index = packet[2] - if index then - local fnt - if index == 0 then - fnt = font - else - local okay = fonts and fonts[index] - if okay then - fnt = okay.id - end - end - if fnt then - -- not efficient but ok for now as experiment - local d = characters[fnt] - if d then - for i=3,#packet do - local chr = packet[i] - local dat = d[chr] - if dat then - flushfontchar(fnt,chr,dat) - end - end - end - end - end - elseif command == "right" then - local h = packet[2] -- already scaled - if factor ~= 0 and h ~= 0 then - h = h + h * factor / 1000 -- expansion - end - pos_h = pos_h + h - elseif command == "down" then - local v = packet[2] -- already scaled - pos_v = pos_v - v - elseif command == "push" then - level = level + 1 - local s = stack[level] - s[1] = pos_h - s[2] = pos_v - elseif command == "pop" then - if level > 0 then - local s = stack[level] - pos_h = s[1] - pos_v = s[2] - level = level - 1 - end - elseif command == "pdf" then - flushliteral(false,pos_h,pos_v,packet[2],packet[3]) - elseif command == "rule" then - local size_v = packet[2] - local size_h = packet[3] - if size_h > 0 and size_v > 0 then - if factor ~= 0 then - size_h = size_h + size_h * factor / 1000 - end - if size_h > 0 then - flushsimplerule(pos_h,pos_v,pos_r,size_h,size_v) - pos_h = pos_h + size_h - end - end - elseif command == "frame" then - local width = packet[2] - if width > 0 then - local height = packet[3] or 0 - local depth = packet[4] or 0 - local total = height + depth - if total > 0 then - if factor ~= 0 then - width = width + width * factor / 1000 - end - if width > 0 then - local line = packet[5] or default - local outline = not packet[6] - local advance = not packet[7] - flushspecialrule(pos_h,pos_v,pos_r,width,height,depth,line,outline) - if advance then - pos_h = pos_h + width - end - end - end - end - elseif command == "font" then - local index = packet[2] - local okay = fonts and fonts[index] - if okay then - fnt = okay.id or fnt -- or maybe just return - end - elseif command == "lua" then - local code = packet[2] - if type(code) ~= "function" then - code = loadstring(code) - end - if type(code) == "function" then - code(font,char,pos_h,pos_v) - end - elseif command == "node" then - local h = packet[2] - hlist_out(h,getlist(h)) - elseif command == "image" then - -- doesn't work because intercepted by engine so we use a different - -- mechanism (for now) - local image = packet[2] - -- to do - elseif command == "pdfmode" then - -- doesn't happen - -- elseif command == "special" then - -- -- not supported - -- elseif command == "nop" then - -- -- nothing to do| - -- elseif command == "scale" then - -- -- not supported - end - end - - pos_h = saved_h - pos_v = saved_v - pos_r = saved_r - - nesting = nesting - 1 -end - -local onetimemessage -- could be defined later (todo: make plug for this) - -flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r,f,e) - - if font ~= lastfont then - lastfont = font - fontcharacters = characters[font] - updatefontstate(font) - end - - local data = fontcharacters[char] - if not data then - if char > 0 then - if not onetimemessage then - onetimemessage = fonts.loggers.onetimemessage - end - onetimemessage(font,char,"missing") - end - return 0, 0, 0 - end - if vfcommands then - vfcommands = data.commands - end - local width, height, depth, naturalwidth - if current then - naturalwidth, height, depth, factor = getwhd(current,true) -- also get corrected width - if factor == 0 then - width = naturalwidth - else - -- width = (1.0 + factor/1000000.0) * naturalwidth - width = naturalwidth + naturalwidth * factor/1000000.0 - -- width = naturalwidth + naturalwidth * 0.000001 * factor - end - else - width = data.width or 0 - height = data.height or 0 - depth = data.depth or 0 - naturalwidth = width - if not factor then - factor = 0 - end - end - if pos_r == righttoleft_code then - pos_h = pos_h - width -- here ? - end - if vfcommands then - flush_vf_packet(pos_h,pos_v,pos_r,font,char,data,factor,vfcommands) -- also f ? - else - -- kind of messy that we do orientation here and offsets elsewhere - local orientation = data.orientation - if orientation and (orientation == 1 or orientation == 3) then - local x = data.xoffset - local y = data.yoffset - if x then - pos_h = pos_h + x - end - if y then - pos_v = pos_v + y - end - pushorientation(orientation,pos_h,pos_v) - flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width) - poporientation(orientation,pos_h,pos_v) - else - flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width) - end - end - return width, height, depth -end - --- end of characters - -local function reset_state() - pos_h = 0 - pos_v = 0 - pos_r = lefttoright_code - shipbox_h = 0 - shipbox_v = 0 - shippingmode = "none" - page_size_h = 0 - page_size_v = 0 - -- page_h_origin = 0 -- trueinch - -- page_v_origin = 0 -- trueinch -end - --- local function dirstackentry(t,k) --- local v = { --- cur_h = 0, --- cur_v = 0, --- ref_h = 0, --- ref_v = 0, --- } --- t[k] = v --- return v --- end --- --- local dirstack = setmetatableindex(dirstackentry) --- --- local function reset_dir_stack() --- dirstack = setmetatableindex(dirstackentry) --- end - -local dirstack = { } - -local function reset_dir_stack() - dirstack = { } -end - -local leaderlevel = 0 - -local function flushlatelua(current,h,v) - -- Here we assume maganement by the lua function so currently we don't - -- check for leaderlevel. - return backends.latelua(current,h,v) -end - -local function flushwriteout(current) - if leaderlevel == 0 then - backends.writeout(current) - end -end - -local function flushopenout(current) - if leaderlevel == 0 then - backends.openout(current) - end -end - -local function flushcloseout(current) - if leaderlevel == 0 then - backends.closeout(current) - end -end - -local hlist_out, vlist_out do - - local function applyanchor(orientation,x,y,width,height,depth,woffset,hoffset,doffset,xoffset,yoffset) - local ot = extract(orientation, 0,4) - local ay = extract(orientation, 4,4) - local ax = extract(orientation, 8,4) - local of = extract(orientation,12,4) - if ot == 4 then - ot, ay = 0, 1 - elseif ot == 5 then - ot, ay = 0, 2 - end - if ot == 0 or ot == 2 then - if ax == 1 then x = x - width - elseif ax == 2 then x = x + width - elseif ax == 3 then x = x - width/2 - elseif ax == 4 then x = x + width/2 - end - if ot == 2 then - doffset, hoffset = hoffset, doffset - end - if ay == 1 then y = y - doffset - elseif ay == 2 then y = y + hoffset - elseif ay == 3 then y = y + (doffset + hoffset)/2 - doffset - end - elseif ot == 1 or ot == 3 then - if ay == 1 then y = y - height - elseif ay == 2 then y = y + height - elseif ay == 3 then y = y - height/2 - end - if ot == 1 then - doffset, hoffset = hoffset, doffset - end - if ax == 1 then x = x - width - elseif ax == 2 then x = x + width - elseif ax == 3 then x = x - width/2 - elseif ax == 4 then x = x + width/2 - elseif ax == 5 then x = x - hoffset - elseif ax == 6 then x = x + doffset - end - end - return ot, x + xoffset, y - yoffset - end - - -- to be checked: begin- or enddir kan nil zijn, weird - - -- local function calculate_width_to_enddir(this_box,begindir) -- can be a helper - -- local dir_nest = 1 - -- local enddir = begindir - -- for current, subtype in nextdir, getnext(begindir) do - -- if subtype == normaldir_code then -- todo - -- dir_nest = dir_nest + 1 - -- else - -- dir_nest = dir_nest - 1 - -- end - -- if dir_nest == 0 then -- does the type matter - -- enddir = current - -- local width = rangedimensions(this_box,begindir,enddir) - -- return enddir, width - -- end - -- end - -- if enddir == begindir then - -- local width = rangedimensions(this_box,begindir) -- ,enddir) - -- return enddir, width - -- end - -- return enddir, 0 - -- end - - -- check frequencies of nodes - - 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 boxwidth, - boxheight, - boxdepth = getwhd(this_box) - - local cur_h = 0 - local cur_v = 0 - - -- if not current then - -- current = getlist(this_box) - -- end - - -- we can encounter par, boundary and penalty nodes but a special - -- iterator over content nodes won't save much - for current, id, subtype in nextnode, current do - if id == glyph_code then - local char, font = isglyph(current) - local x_offset, y_offset = getoffsets(current) - if x_offset ~= 0 or y_offset ~= 0 then - if pos_r == righttoleft_code then - pos_h = ref_h - (cur_h + x_offset) - else - pos_h = ref_h + (cur_h + x_offset) - end - pos_v = ref_v - (cur_v - y_offset) - -- synced - end - local wd = flush_character(current,font,char,false,true,pos_h,pos_v,pos_r) - cur_h = cur_h + wd - elseif id == glue_code then - local gluewidth = effectiveglue(current,this_box) - if gluewidth ~= 0 then - if subtype >= leaders_code then - local leader = getleader(current) - if leader then - local width, height, depth = getwhd(leader) - if getid(leader) == rule_code then - if gluewidth > 0 then - if height == running then - height = boxheight - end - if depth == running then - depth = boxdepth - end - local total = height + depth - if total > 0 then - if pos_r == righttoleft_code then - pos_h = pos_h - gluewidth - end - pos_v = pos_v - depth - flushrule(leader,pos_h,pos_v,pos_r,gluewidth,total,getsubtype(leader)) - end - cur_h = cur_h + gluewidth - end - elseif width > 0 and gluewidth > 0 then - local boxdir = getdirection(leader) or lefttoright_code - gluewidth = gluewidth + 10 - local edge = cur_h + gluewidth - local lx = 0 - if subtype == gleaders_code then - local save_h = cur_h - if pos_r == righttoleft_code then - cur_h = ref_h - shipbox_h - cur_h - cur_h = width * (cur_h / width) - cur_h = ref_h - shipbox_h - cur_h - else - cur_h = cur_h + ref_h - shipbox_h - cur_h = width * (cur_h / width) - cur_h = cur_h - ref_h - shipbox_h - end - if cur_h < save_h then - cur_h = cur_h + width - end - elseif subtype == leaders_code then - local save_h = cur_h - cur_h = width * (cur_h / width) - if cur_h < save_h then - cur_h = cur_h + width - end - else - lq = gluewidth / width - lr = gluewidth % width - if subtype == cleaders_code then - cur_h = cur_h + lr / 2 - else - lx = lr / (lq + 1) - cur_h = cur_h + (lr - (lq - 1) * lx) / 2 - end - end - local shift = getshift(leader) - leaderlevel = leaderlevel + 1 - while cur_h + width <= edge do - local basepoint_h = 0 - -- local basepoint_v = shift - if boxdir ~= pos_r then - basepoint_h = boxwidth - end - -- synch_pos_with_cur(ref_h,ref_v,cur_h + basepoint_h,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 - shift - -- synced - if getid(leader) == vlist_code then - vlist_out(leader,getlist(leader)) - else - hlist_out(leader,getlist(leader)) - end - cur_h = cur_h + width + lx - end - leaderlevel = leaderlevel - 1 - cur_h = edge - 10 - else - cur_h = cur_h + gluewidth - end - else - cur_h = cur_h + gluewidth - end - else - if tospace and subtype == spaceskip_code then - -- todo: flush_space - flush_character(false,getfont(current),32,false,true,pos_h,pos_v,pos_r) - end - cur_h = cur_h + gluewidth - end - end - 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, orientation = getshift(current) - if not orientation then - 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 - shift - -- synced - if id == vlist_code then - vlist_out(current,list) - else - hlist_out(current,list) - end - elseif orientation == 0x1000 then - local orientation, xoffset, yoffset = getorientation(current) - 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 + xoffset) - else - pos_h = ref_h + (cur_h + basepoint_h + xoffset) - end - pos_v = ref_v - (shift - yoffset) - -- synced - if id == vlist_code then - vlist_out(current,list) - else - hlist_out(current,list) - end - else - local orientation, xoffset, yoffset, woffset, hoffset, doffset = getorientation(current) - local orientation, basepoint_h, basepoint_v = applyanchor(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 - elseif orientation == 2 then - if boxdir == pos_r then - basepoint_h = basepoint_h + width - end - elseif orientation == 3 then - basepoint_h = basepoint_h + hoffset - if boxdir ~= pos_r then - basepoint_v = basepoint_v - height - 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) - -- synced - pushorientation(orientation,pos_h,pos_v,pos_r) - if id == vlist_code then - vlist_out(current,list) - else - hlist_out(current,list) - end - poporientation(orientation,pos_h,pos_v,pos_r) - end - end - cur_h = cur_h + width - elseif id == kern_code then - -- we can use getkerndimension(current) but then we get rounded values so for - -- now we calculate ourselves - 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 - local width, height, depth = getwhd(current) - if width > 0 then - if height == running then - height = boxheight - end - if depth == running then - depth = boxdepth - end - local total = height + depth - if total > 0 then - local xoffset, yoffset, left, right = getoffsets(current) -- top bottom - if left ~= 0 then - pos_v = pos_v + left - total = total - left - end - if right ~= 0 then - depth = depth - right - total = total - right - end - if pos_r == righttoleft_code then - pos_h = pos_h - width - xoffset = - xoffset - end - pos_v = pos_v - depth - flushrule(current,pos_h + xoffset,pos_v + yoffset,pos_r,width,total,subtype) - end - end - cur_h = cur_h + width - elseif id == math_code then - -- local kern = getkern(current) - -- if kern ~= 0 then - -- cur_h = cur_h + kern - -- else - cur_h = cur_h + effectiveglue(current,this_box) - -- end - elseif id == dir_code then - -- We normally have proper begin-end pairs. A begin without end is (silently) handled - -- and an end without a begin will be (silently) skipped we only need to move forward - -- so we then have a faster calculation. - 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 - cur_v = ds.cur_v - else - -- pardir - 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, - cur_v = cur_v, - 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 - cur_v - -- synced - ref_h = pos_h - ref_v = pos_v - cur_h = 0 - cur_v = 0 - pos_r = dir - goto synced - end - elseif id == whatsit_code then - if subtype == literalwhatsit_code then - flushliteral(current,pos_h,pos_v) - elseif subtype == lateluawhatsit_code then - flushlatelua(current,pos_h,pos_v) - elseif subtype == setmatrixwhatsit_code then - flushsetmatrix(current,pos_h,pos_v) - elseif subtype == savewhatsit_code then - flushsave(current,pos_h,pos_v) - elseif subtype == restorewhatsit_code then - flushrestore(current,pos_h,pos_v) - elseif subtype == saveposwhatsit_code then - last_position_x = pos_h - last_position_y = pos_v - elseif subtype == writewhatsit_code then - flushwriteout(current) - elseif subtype == closewhatsit_code then - flushcloseout(current) - elseif subtype == openwhatsit_code then - flushopenout(current) - end - elseif id == disc_code then - local replace, tail = getreplace(current) - if replace and subtype ~= select_disc then - -- we could flatten .. no gain - setlink(tail,getnext(current)) - setlink(current,replace) - setreplace(current) - end - -- elseif id == par_code and start_of_par(current) then - -- local pardir = getdirection(current) or lefttoright_code - -- if pardir == righttoleft_code then - -- end - -- end - else - -- penalty, boundary ... no dimensions - goto synced - end - -- There is no gain in skipping over this when we have zero progression - -- and such. - if pos_r == righttoleft_code then - pos_h = ref_h - cur_h - else - pos_h = ref_h + cur_h - end - pos_v = ref_v - cur_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 boxwidth, - boxheight, - boxdepth = getwhd(this_box) - - local cur_h = 0 - local cur_v = - boxheight - local top_edge = cur_v - - if pos_r == righttoleft_code then - pos_h = ref_h - cur_h - else - pos_h = ref_h + cur_h - end - pos_v = ref_v - cur_v - -- synced - - -- if not current then - -- current = getlist(this_box) - -- end - - -- while current do - -- local id = getid(current) - for current, id, subtype in nextnode, current do - if id == glue_code then - local glueheight = effectiveglue(current,this_box) - if glueheight ~= 0 then - if subtype >= leaders_code then - local leader = getleader(current) - if leader then - local width, height, depth = getwhd(leader) - local total = height + depth - if getid(leader) == rule_code then - depth = 0 -- hm --- forgotten ... needs testing -total = glueheight - if total > 0 then - if width == running then - width = boxwidth - end - if width > 0 then - if pos_r == righttoleft_code then - cur_h = cur_h - width - end - flushrule(leader,pos_h,pos_v - total,pos_r,width,total,getsubtype(leader)) - end - cur_v = cur_v + total - end - elseif total > 0 and glueheight > 0 then - glueheight = glueheight + 10 - local edge = cur_v + glueheight - local ly = 0 - if subtype == gleaders_code then - save_v = cur_v - cur_v = ref_v - shipbox_v - cur_v - cur_v = total * (cur_v / total) - cur_v = ref_v - shipbox_v - cur_v - if cur_v < save_v then - cur_v = cur_v + total - end - elseif subtype == leaders_code then -- aleader - save_v = cur_v - cur_v = top_edge + total * ((cur_v - top_edge) / total) - if cur_v < save_v then - cur_v = cur_v + total - end - else - lq = glueheight / total - lr = glueheight % total - if subtype == cleaders_code then - cur_v = cur_v + lr / 2 - else - ly = lr / (lq + 1) - cur_v = cur_v + (lr - (lq - 1) * ly) / 2 - end - end - local shift = getshift(leader) - leaderlevel = leaderlevel + 1 - while cur_v + total <= edge do -- todo: <= edge - total - -- synch_pos_with_cur(ref_h, ref_v, getshift(leader), cur_v + height) - 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) - -- synced - if getid(leader) == vlist_code then - vlist_out(leader,getlist(leader)) - else - hlist_out(leader,getlist(leader)) - end - cur_v = cur_v + total + ly - end - leaderlevel = leaderlevel - 1 - cur_v = edge - 10 - else - cur_v = cur_v + glueheight - end - end - else - cur_v = cur_v + glueheight - end - end - 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, orientation = getshift(current) - if not orientation then - -- 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) - -- synced - if id == vlist_code then - vlist_out(current,list) - else - hlist_out(current,list) - end - elseif orientation == 0x1000 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 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) - -- synced - if id == vlist_code then - vlist_out(current,list) - else - hlist_out(current,list) - end - else - local orientation, xoffset, yoffset, woffset, hoffset, doffset = getorientation(current) - local orientation, basepoint_h, basepoint_v = applyanchor(orientation,shift,height,width,height,depth,woffset,hoffset,doffset,xoffset,yoffset) - if orientation == 1 then - basepoint_h = basepoint_h + width - height - basepoint_v = basepoint_v - height - elseif orientation == 2 then - basepoint_h = basepoint_h + width - basepoint_v = basepoint_v + depth - height - elseif orientation == 3 then -- weird - basepoint_h = basepoint_h + height - 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) - -- synced - pushorientation(orientation,pos_h,pos_v,pos_r) - if id == vlist_code then - vlist_out(current,list) - else - hlist_out(current,list) - end - poporientation(orientation,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) - local total = height + depth - if total > 0 then - if width == running then - width = boxwidth - end - if width > 0 then - local xoffset, yoffset, left, right = getoffsets(current) - if left ~= 0 then - width = width - left - xoffset = left - end - if right ~= 0 then - width = width - right - end - if pos_r == righttoleft_code then - xoffset = - xoffset - width - end - flushrule(current,pos_h + xoffset,pos_v - total - yoffset,pos_r,width,total,subtype) - end - end - cur_v = cur_v + total - elseif id == whatsit_code then - if subtype == literalwhatsit_code then - flushliteral(current,pos_h,pos_v) - elseif subtype == lateluawhatsit_code then - flushlatelua(current,pos_h,pos_v) - elseif subtype == setmatrixwhatsit_code then - flushsetmatrix(current,pos_h,pos_v) - elseif subtype == savewhatsit_code then - flushsave(current,pos_h,pos_v) - elseif subtype == restorewhatsit_code then - flushrestore(current,pos_h,pos_v) - elseif subtype == saveposwhatsit_code then - last_position_x = pos_h - last_position_y = pos_v - elseif subtype == writewhatsit_code then - flushwriteout(current) - elseif subtype == closewhatsit_code then - flushcloseout(current) - elseif subtype == openwhatsit_code then - flushopenout(current) - end - else - -- penalty - 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 - cur_v - ::synced:: - end - pos_h = ref_h - pos_v = ref_v - pos_r = ref_r - end - -end - -function drivers.converters.lmtx(driver,box,smode,objnum,specification) - - if not driver then - report("error in converter, no driver") - return - end - - if box then - box = tonut(box) - else - report("error in converter, no box") - return - end - - local actions = driver.actions - local flushers = driver.flushers - - initialize = actions.initialize - finalize = actions.finalize - - updatefontstate = flushers.updatefontstate - - pushorientation = flushers.pushorientation - poporientation = flushers.poporientation - - flushcharacter = flushers.character - flushfontchar = flushers.fontchar - flushrule = flushers.rule - flushsimplerule = flushers.simplerule - flushspecialrule = flushers.specialrule - flushspecial = flushers.special - flushliteral = flushers.literal - flushsetmatrix = flushers.setmatrix - flushsave = flushers.save - flushrestore = flushers.restore - -- flushimage = flushers.image - - reset_dir_stack() - reset_state() - - shippingmode = smode - - local details = nil -- must be outside labels - - local width, height, depth = getwhd(box) - - local total = height + depth - - ----- v_offset_par = 0 - ----- h_offset_par = 0 - - local max_v = total -- + v_offset_par - local max_h = width -- + h_offset_par - - if height > maxdimen or depth > maxdimen or width > maxdimen then - goto DONE - end - - if max_v > maxdimen then - goto DONE - elseif max_v > abs_max_v then - abs_max_v = max_v - end - - if max_h > maxdimen then - goto DONE - elseif max_h > abs_max_h then - abs_max_h = max_h - end - - if shippingmode == "page" then - - -- We have zero offsets in ConTeXt. - - local pagewidth, pageheight = getpagedimensions() - - -- local h_offset_par = texget("hoffset") - -- local v_offset_par = texget("voffset") - - -- page_h_origin = trueinch - -- page_v_origin = trueinch - - pos_r = lefttoright_code - - if pagewidth > 0 then - page_size_h = pagewidth - else - page_size_h = width - end - - if page_size_h == 0 then - page_size_h = width - end - - if pageheight > 0 then - page_size_v = pageheight - else - page_size_v = total - end - - if page_size_v == 0 then - page_size_v = total - end - - local refpoint_h = 0 -- + page_h_origin + h_offset_par - local refpoint_v = page_size_v -- - page_v_origin - v_offset_par - - pos_h = refpoint_h - pos_v = refpoint_v - height - -- synced - - else - - -- page_h_origin = 0 - -- page_v_origin = 0 - page_size_h = width - page_size_v = total - pos_r = getdirection(box) - pos_v = depth - pos_h = pos_r == righttoleft_code and width or 0 - - end - - shipbox_ref_h = pos_h - shipbox_ref_v = pos_v - - details = { - shippingmode = smode, -- target - boundingbox = { 0, 0, page_size_h, page_size_v }, - objectnumber = smode ~= "page" and objnum or nil, - pagenumber = smode == "page" and objnum or nil, - specification = specification, - } - - initialize(driver,details) - - lastfont = nil -- this forces a sync each page / object - - if getid(box) == vlist_code then - vlist_out(box,getlist(box)) - else - hlist_out(box,getlist(box)) - end - - ::DONE:: - - finalize(driver,details) - - shippingmode = "none" -end - --- This will move to back-out.lua eventually. - -do - - ----- sortedhash = table.sortedhash - - ----- tonut = nodes.tonut - local properties = nodes.properties.data - local flush = texio.write_nl - - local periods = utilities.strings.newrepeater(".") - - local function showdetails(n,l) - local p = properties[tonut(n)] - if p then - local done = false - for k, v in sortedhash(p) do - if done then - flush("\n") - else - done = true - end - flush(periods[l+1] .. " " .. k .. " = " .. tostring(v)) - end - end - end - - local whatsittracers = { - latelua = showdetails, - literal = showdetails, - } - - callback.register("show_whatsit",function(n,l) - local s = nodes.whatsitcodes[n.subtype] - texio.write(" [" .. s .. "]") - local w = whatsittracers[s] - if w then - w(n,l) - end - end) - -end |