diff options
Diffstat (limited to 'tex')
20 files changed, 737 insertions, 186 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 9a3e4701c..39d4f1284 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2017.02.19 17:14} +\newcontextversion{2017.02.20 15:10} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 0da99796f..2c673c837 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2017.02.19 17:14} +\edef\contextversion{2017.02.20 15:10} %D For those who want to use this: diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua index 6a2912024..5e111fcdf 100644 --- a/tex/context/base/mkiv/anch-pgr.lua +++ b/tex/context/base/mkiv/anch-pgr.lua @@ -16,8 +16,8 @@ if not modules then modules = { } end modules ['anch-pgr'] = { -- been replaced. Background code is still not perfect, but some day ... the details manual -- will discuss this issue. -local abs, div, floor, round = math.abs, math.div, math.floor, math.round -local concat = table.concat +local abs, div, floor, round, min, max = math.abs, math.div, math.floor, math.round, math.min, math.max +local sort, concat = table.sort, table.concat local splitter = lpeg.splitat(":") local lpegmatch = lpeg.match @@ -34,8 +34,9 @@ local report_graphics = logs.reporter("backgrounds") local report_shapes = logs.reporter("backgrounds","shapes") local report_free = logs.reporter("backgrounds","free") -local trace_shapes = false trackers.register("backgrounds.shapes", function(v) trace_shapes = v end) -local trace_free = false trackers.register("backgrounds.shapes.free",function(v) trace_free = v end) +local trace_shapes = false trackers.register("backgrounds.shapes", function(v) trace_shapes = v end) +local trace_ranges = false trackers.register("backgrounds.shapes.ranges",function(v) trace_ranges = v end) +local trace_free = false trackers.register("backgrounds.shapes.free", function(v) trace_free = v end) local f_b_tag = formatters["b:%s"] local f_e_tag = formatters["e:%s"] @@ -60,11 +61,23 @@ local pdfgetpos = pdf.getpos -- why not a generic name ! local a_textbackground = attributes.private("textbackground") local nuts = nodes.nuts +local tonut = nodes.tonut +local tonode = nodes.tonode local new_latelua = nuts.pool.latelua +local new_rule = nuts.pool.rule +local new_kern = nuts.pool.kern +local new_hlist = nuts.pool.hlist local getbox = nuts.getbox -local getlist = nuts.getlist +local getid = nuts.getid +----- getlist = nuts.getlist +local setlink = nuts.setlink +local getheight = nuts.getheight +local getdepth = nuts.getdepth + +local nodecodes = nodes.nodecodes +local localpar_code = nodecodes.localpar local insert_before = nuts.insert_before local insert_after = nuts.insert_after @@ -83,6 +96,76 @@ local enabled = false -- Freeing the data is somewhat tricky as we can have backgrounds spanning -- many pages but for an arbitrary background shape that is not so common. +local function check(a,index,depth,d,where,ht,dp) + -- this is not yet r2l ready + local w = d.shapes[realpage] + local x, y = pdfgetpos() + if trace_ranges then + report_shapes("attribute %i, index %i, depth %i, location %s, position (%p,%p)", + a,index,depth,where,x,y) + end + local n = #w + if d.index ~= index then + n = n + 1 + d.index = index + d.depth = depth +-- w[n] = { x, x, y, ht, dp } + w[n] = { y, ht, dp, x, x } + else + local wn = w[n] + local wh = wn[2] + local wd = wn[3] + if depth < d.depth then + local wy = wn[1] + wn[1] = y + d.depth = depth + local dy = wy - y + wh = wh - dy + wd = wd - dy + end + if where == "r" then + if x > wn[5] then + wn[5] = x + end + else + if x < wn[4] then + wn[4] = x + end + end + if ht > wh then + wn[2] = ht + end + if dp > wd then + wn[3] = dp + end + end + -- inspect(w) +end + +local index = 0 + +local function flush(head,f,l,a,parent,depth) + local d = data[a] + if d then + local ix = index + local ht = getheight(parent) + local dp = getdepth(parent) + local ln = new_latelua(function() check(a,ix,depth,d,"l",ht,dp) end) + local rn = new_latelua(function() check(a,ix,depth,d,"r",ht,dp) end) + if trace_ranges then + ln = new_hlist(setlink(new_rule(65536,65536*4,0),new_kern(-65536),ln)) + rn = new_hlist(setlink(new_rule(65536,0,65536*4),new_kern(-65536),rn)) + end + if getid(f) == localpar_code then -- we need to clean this mess + insert_after(head,f,ln) + else + head, f = insert_before(head,f,ln) + end + insert_after(head,l,rn) + end + return head, true +end + local function registerbackground(name) local n = #data + 1 if n > recycle then @@ -101,62 +184,25 @@ local function registerbackground(name) n = n, shapes = s, count = 0, + sindex = 0, } texsetattribute(a_textbackground,n) - enabled = true - else - texsetattribute(a_textbackground,unsetvalue) - end -end - -local function check(d,where) - -- this is not yet r2l ready - local w = d.shapes[realpage] - local x, y = pdfgetpos() - local n = #w - if n == 0 then - w[n+1] = { x, x, y } - elseif where == "r" then - local w0 = w[n] - if n > 2 then - local w2 = w[n-2] - if w2[2] == x then - local w1 = w[n-1] - if w1[2] == x then - local xx = w1[1] - if w2[1] == xx and xx == w0[1] then - w1[3] = w0[3] - w[n] = nil - return - end - end - end + if not enabled then + nodes.tasks.enableaction("contributers", "nodes.handlers.bck") + enabled = true end - w0[2] = x - elseif w[n][3] == y then - -- we have another one in the same line - -- w[n][2] = x else - w[n+1] = { x, x, y } - end -end - -local function flush(head,f,l,a,parent) - local d = data[a] - if d then - head, f = insert_before(head,f,new_latelua(function() check(d,"l") end)) - head, l = insert_after (head,l,new_latelua(function() check(d,"r") end)) + texsetattribute(a_textbackground,unsetvalue) end - return head, true end local function collectbackgrounds(r,n) - if enabled then - local parent = getbox(n) - local head = getlist(parent) - realpage = r - processranges(a_textbackground,flush,head) -- ,parent) - end +-- if enabled then +-- local parent = getbox(n) +-- local head = getlist(parent) +-- realpage = r +-- processranges(a_textbackground,flush,head) -- ,parent) +-- end end interfaces.implement { @@ -165,6 +211,21 @@ interfaces.implement { arguments = { "integer", "integer" } } +---------------------------------------------------------------------------------------- + +nodes.handlers.bck = function(head,where,parent) -- we have hlistdir and local dir + -- todo enable action in register + head = tonut(head) + index = index + 1 + local head, done = processranges(a_textbackground,flush,head,parent) + return tonode(head), done +end + +nodes.tasks.appendaction("contributers", "normalizers", "nodes.handlers.bck") +nodes.tasks.disableaction("contributers", "nodes.handlers.bck") + +---------------------------------------------------------------------------------------- + interfaces.implement { name = "registerbackground", actions = registerbackground, @@ -210,7 +271,7 @@ local function finish(t) if tm < 2 then return end - if trace_shapes then + if trace_ranges then report_shapes("initial list: %s",topairs(t,tm)) end -- remove similar points @@ -391,40 +452,86 @@ local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) local pl = nil -- previous left x local pr = nil -- previous right x local n = 0 + local xl = nil + local xr = nil + local mh = ph -- min + local md = pd -- min for i=1,ns do local si = s[i] - local xl = si[1] - local xr = si[2] - local y = si[3] - local xm = xl + (xr - xl)/2 -- midpoint should be in region - if xm >= xmin and xm <= xmax and y >= ymin and y <= ymax then - local h = y + ph - local d = y - pd - if pl then + local y = si[1] + local ll = si[4] -- can be sparse + if ll then + xl = ll + local rr = si[5] -- can be sparse + if rr then + xr = rr + end + end + if trace_ranges then + report_shapes("original : [%02i] xl=%p xr=%p y=%p",i,xl,xr,y) + end + if xl ~= xr then -- could be catched in the finalizer + local xm = xl + (xr - xl)/2 -- midpoint should be in region + if xm >= xmin and xm <= xmax and y >= ymin and y <= ymax then + local ht = si[2] -- can be sparse + if ht then + ph = ht + local dp = si[3] -- can be sparse + if dp then + pd = dp + end + end + local h = y + (ph < mh and mh or ph) + local d = y - (pd < md and md or pd) + if pl then + n = n + 1 + ls[n] = { pl, h } + rs[n] = { pr, h } + if trace_ranges then + report_shapes("paragraph : [%02i] xl=%p xr=%p y=%p",i,pl,pr,h) + end + end + n = n + 1 + ls[n] = { xl, h } + rs[n] = { xr, h } + if trace_ranges then + report_shapes("height : [%02i] xl=%p xr=%p y=%p",i,xl,xr,h) + end n = n + 1 - ls[n] = { pl, h } - rs[n] = { pr, h } + ls[n] = { xl, d } + rs[n] = { xr, d } + if trace_ranges then + report_shapes("depth : [%02i] xl=%p xr=%p y=%p",i,xl,xr,d) + end + end + pl, pr = xl, xr + else + if trace_ranges then + report_shapes("ignored : [%02i] xl=%p xr=%p y=%p",i,xl,xr,y) end - n = n + 1 - ls[n] = { xl, h } - rs[n] = { xr, h } - n = n + 1 - ls[n] = { xl, d } - rs[n] = { xr, d } end - pl, pr = xl, xr end -- if true and n > 0 then -- use height of b and depth of e, maybe check for weird border -- cases here if fh then - ls[1][2] = fh - rs[1][2] = fh + local lsf, rsf = ls[1], rs[1] + if lsf[2] < fh then + lsf[2] = fh + end + if rsf[2] < fh then + rsf[2] = fh + end end if fd then - ls[n][2] = fd - rs[n][2] = fd + local lsl, rsl = ls[n], rs[n] + if lsl[2] > fd then + lsl[2] = fd + end + if rsl[2] > fd then + rsl[2] = fd + end end end -- diff --git a/tex/context/base/mkiv/anch-pgr.mkiv b/tex/context/base/mkiv/anch-pgr.mkiv index 4a86671a4..1a583142e 100644 --- a/tex/context/base/mkiv/anch-pgr.mkiv +++ b/tex/context/base/mkiv/anch-pgr.mkiv @@ -16,11 +16,7 @@ %D Before we come to graphics support, we have to make sure of the reference point %D on the page. The next macros do so and are hooked into the page building routine. -\doifelsefile {anch-pgr-new.lua} { - \registerctxluafile{anch-pgr-new}{1.001} -} { - \registerctxluafile{anch-pgr}{1.001} -} +\registerctxluafile{anch-pgr}{1.001} \unprotect diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua index 848b42d41..6a9612d9e 100644 --- a/tex/context/base/mkiv/anch-pos.lua +++ b/tex/context/base/mkiv/anch-pos.lua @@ -269,7 +269,54 @@ end -- function jobpositions.getcollected(class,tag) if tag then return collected[class..tag] else return collected[class] end end -- function jobpositions.gettobesaved(class,tag) if tag then return tobesaved[class..tag] else return tobesaved[class] end end -job.register('job.positions.collected', tobesaved, initializer) +local function finalizer() + -- We make the (possible extensive) shape lists sparse working + -- from the end. We could also drop entries here that have l and + -- r the same which saves testing later on. + for k, v in next, tobesaved do + local s = v.s + if s then + for p, data in next, s do + local n = #data + if n > 1 then + local ph = data[1][2] + local pd = data[1][3] + local xl = data[1][4] + local xr = data[1][5] + for i=2,n do + local di = data[i] + local h = di[2] + local d = di[3] + local l = di[4] + local r = di[5] + if r == xr then + di[5] = nil + if l == xl then + di[4] = nil + if d == pd then + di[3] = nil + if h == ph then + di[2] = nil + else + ph = h + end + else + pd, ph = d, h + end + else + ph, pd, xl = h, d, l + end + else + ph, pd, xl, xr = h, d, l, r + end + end + end + end + end + end +end + +job.register('job.positions.collected', tobesaved, initializer, finalizer) local regions = { } local nofregions = 0 diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 8b77ca89c..d2fb678d5 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2017.02.19 17:14} +\newcontextversion{2017.02.20 15:10} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 33b264f8e..c3c798b12 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2017.02.19 17:14} +\edef\contextversion{2017.02.20 15:10} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 4d8c0fcdd..c8f3e3474 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -3064,6 +3064,83 @@ local function comprun(disc,c_run,...) -- vararg faster than the whole list return getnext(disc), renewed end +-- local function testrun(disc,t_run,c_run,...) +-- if trace_testruns then +-- report_disc("test",disc) +-- end +-- local prev, next = getboth(disc) +-- if not next then +-- -- weird discretionary +-- return +-- end +-- local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) +-- local done = false +-- if replace and prev then +-- -- this is a bit strange as we only do replace here and not post +-- -- anyway, we only look ahead ... the idea is that we discard a +-- -- disc when there is a ligature crossing the replace boundary +-- setlink(replacetail,next) +-- local ok, overflow = t_run(replace,next,...) +-- if ok and overflow then +-- -- so, we can have crossed the boundary +-- setfield(disc,"replace") +-- setlink(prev,replace) +-- -- setlink(replacetail,next) +-- setboth(disc) +-- flush_node_list(disc) +-- return replace, true -- restart .. tricky ! +-- else +-- -- we stay inside the disc +-- setnext(replacetail) +-- setprev(next,disc) +-- end +-- -- pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) +-- end +-- -- +-- -- like comprun +-- -- +-- local renewed = false +-- -- +-- if pre then +-- sweepnode = disc +-- sweeptype = "pre" +-- local new, ok = c_run(pre,...) +-- if ok then +-- pre = new +-- renewed = true +-- end +-- end +-- -- +-- if post then +-- sweepnode = disc +-- sweeptype = "post" +-- local new, ok = c_run(post,...) +-- if ok then +-- post = new +-- renewed = true +-- end +-- end +-- -- +-- if replace then +-- sweepnode = disc +-- sweeptype = "replace" +-- local new, ok = c_run(replace,...) +-- if ok then +-- replace = new +-- renewed = true +-- end +-- end +-- -- +-- sweepnode = nil +-- sweeptype = nil +-- if renewed then +-- setdisc(disc,pre,post,replace) +-- return next, true +-- else +-- return next, done +-- end +-- end + local function testrun(disc,t_run,c_run,...) if trace_testruns then report_disc("test",disc) @@ -3075,22 +3152,49 @@ local function testrun(disc,t_run,c_run,...) end local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) local done = false - if replace and prev then - -- this is a bit strange as we only do replace here and not post - -- anyway, we only look ahead ... the idea is that we discard a - -- disc when there is a ligature crossing the replace boundary - setlink(replacetail,next) - local ok, overflow = t_run(replace,next,...) - if ok and overflow then - -- so, we can have crossed the boundary - setfield(disc,"replace") - setlink(prev,replace) - -- setlink(replacetail,next) - setboth(disc) - flush_node_list(disc) - return replace, true -- restart .. tricky ! + if (post or replace) and prev then + if post then + setlink(posttail,next) + else + post = next + end + if replace then + setlink(replacetail,next) + else + replace = next + end + local d_post = t_run(post,next,...) + local d_replace = t_run(replace,next,...) + if (d_post and d_post > 0) or (d_replace and d_replace > 0) then + local d = d_replace or d_post + if d_post and d < d_post then + d = d_post + end + local head, tail = getnext(disc), disc + for i=1,d do + tail = getnext(tail) + if getid(tail) == disc_code then + head, tail = flattendisk(head,tail) + end + end + local next = getnext(tail) + setnext(tail) + setprev(head) + local new = copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post = head + end + if replacetail then + setlink(replacetail,new) + else + replace = new + end + setlink(disc,next) else -- we stay inside the disc + setnext(posttail) setnext(replacetail) setprev(next,disc) end @@ -3214,7 +3318,52 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm return head, done end +-- local function t_run_single(start,stop,font,attr,lookupcache) +-- while start ~= stop do +-- local char = ischar(start,font) +-- if char then +-- local a -- happens often so no assignment is faster +-- if attr then +-- a = getattr(start,0) +-- end +-- local startnext = getnext(start) +-- if not a or (a == attr) then +-- local lookupmatch = lookupcache[char] +-- if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check +-- -- if we need more than ligatures we can outline the code and use functions +-- local s = startnext +-- local l = nil +-- local d = 0 +-- while s do +-- if s == stop then +-- d = 1 +-- elseif d > 0 then +-- d = d + 1 +-- end +-- local lg = lookupmatch[getchar(s)] +-- if lg then +-- l = lg +-- s = getnext(s) +-- else +-- break +-- end +-- end +-- if l and l.ligature then +-- return true, d > 1 +-- end +-- end +-- else +-- -- go on can be a mixed one +-- end +-- start = starttnext +-- else +-- break +-- end +-- end +-- end + local function t_run_single(start,stop,font,attr,lookupcache) + local lastd = nil while start ~= stop do local char = ischar(start,font) if char then @@ -3227,31 +3376,61 @@ local function t_run_single(start,stop,font,attr,lookupcache) local lookupmatch = lookupcache[char] if lookupmatch then -- hm, hyphens can match (tlig) so we need to really check -- if we need more than ligatures we can outline the code and use functions - local s = startnext + local s = startnext + local ss = nil + local sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end local l = nil local d = 0 while s do - if s == stop then - d = 1 - elseif d > 0 then - d = d + 1 - end local lg = lookupmatch[getchar(s)] if lg then + if sstop then + d = 1 + elseif d > 0 then + d = d + 1 + end l = lg s = getnext(s) + sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end else break end end if l and l.ligature then - return true, d > 1 + lastd = d end end else -- go on can be a mixed one end - start = starttnext + if lastd then + return lastd + end + start = startnext else break end @@ -3341,7 +3520,60 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm return head, done end +-- local function t_run_multiple(start,stop,font,attr,steps,nofsteps) +-- while start ~= stop do +-- local char = ischar(start,font) +-- if char then +-- local a -- happens often so no assignment is faster +-- if attr then +-- a = getattr(start,0) +-- end +-- local startnext = getnext(start) +-- if not a or (a == attr) then +-- for i=1,nofsteps do +-- local step = steps[i] +-- local lookupcache = step.coverage +-- if lookupcache then +-- local lookupmatch = lookupcache[char] +-- if lookupmatch then +-- -- if we need more than ligatures we can outline the code and use functions +-- local s = startnext +-- local l = nil +-- local d = 0 +-- while s do +-- if s == stop then +-- d = 1 +-- elseif d > 0 then +-- d = d + 1 +-- end +-- local lg = lookupmatch[getchar(s)] +-- if lg then +-- l = lg +-- s = getnext(s) +-- else +-- break +-- end +-- end +-- if l and l.ligature then +-- return true, d > 1 +-- end +-- end +-- else +-- report_missing_coverage(dataset,sequence) +-- end +-- end +-- else +-- -- go on can be a mixed one +-- end +-- start = startnext +-- else +-- break +-- end +-- end +-- end + local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd = nil while start ~= stop do local char = ischar(start,font) if char then @@ -3358,25 +3590,52 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) local lookupmatch = lookupcache[char] if lookupmatch then -- if we need more than ligatures we can outline the code and use functions - local s = startnext + local s = startnext + local ss = nil + local sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end local l = nil local d = 0 while s do - if s == stop then - d = 1 - elseif d > 0 then - d = d + 1 - end local lg = lookupmatch[getchar(s)] if lg then + if sstop then + d = 1 + elseif d > 0 then + d = d + 1 + end l = lg s = getnext(s) + sstop = s == stop + if not s then + s = ss + ss = nil + end + while getid(s) == disc_code do + ss = getnext(s) + s = getfield(s,"replace") + if not s then + s = ss + ss = nil + end + end else break end end if l and l.ligature then - return true, d > 1 + lastd = d end end else @@ -3386,6 +3645,9 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) else -- go on can be a mixed one end + if lastd then + return lastd + end start = startnext else break diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua index 34d7ec000..42abea569 100644 --- a/tex/context/base/mkiv/lang-dis.lua +++ b/tex/context/base/mkiv/lang-dis.lua @@ -294,13 +294,7 @@ end local flatten = languages.flatten local getlist = nodes.getlist -function nodes.handlers.flattenline(head) - local list = getlist(head) - if list then - flatten(list) - end - return head -end +nodes.handlers.flattenline = flatten function nodes.handlers.flatten(head,where) if head and (where == "box" or where == "adjusted_hbox") then diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index d65813f5c..369b06ab2 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -35,12 +35,7 @@ \registerctxluafile{node-acc}{1.001} % experimental %registerctxluafile{node-prp}{1.001} % makes no sense (yet) \registerctxluafile{node-ppt}{1.001} - -\doifelsefile {node-scn-new.lua} { - \registerctxluafile{node-scn-new}{1.001} -} { - \registerctxluafile{node-scn}{1.001} -} +\registerctxluafile{node-scn}{1.001} \newcount\c_node_tracers_show_box % box number diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua index acdb1286e..9ebc8e411 100644 --- a/tex/context/base/mkiv/node-met.lua +++ b/tex/context/base/mkiv/node-met.lua @@ -170,13 +170,17 @@ local n_getdisc = node.getdisc local n_getleader = node.getleader local n_setnext = node.setnext or -- always - function(c,next) + function(c,n) setfield(c,"next",n) end local n_setprev = node.setprev or -- always - function(c,prev) + function(c,p) setfield(c,"prev",p) end +local n_setlist = node.setlist or -- always + function(c,l) + setfield(c,"list",l) + end local n_setlink = node.setlink or -- always -- function(c1,c2) -- if c1 then setfield(c1,"next",c2) end @@ -204,10 +208,11 @@ local n_setboth = node.setboth or -- always setfield(c,"next",n) end -node.setnext = n_setnext -node.setprev = n_setprev -node.setlink = n_setlink -node.setboth = n_setboth +nodes.setnext = n_setnext +nodes.setprev = n_setprev +nodes.setlink = n_setlink +nodes.setboth = n_setboth +nodes.setlist = n_setlist nodes.getfield = n_getfield nodes.setfield = n_setfield diff --git a/tex/context/base/mkiv/node-pro.lua b/tex/context/base/mkiv/node-pro.lua index 8a501a590..3251b0133 100644 --- a/tex/context/base/mkiv/node-pro.lua +++ b/tex/context/base/mkiv/node-pro.lua @@ -202,8 +202,8 @@ do local texnest = tex.nest local getlist = nodes.getlist - local getsubtype = nodes.getsubtype local setlist = nodes.setlist + local getsubtype = nodes.getsubtype local line_code = nodes.listcodes.line @@ -213,11 +213,14 @@ do if groupcode == "box" then -- "pre_box" local whatever = texnest[texnest.ptr] if whatever then - local tail = whatever.tail - if tail and getsubtype(tail) == line_code then - local okay, done = actions(tail,groupcode) - if okay and okay ~= tail then - setlist(tail,okay) + local line = whatever.tail + if line and getsubtype(line) == line_code then + local head = getlist(line) + if head then + local okay, done = actions(head,groupcode,line) + if okay and okay ~= head then + setlist(line,okay) + end end end end diff --git a/tex/context/base/mkiv/node-scn.lua b/tex/context/base/mkiv/node-scn.lua index 2409750c2..67a0badec 100644 --- a/tex/context/base/mkiv/node-scn.lua +++ b/tex/context/base/mkiv/node-scn.lua @@ -238,9 +238,11 @@ nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlist return tonode(head), done end --- +-- works on lines ! + +-- todo: stack because skip can change when nested -local function processranges(attribute,flush,head,parent) +local function processranges(attribute,flush,head,parent,depth,skip) local n = head if n then local f, l, a @@ -249,7 +251,8 @@ local function processranges(attribute,flush,head,parent) local id = getid(n) if id == glyph_code or id == rule_code then local aa = getattr(n,attribute) - if aa and aa ~= skip then +-- if aa and (not skip or aa ~= skip) then + if aa then if aa == a then if not f then f = n @@ -257,13 +260,13 @@ local function processranges(attribute,flush,head,parent) l = n else if f then - head, done = flush(head,f,l,a,parent), true + head, done = flush(head,f,l,a,parent,depth), true end f, l, a = n, n, aa end else if f then - head, done = flush(head,f,l,a,parent), true + head, done = flush(head,f,l,a,parent,depth), true end f, l, a = nil, nil, nil end @@ -281,18 +284,35 @@ local function processranges(attribute,flush,head,parent) elseif id == glue_code then -- todo: leaders elseif id == hlist_code or id == vlist_code then - if f then - l = n + local aa = getattr(n,attribute) +-- if aa and (not skip or aa ~= skip) then + if aa then + if aa == a then + if not f then + f = n + end + l = n + else + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + f, l, a = n, n, aa + end + else + if f then + head, done = flush(head,f,l,a,parent,depth), true + end + f, l, a = nil, nil, nil end local list = getlist(n) if list then - setlist(n,(processranges(attribute,flush,list,n,aa))) + setlist(n,(processranges(attribute,flush,list,n,depth+1,aa))) end end n = getnext(n) end if f then - head, done = flush(head,f,l,a,parent), true + head, done = flush(head,f,l,a,parent,depth), true end return head, done else @@ -305,7 +325,6 @@ nodes.processranges = function(attribute,flush,head,parent) -- we have hlistdir if parent then parent = tonut(parent) end - local head, done = processranges(attribute,flush,head,parent) + local head, done = processranges(attribute,flush,head,parent,0) return tonode(head), done end - diff --git a/tex/context/base/mkiv/node-tsk.lua b/tex/context/base/mkiv/node-tsk.lua index 4dcbb27bd..c33f0e9f4 100644 --- a/tex/context/base/mkiv/node-tsk.lua +++ b/tex/context/base/mkiv/node-tsk.lua @@ -443,7 +443,7 @@ tasks.new { tasks.new { name = "contributers", - arguments = 1, + arguments = 2, -- [head] where parent processor = nodeprocessor, sequence = { "before", -- for users diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua index c7eec18ee..569dfb982 100644 --- a/tex/context/base/mkiv/spac-ver.lua +++ b/tex/context/base/mkiv/spac-ver.lua @@ -368,6 +368,17 @@ local function fixedprofile(current) return profiling and profiling.fixedprofile(current) end +-- local function onlyoneentry(t) +-- local n = 1 +-- for k, v in next, t do +-- if n > 1 then +-- return false +-- end +-- n = n + 1 +-- end +-- return true +-- end + local function snap_hlist(where,current,method,height,depth) -- method[v_strut] is default if fixedprofile(current) then return @@ -429,6 +440,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] t[#t+1] = formatters["hlist: wd %p ht %p (used %p) dp %p (used %p)"](wd,ht,h,dp,d) t[#t+1] = formatters["fractions: hfraction %s dfraction %s bfraction %s tlines %s blines %s"](hr,dr,br,tlines,blines) end + if method[v_box] then local br = 1 - br if br < 0 then @@ -440,20 +452,38 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] local x = n * snaphtdp - h - d plusht = h + x / 2 plusdp = d + x / 2 + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_box,plusht,plusdp) + end elseif method[v_max] then local n = ceiled((h+d)/snaphtdp) local x = n * snaphtdp - h - d plusht = h + x / 2 plusdp = d + x / 2 + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_max,plusht,plusdp) + end elseif method[v_min] then - local n = floored((h+d)/snaphtdp) - local x = n * snaphtdp - h - d - plusht = h + x / 2 - plusdp = d + x / 2 + -- we catch a lone min + if method.specification ~= v_min then + local n = floored((h+d)/snaphtdp) + local x = n * snaphtdp - h - d + plusht = h + x / 2 + plusdp = d + x / 2 + if plusht < 0 then + plusht = 0 + end + if plusdp < 0 then + plusdp = 0 + end + end + if t then + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_min,plusht,plusdp) + end elseif method[v_none] then plusht, plusdp = 0, 0 if t then - t[#t+1] = "none: plusht 0pt plusdp 0pt" + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_none,0,0) end end -- for now, we actually need to tag a box and then check at several points if something ended up @@ -463,7 +493,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] plusht = plusht + extra plusdp = plusdp + extra if t then - t[#t+1] = formatters["halfline: plusht %p plusdp %p"](plusht,plusdp) + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_halfline,plusht,plusdp) end end if method[v_line] then -- extra line @@ -471,7 +501,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] plusht = plusht + extra plusdp = plusdp + extra if t then - t[#t+1] = formatters["line: plusht %p plusdp %p"](plusht,plusdp) + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_line,plusht,plusdp) end end if method[v_halfline_m] then -- extra halfline @@ -479,7 +509,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] plusht = plusht + extra plusdp = plusdp + extra if t then - t[#t+1] = formatters["-halfline: plusht %p plusdp %p"](plusht,plusdp) + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_halfline_m,plusht,plusdp) end end if method[v_line_m] then -- extra line @@ -487,7 +517,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] plusht = plusht + extra plusdp = plusdp + extra if t then - t[#t+1] = formatters["-line: plusht %p plusdp %p"](plusht,plusdp) + t[#t+1] = formatters["%s: plusht %p plusdp %p"](v_line_m,plusht,plusdp) end end if method[v_first] then @@ -606,7 +636,6 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] t[#t+1] = formatters["bottom depth: %p"](cd) end end - local offset = method[v_offset] if offset then -- we need to set the attr @@ -640,9 +669,9 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] if t then local original = (h+d)/snaphtdp local whatever = (ch+cd)/(texgetdimen("globalbodyfontstrutheight") + texgetdimen("globalbodyfontstrutdepth")) - t[#t+1] = formatters["final lines: %s -> %s (%s)"](original,lines,whatever) + t[#t+1] = formatters["final lines : %p -> %p (%p)"](original,lines,whatever) t[#t+1] = formatters["final height: %p -> %p"](h,ch) - t[#t+1] = formatters["final depth: %p -> %p"](d,cd) + t[#t+1] = formatters["final depth : %p -> %p"](d,cd) end -- todo: -- diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 24a936e81..9f7079e28 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 8813b05ad..30bf8b4b4 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 152dd82cb..9ec728d6f 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex 069ad08be..dd1ffacc0 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index dc16e2426..baf9b1a8f 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 02/19/17 17:14:56 +-- merge date : 02/20/17 15:10:11 do -- begin closure to overcome local limits and interference @@ -20956,16 +20956,48 @@ local function testrun(disc,t_run,c_run,...) end local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) local done=false - if replace and prev then - setlink(replacetail,next) - local ok,overflow=t_run(replace,next,...) - if ok and overflow then - setfield(disc,"replace") - setlink(prev,replace) - setboth(disc) - flush_node_list(disc) - return replace,true + if (post or replace) and prev then + if post then + setlink(posttail,next) + else + post=next + end + if replace then + setlink(replacetail,next) else + replace=next + end + local d_post=t_run(post,next,...) + local d_replace=t_run(replace,next,...) + if (d_post and d_post>0) or (d_replace and d_replace>0) then + local d=d_replace or d_post + if d_post and d<d_post then + d=d_post + end + local head,tail=getnext(disc),disc + for i=1,d do + tail=getnext(tail) + if getid(tail)==disc_code then + head,tail=flattendisk(head,tail) + end + end + local next=getnext(tail) + setnext(tail) + setprev(head) + local new=copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post=head + end + if replacetail then + setlink(replacetail,new) + else + replace=new + end + setlink(disc,next) + else + setnext(posttail) setnext(replacetail) setprev(next,disc) end @@ -21050,6 +21082,7 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm return head,done end local function t_run_single(start,stop,font,attr,lookupcache) + local lastd=nil while start~=stop do local char=ischar(start,font) if char then @@ -21062,29 +21095,59 @@ local function t_run_single(start,stop,font,attr,lookupcache) local lookupmatch=lookupcache[char] if lookupmatch then local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end local l=nil local d=0 while s do - if s==stop then - d=1 - elseif d>0 then - d=d+1 - end local lg=lookupmatch[getchar(s)] if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end l=lg s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end else break end end if l and l.ligature then - return true,d>1 + lastd=d end end else end - start=starttnext + if lastd then + return lastd + end + start=startnext else break end @@ -21166,6 +21229,7 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm return head,done end local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd=nil while start~=stop do local char=ischar(start,font) if char then @@ -21182,24 +21246,51 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) local lookupmatch=lookupcache[char] if lookupmatch then local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end local l=nil local d=0 while s do - if s==stop then - d=1 - elseif d>0 then - d=d+1 - end local lg=lookupmatch[getchar(s)] if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end l=lg s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end else break end end if l and l.ligature then - return true,d>1 + lastd=d end end else @@ -21208,6 +21299,9 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end else end + if lastd then + return lastd + end start=startnext else break |