summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/driv-shp.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/driv-shp.lmt')
-rw-r--r--tex/context/base/mkiv/driv-shp.lmt1360
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