diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/font-sol.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/font-sol.lua | 128 |
1 files changed, 54 insertions, 74 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-sol.lua b/Master/texmf-dist/tex/context/base/mkiv/font-sol.lua index 002f9df131f..8967d88e60b 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-sol.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-sol.lua @@ -54,6 +54,8 @@ local settings_to_hash = utilities.parsers.settings_to_hash local tasks = nodes.tasks local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode local getfield = nuts.getfield local getnext = nuts.getnext @@ -63,10 +65,8 @@ local getattr = nuts.getattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getlist = nuts.getlist -local getdirection = nuts.getdirection +local getdir = nuts.getdir local getwidth = nuts.getwidth -local getdata = nuts.getdata - local getboxglue = nuts.getboxglue local setattr = nuts.setattr @@ -78,15 +78,13 @@ local find_node_tail = nuts.tail local flush_node = nuts.flush_node local flush_node_list = nuts.flush_list local copy_node_list = nuts.copy_list +local traverse_nodes = nuts.traverse +local traverse_ids = nuts.traverse_id local hpack_nodes = nuts.hpack local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local protect_glyphs = nuts.protect_glyphs -local nextnode = nuts.traversers.next -local nexthlist = nuts.traversers.hlist -local nextwhatsit = nuts.traversers.whatsit - local repack_hlist = nuts.repackhlist local nodes_to_utf = nodes.listtoutf @@ -110,15 +108,13 @@ local whatsit_code = nodecodes.whatsit local fontkern_code = kerncodes.fontkern -local userdefinedwhatsit_code = whatsitcodes.userdefined - -local nodeproperties = nodes.properties.data +local userdefined_code = whatsitcodes.userdefined local nodepool = nuts.pool local usernodeids = nodepool.userids -local new_direction = nodepool.direction -local new_usernode = nodepool.usernode +local new_textdir = nodepool.textdir +local new_usernumber = nodepool.usernumber local new_glue = nodepool.glue local new_leftskip = nodepool.leftskip @@ -241,6 +237,7 @@ local function convert(featuresets,name,list) fs = contextsetups[feature] fn = fs and fs.number end +-- inspect(fs) if fn then nofnumbers = nofnumbers + 1 numbers[nofnumbers] = fn @@ -347,23 +344,20 @@ directives.register("builders.paragraphs.solutions.splitters.encapsulate", funct encapsulate = v end) -function splitters.split(head) -- best also pass the direction - local current = head - local r2l = false - local start = nil - local stop = nil - local attribute = 0 - cache = { } - max_less = 0 - max_more = 0 +function splitters.split(head) + -- quite fast + head = tonut(head) + local current, done, rlmode, start, stop, attribute = head, false, false, nil, nil, 0 + cache, max_less, max_more = { }, 0, 0 local function flush() -- we can move this local font = getfont(start) local last = getnext(stop) - local list = last and copy_node_list(start,last) or copy_node_list(start) - local n = #cache + 1 +-- local list = last and copy_node_list(start,last) or copy_node_list(start) + local list = last and copy_node_list(start,stop) or copy_node_list(start) + local n = #cache + 1 if encapsulate then - local user_one = new_usernode(splitter_one,n) - local user_two = new_usernode(splitter_two,n) + local user_one = new_usernumber(splitter_one,n) + local user_two = new_usernumber(splitter_two,n) head, start = insert_node_before(head,start,user_one) insert_node_after(head,stop,user_two) else @@ -377,8 +371,9 @@ function splitters.split(head) -- best also pass the direction end end end + local r2l = rlmode == "TRT" or rlmode == "+TRT" if r2l then - local dirnode = new_direction(righttoleft) -- brrr, we don't pop ... to be done (when used at all) + local dirnode = new_textdir("+TRT") setlink(dirnode,list) list = dirnode end @@ -398,7 +393,7 @@ function splitters.split(head) -- best also pass the direction local m = #solution.more if l > max_less then max_less = l end if m > max_more then max_more = m end - start, stop = nil, nil + start, stop, done = nil, nil, true end while current do -- also ischar local next = getnext(current) @@ -427,19 +422,11 @@ function splitters.split(head) -- best also pass the direction else start, stop = nil, nil end - elseif id == dir_code then - -- not tested (to be done by idris when font is ready) + elseif id == dir_code or id == localpar_code then if start then flush() end - local direction, pop = getdirection(current) - r2l = not pop and direction == righttoleft - elseif id == localpar_code and getsubtype(current) == 0 then - if start then - flush() -- very unlikely as this starts a paragraph - end - local direction = getdirection(current) - r2l = direction == righttoleft or direction == "TRT" -- for old times sake + rlmode = getdir(current) else if start then flush() @@ -451,37 +438,31 @@ function splitters.split(head) -- best also pass the direction flush() end nofparagraphs = nofparagraphs + 1 - nofwords = nofwords + #cache - return head + nofwords = nofwords + #cache + return tonode(head), done end local function collect_words(list) -- can be made faster for attributes - local words = { } - local w = 0 - local word = nil + local words, w, word = { }, 0, nil if encapsulate then - for current, subtype in nextwhatsit, list do - if subtype == userdefinedwhatsit_code then -- hm - local p = nodeproperties[current] - if p then - local user_id = p.id - if user_id == splitter_one then - word = { p.data, current, current } - w = w + 1 - words[w] = word - elseif user_id == splitter_two then - if word then - word[3] = current - else - -- something is wrong - end + for current in traverse_ids(whatsit_code,list) do + if getsubtype(current) == userdefined_code then -- hm + local user_id = getfield(current,"user_id") + if user_id == splitter_one then + word = { getfield(current,"value"), current, current } + w = w + 1 + words[w] = word + elseif user_id == splitter_two then + if word then + word[3] = current + else + -- something is wrong end end end end else - local first, last, index - local current = list + local current, first, last, index = list, nil, nil, nil while current do -- todo: disc and kern local id = getid(current) @@ -546,9 +527,7 @@ local function collect_words(list) -- can be made faster for attributes if trace_split then for i=1,#words do local w = words[i] - local n = w[1] - local f = w[2] - local l = w[3] + local n, f, l = w[1], w[2], w[3] local c = cache[n] if c then report_splitters("found %4i: word %a, cached %a",n,nodes_to_utf(f,true,true,l),nodes_to_utf(c.original,true)) @@ -605,20 +584,21 @@ local function doit(word,list,best,width,badness,line,set,listdir) noftries = noftries + 1 local first = copy_node_list(original) if not trace_colors then - for n in nextnode, first do -- maybe fast force so no attr needed + for n in traverse_nodes(first) do -- maybe fast force so no attr needed setattr(n,0,featurenumber) -- this forces dynamics end elseif set == "less" then - for n in nextnode, first do + for n in traverse_nodes(first) do setnodecolor(n,"font:isol") -- yellow setattr(n,0,featurenumber) end else - for n in nextnode, first do + for n in traverse_nodes(first) do setnodecolor(n,"font:medi") -- green setattr(n,0,featurenumber) end end +first = tonode(first) local font = found.font local setdynamics = setfontdynamics[font] if setdynamics then @@ -630,6 +610,7 @@ local function doit(word,list,best,width,badness,line,set,listdir) report_solutions("fatal error, no dynamics for font %a",font) end first = inject_kerns(first) +first = tonut(first) if getid(first) == whatsit_code then local temp = first first = getnext(first) @@ -772,19 +753,19 @@ function splitters.optimize(head) if trace_optimize then report_optimizers("preroll %a, variant %a, criterium %a, cache size %a",preroll,variant,criterium,nc) end - for current in nexthlist, head do + for current in traverse_ids(hlist_code,tonut(head)) do line = line + 1 - local sign = getfield(current,"glue_sign") - local direction = getdirection(current) - local width = getwidth(current) - local list = getlist(current) + local sign = getfield(current,"glue_sign") + local dir = getdir(current) + local width = getwidth(current) + local list = getlist(current) if not encapsulate and getid(list) == glyph_code then -- nasty .. we always assume a prev being there .. future luatex will always have a leftskip set -- is this assignment ok ? .. needs checking list = insert_node_before(list,list,new_leftskip(0)) -- new_glue(0) setlist(current,list) end - local temp, badness = repack_hlist(list,width,"exactly",direction) -- it would be nice if the badness was stored in the node + local temp, badness = repack_hlist(list,width,'exactly',dir) -- it would be nice if the badness was stored in the node if badness > 0 then if sign == 0 then if trace_optimize then @@ -804,8 +785,7 @@ function splitters.optimize(head) set, max = "less", max_less end -- we can keep the best variants - local lastbest = nil - local lastbadness = badness + local lastbest, lastbadness = nil, badness if preroll then local bb, base for i=1,max do @@ -878,7 +858,7 @@ statistics.register("optimizer statistics", function() if nofwords > 0 then local elapsed = statistics.elapsedtime(splitters) local average = noftries/elapsed - return format("%s words identified in %s paragraphs, %s words retried, %s lines tried, %s seconds used, %s adapted, %0.1f lines per second", + return format("%s words identified in %s paragraphs, %s words retried, %s lines tried, %0.3f seconds used, %s adapted, %0.1f lines per second", nofwords,nofparagraphs,noftries,nofadapted+nofkept,elapsed,nofadapted,average) end end) |