diff options
Diffstat (limited to 'tex/context/base/font-sol.lua')
-rw-r--r-- | tex/context/base/font-sol.lua | 174 |
1 files changed, 72 insertions, 102 deletions
diff --git a/tex/context/base/font-sol.lua b/tex/context/base/font-sol.lua index a41e4a679..9ccfd0588 100644 --- a/tex/context/base/font-sol.lua +++ b/tex/context/base/font-sol.lua @@ -48,41 +48,19 @@ local v_split = variables.split local settings_to_array = utilities.parsers.settings_to_array 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 setfield = nuts.setfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getattr = nuts.getattr -local setattr = nuts.setattr -local getfont = nuts.getfont -local getsubtype = nuts.getsubtype -local getchar = nuts.getchar -local getlist = nuts.getlist - -local find_node_tail = nuts.tail -local free_node = nuts.free -local free_nodelist = nuts.flush_list -local copy_nodelist = 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 repack_hlist = nuts.repackhlist - +local find_node_tail = node.tail or node.slide +local free_node = node.free +local free_nodelist = node.flush_list +local copy_nodelist = node.copy_list +local traverse_nodes = node.traverse +local traverse_ids = node.traverse_id +local protect_glyphs = nodes.handlers.protectglyphs or node.protect_glyphs +local hpack_nodes = node.hpack +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after +local repack_hlist = nodes.repackhlist local nodes_to_utf = nodes.listtoutf ------ protect_glyphs = nodes.handlers.protectglyphs - local setnodecolor = nodes.tracers.colors.set local nodecodes = nodes.nodecodes @@ -101,7 +79,8 @@ local localpar_code = whatsitcodes.localpar local dir_code = whatsitcodes.dir local userdefined_code = whatsitcodes.userdefined -local nodepool = nuts.pool +local nodepool = nodes.pool +local tasks = nodes.tasks local usernodeids = nodepool.userids local new_textdir = nodepool.textdir @@ -111,7 +90,7 @@ local new_leftskip = nodepool.leftskip local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming ------ process_characters = nodes.handlers.characters +local process_characters = nodes.handlers.characters local inject_kerns = nodes.injections.handler local fonthashes = fonts.hashes @@ -338,12 +317,11 @@ end) 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 font = start.font + local last = stop.next local list = last and copy_nodelist(start,last) or copy_nodelist(start) local n = #cache + 1 if encapsulate then @@ -354,18 +332,18 @@ function splitters.split(head) else local current = start while true do - setattr(current,a_word,n) + current[a_word] = n if current == stop then break else - current = getnext(current) + current = current.next end end end if rlmode == "TRT" or rlmode == "+TRT" then local dirnode = new_textdir("+TRT") - setfield(list,"prev",dirnode) - setfield(dirnode,"next",list) + list.prev = dirnode + dirnode.next = list list = dirnode end local c = { @@ -386,11 +364,11 @@ function splitters.split(head) start, stop, done = nil, nil, true end while current do -- also nextid - local next = getnext(current) - local id = getid(current) + local next = current.next + local id = current.id if id == glyph_code then - if getsubtype(current) < 256 then - local a = getattr(current,a_split) + if current.subtype < 256 then + local a = current[a_split] if not a then start, stop = nil, nil elseif not start then @@ -406,7 +384,7 @@ function splitters.split(head) if start then flush() end - elseif start and next and getid(next) == glyph_code and getsubtype(next) < 256 then + elseif start and next and next.id == glyph_code and next.subtype < 256 then -- beware: we can cross future lines stop = next else @@ -416,9 +394,9 @@ function splitters.split(head) if start then flush() end - local subtype = getsubtype(current) + local subtype = current.subtype if subtype == dir_code or subtype == localpar_code then - rlmode = getfield(current,"dir") + rlmode = current.dir end else if start then @@ -432,17 +410,17 @@ function splitters.split(head) end nofparagraphs = nofparagraphs + 1 nofwords = nofwords + #cache - return tonode(head), done + return head, done end local function collect_words(list) -- can be made faster for attributes local words, w, word = { }, 0, nil if encapsulate then for current in traverse_ids(whatsit_code,list) do - if getsubtype(current) == userdefined_code then -- hm - local user_id = getfield(current,"user_id") + if current.subtype == userdefined_code then -- hm + local user_id = current.user_id if user_id == splitter_one then - word = { getfield(current,"value"), current, current } + word = { current.value, current, current } w = w + 1 words[w] = word elseif user_id == splitter_two then @@ -458,9 +436,9 @@ local function collect_words(list) -- can be made faster for attributes local current, first, last, index = list, nil, nil, nil while current do -- todo: disc and kern - local id = getid(current) + local id = current.id if id == glyph_code or id == disc_code then - local a = getattr(current,a_word) + local a = current[a_word] if a then if a == index then -- same word @@ -493,7 +471,7 @@ local function collect_words(list) -- can be made faster for attributes report_splitters("skipped: %C",current.char) end end - elseif id == kern_code and (getsubtype(current) == fontkern_code or getattr(current,a_fontkern)) then + elseif id == kern_code and (current.subtype == fontkern_code or current[a_fontkern]) then if first then last = current else @@ -511,7 +489,7 @@ local function collect_words(list) -- can be made faster for attributes end end end - current = getnext(current) + current = current.next end if index then w = w + 1 @@ -542,8 +520,8 @@ local function doit(word,list,best,width,badness,line,set,listdir) if found then local h, t if encapsulate then - h = getnext(word[2]) -- head of current word - t = getprev(word[3]) -- tail of current word + h = word[2].next -- head of current word + t = word[3].prev -- tail of current word else h = word[2] t = word[3] @@ -558,7 +536,7 @@ local function doit(word,list,best,width,badness,line,set,listdir) ok = true break else - c = getnext(c) + c = c.next end end if not ok then @@ -577,20 +555,19 @@ local function doit(word,list,best,width,badness,line,set,listdir) local first = copy_nodelist(original) if not trace_colors then for n in traverse_nodes(first) do -- maybe fast force so no attr needed - setattr(n,0,featurenumber) -- this forces dynamics + n[0] = featurenumber -- this forces dynamics end elseif set == "less" then for n in traverse_nodes(first) do setnodecolor(n,"font:isol") -- yellow - setattr(n,0,featurenumber) + n[0] = featurenumber end else for n in traverse_nodes(first) do setnodecolor(n,"font:medi") -- green - setattr(n,0,featurenumber) + n[0] = featurenumber end end -first = tonode(first) local font = found.font local setdynamics = setfontdynamics[font] if setdynamics then @@ -602,21 +579,20 @@ first = tonode(first) report_solutions("fatal error, no dynamics for font %a",font) end first = inject_kerns(first) -first = tonut(first) - if getid(first) == whatsit_code then + if first.id == whatsit_code then local temp = first - first = getnext(first) + first = first.next free_node(temp) end local last = find_node_tail(first) -- replace [u]h->t by [u]first->last - local prev = getprev(h) - local next = getnext(t) - setfield(prev,"next",first) - setfield(first,"prev",prev) + local prev = h.prev + local next = t.next + prev.next = first + first.prev = prev if next then - setfield(last,"next",next) - setfield(next,"prev",last) + last.next = next + next.prev = last end -- check new pack local temp, b = repack_hlist(list,width,'exactly',listdir) @@ -625,22 +601,22 @@ first = tonut(first) report_optimizers("line %a, badness before %a, after %a, criterium %a, verdict %a",line,badness,b,criterium,"quit") end -- remove last insert - setfield(prev,"next",h) - setfield(h,"prev",prev) + prev.next = h + h.prev = prev if next then - setfield(t,"next",next) - setfield(next,"prev",t) + t.next = next + next.prev = t else - setfield(t,"next",nil) + t.next = nil end - setfield(last,"next",nil) + last.next = nil free_nodelist(first) else if trace_optimize then report_optimizers("line %a, badness before: %a, after %a, criterium %a, verdict %a",line,badness,b,criterium,"continue") end -- free old h->t - setfield(t,"next",nil) + t.next = nil free_nodelist(h) -- somhow fails if not encapsulate then word[2] = first @@ -721,9 +697,9 @@ variants[v_random] = function(words,list,best,width,badness,line,set,listdir) end local function show_quality(current,what,line) - local set = getfield(current,"glue_set") - local sign = getfield(current,"glue_sign") - local order = getfield(current,"glue_order") + local set = current.glue_set + local sign = current.glue_sign + local order = current.glue_order local amount = set * ((sign == 2 and -1) or 1) report_optimizers("line %a, category %a, amount %a, set %a, sign %a, how %a, order %a",line,what,amount,set,sign,how,order) end @@ -743,25 +719,20 @@ function splitters.optimize(head) math.setrandomseedi(randomseed) randomseed = nil end - local line = 0 - local tex_hbadness = tex.hbadness - local tex_hfuzz = tex.hfuzz - tex.hbadness = 10000 - tex.hfuzz = number.maxdimen + local line = 0 + local tex_hbadness, tex_hfuzz = tex.hbadness, tex.hfuzz + tex.hbadness, tex.hfuzz = 10000, number.maxdimen if trace_optimize then report_optimizers("preroll %a, variant %a, criterium %a, cache size %a",preroll,variant,criterium,nc) end - for current in traverse_ids(hlist_code,tonut(head)) do + for current in traverse_ids(hlist_code,head) do + -- report_splitters("before: [%s] => %s",current.dir,nodes.tosequence(current.list,nil)) line = line + 1 - local sign = getfield(current,"glue_sign") - local dir = getfield(current,"dir") - local width = getfield(current,"width") - local list = getlist(current) - if not encapsulate and getid(list) == glyph_code then + local sign, dir, list, width = current.glue_sign, current.dir, current.list, current.width + if not encapsulate and list.id == 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) - setfield(current,"list",list) + -- current.list, list = insert_node_before(list,list,new_glue(0)) + current.list, list = insert_node_before(list,list,new_leftskip(0)) end 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 @@ -821,7 +792,7 @@ function splitters.optimize(head) local words = collect_words(list) for best=lastbest or 1,max do local temp, done, changes, b = optimize(words,list,best,width,badness,line,set,dir) - setfield(current,"list",temp) + current.list = temp if trace_optimize then report_optimizers("line %a, alternative %a, changes %a, badness %a",line,best,changes,b) end @@ -839,16 +810,15 @@ function splitters.optimize(head) end end -- we pack inside the outer hpack and that way keep the original wd/ht/dp as bonus - local list = hpack_nodes(getlist(current),width,'exactly',listdir) - setfield(current,"list",list) + current.list = hpack_nodes(current.list,width,'exactly',listdir) + -- report_splitters("after: [%s] => %s",temp.dir,nodes.tosequence(temp.list,nil)) end for i=1,nc do local ci = cache[i] free_nodelist(ci.original) end cache = { } - tex.hbadness = tex_hbadness - tex.hfuzz = tex_hfuzz + tex.hbadness, tex.hfuzz = tex_hbadness, tex_hfuzz stoptiming(splitters) end |