diff options
author | Hans Hagen <pragma@wxs.nl> | 2017-02-17 10:31:56 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2017-02-17 10:31:56 +0100 |
commit | b14f992ef5f4e868c9959b174278c86516d60dbc (patch) | |
tree | 28587bb46c025ea7b0d27ba93f09c93dcf53c73a /tex/context/base/mkiv/node-ltp.lua | |
parent | 95a1799032dc61dbca4a11e495be34b4397c8fec (diff) | |
download | context-b14f992ef5f4e868c9959b174278c86516d60dbc.tar.gz |
2017-02-17 10:23:00
Diffstat (limited to 'tex/context/base/mkiv/node-ltp.lua')
-rw-r--r-- | tex/context/base/mkiv/node-ltp.lua | 1334 |
1 files changed, 677 insertions, 657 deletions
diff --git a/tex/context/base/mkiv/node-ltp.lua b/tex/context/base/mkiv/node-ltp.lua index 32b11267b..22a4799ad 100644 --- a/tex/context/base/mkiv/node-ltp.lua +++ b/tex/context/base/mkiv/node-ltp.lua @@ -21,6 +21,7 @@ if not modules then modules = { } end modules ['node-par'] = { -- todo: check and improve protrusion -- todo: arabic etc (we could use pretty large scales there) .. marks and cursive -- todo: see: we need to check this with the latest patches to the tex kernel +-- todo: adapt math glue spacing to new model (left/right) -- todo: optimize a bit more (less par.*) @@ -139,14 +140,13 @@ local sub, formatters = string.sub, string.formatters local round, floor = math.round, math.floor local insert, remove = table.insert, table.remove -local fonts, nodes, node = fonts, nodes, node +-- local fonts, nodes, node = fonts, nodes, node -- too many locals local trace_basic = false trackers.register("builders.paragraphs.basic", function(v) trace_basic = v end) local trace_lastlinefit = false trackers.register("builders.paragraphs.lastlinefit", function(v) trace_lastlinefit = v end) local trace_adjusting = false trackers.register("builders.paragraphs.adjusting", function(v) trace_adjusting = v end) local trace_protruding = false trackers.register("builders.paragraphs.protruding", function(v) trace_protruding = v end) local trace_expansion = false trackers.register("builders.paragraphs.expansion", function(v) trace_expansion = v end) -local trace_quality = false trackers.register("builders.paragraphs.quality", function(v) trace_quality = v end) local report_parbuilders = logs.reporter("nodes","parbuilders") ----- report_hpackers = logs.reporter("nodes","hpackers") @@ -207,7 +207,14 @@ local getattr = nuts.getattr local getdisc = nuts.getdisc local getglue = nuts.getglue local getwhd = nuts.getwhd -local setwhd = nuts.setwhd +local getcomponents = nuts.getcomponents +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getdir = nuts.getdir +local getshift = nuts.getshift +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth local isglyph = nuts.isglyph @@ -220,6 +227,13 @@ local setprev = nuts.setprev local setdisc = nuts.setdisc local setsubtype = nuts.setsubtype local setglue = nuts.setglue +local setwhd = nuts.setwhd +local setkern = nuts.setkern +local setdir = nuts.setdir +local setshift = nuts.setshift +local setwidth = nuts.setwidth +----- getheight = nuts.getheight +----- getdepth = nuts.getdepth local slide_node_list = nuts.slide -- get rid of this, probably ok > 78.2 local find_tail = nuts.tail @@ -233,8 +247,6 @@ local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local is_zero_glue = nuts.is_zero_glue -local setnodecolor = nodes.tracers.colors.set - local nodepool = nuts.pool local nodecodes = nodes.nodecodes @@ -352,12 +364,12 @@ local function checked_line_dir(stack,current) local n = stack.n + 1 stack.n = n stack[n] = current - return getfield(current,"dir") + return getdir(current) elseif n > 0 then local n = stack.n local dirnode = stack[n] dirstack.n = n - 1 - return getfield(dirnode,"dir") + return getdir(dirnode) else report_parbuilders("warning: missing pop node (%a)",1) -- in line ... end @@ -374,7 +386,7 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop) while start and start ~= stop do local id = getid(start) if id == dir_code then - if not dir_pops[getfield(start,"dir")] then -- weird, what is this # + if not dir_pops[getdir(start)] then -- weird, what is this # n = n + 1 stack[n] = start elseif n > 0 then @@ -386,7 +398,7 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop) start = getnext(start) end for i=n,1,-1 do - h, current = insert_node_after(current,current,new_dir(dir_negations[getfield(stack[i],"dir")])) + h, current = insert_node_after(current,current,new_dir(dir_negations[getdir(stack[i])])) end stack.n = n return current @@ -754,13 +766,13 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw end elseif id == hlist_code or id == vlist_code then local wd, ht, dp = getwhd(s) - if is_parallel[getfield(s,"dir")][line_break_dir] then + if is_parallel[getdir(s)][line_break_dir] then size = size + wd else size = size + ht + dp end elseif id == kern_code then - local kern = getfield(s,"kern") + local kern = getkern(s) if kern ~= 0 then if checked_expansion and expand_kerns and (getsubtype(s) == kerning_code or getattr(a_fontkern)) then local stretch, shrink = kern_stretch_shrink(s,kern) @@ -776,7 +788,7 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw size = size + kern end elseif id == rule_code then - size = size + getfield(s,"width") + size = size + getwidth(s) elseif trace_unsupported then report_parbuilders("unsupported node at location %a",6) end @@ -831,12 +843,12 @@ local function compute_break_width(par,break_type,p) -- split in two elseif id == kern_code then local s = getsubtype(p) if s == userkern_code or s == italickern_code then - break_width.size = break_width.size - getfield(p,"kern") + break_width.size = break_width.size - getkern(p) else return end elseif id == math_code then - break_width.size = break_width.size - getfield(p,"surround") + break_width.size = break_width.size - getkern(p) -- surround -- new in luatex local wd, stretch, shrink, stretch_order = getglue(p) local order = stretch_orders[stretch_order] @@ -859,7 +871,7 @@ local function append_to_vlist(par, b) if prev_depth > ignore_depth then if is_hlist then local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip) - local delta = width - prev_depth - getfield(b,"height") -- deficiency of space between baselines + local delta = width - prev_depth - getheight(b) -- deficiency of space between baselines local skip = nil if delta < par.line_skip_limit then width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip) @@ -882,7 +894,7 @@ local function append_to_vlist(par, b) par.head_field = b end if is_hlist then - local pd = getfield(b,"depth") + local pd = getdepth(b) par.prev_depth = pd texnest[texnest.ptr].prevdepth = pd end @@ -1303,9 +1315,9 @@ local function post_line_break(par) setdisc(lastnode) -- nil, nil, nil disc_break = true elseif id == kern_code then - setfield(lastnode,"kern",0) + setkern(lastnode,0) elseif getid(lastnode) == math_code then - setfield(lastnode,"surround",0) + setkern(lastnode,0) -- surround -- new in luatex setglue(lastnode) -- zeros end @@ -1398,21 +1410,21 @@ local function post_line_break(par) local adjust_head = texlists.adjust_head local pre_adjust_head = texlists.pre_adjust_head -- - setfield(finished_line,"shift",cur_indent) + setshift(finished_line,cur_indent) -- -- -- this is gone: -- -- if par.each_line_height ~= ignored_dimen then - -- setfield(finished_line,"height",par.each_line_height) + -- setheight(finished_line,par.each_line_height) -- end -- if par.each_line_depth ~= ignored_dimen then - -- setfield(finished_line,"depth",par.each_line_depth) + -- setdepth(finished_line,par.each_line_depth) -- end -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then - -- setfield(finished_line,"height",par.first_line_height) + -- setheight(finished_line,par.first_line_height) -- end -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then - -- setfield(finished_line,"depth",par.last_line_depth) + -- setdepth(finished_line,par.last_line_depth) -- end -- if texlists.pre_adjust_head ~= pre_adjust_head then @@ -1473,7 +1485,7 @@ local function post_line_break(par) break elseif id == math_code then -- keep the math node - setfield(next,"surround",0) + setkern(next,0) -- surround -- new in luatex setglue(lastnode) -- zeros break @@ -1519,7 +1531,7 @@ local function wrap_up(par) par.do_last_line_fit = false else local glue = par.final_par_glue - setfield(glue,"width",getfield(glue,"width") + active_short - active_glue) + setwidth(glue,getwidth(glue) + active_short - active_glue) setfield(glue,"stretch",0) if trace_lastlinefit then report_parbuilders("applying last line fit, short %a, glue %p",active_short,active_glue) @@ -2263,7 +2275,7 @@ function constructors.methods.basic(head,d) end elseif id == hlist_code or id == vlist_code then local wd, ht, dp = getwhd(current) - if is_parallel[getfield(current,"dir")][par.line_break_dir] then + if is_parallel[getdir(current)][par.line_break_dir] then active_width.size = active_width.size + wd else active_width.size = active_width.size + ht + dp @@ -2298,7 +2310,7 @@ function constructors.methods.basic(head,d) if second_pass or subtype <= automatic_disc_code then local actual_pen = subtype == automatic_disc_code and par.ex_hyphen_penalty or par.hyphen_penalty -- 0.81 : - -- local actual_pen = getfield(current,"penalty") + -- local actual_pen = getpenalty(current) -- local pre, post, replace = getdisc(current) if not pre then -- trivial pre-break @@ -2377,9 +2389,9 @@ function constructors.methods.basic(head,d) p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) end local active_width = par.active_width - active_width.size = active_width.size + getfield(current,"kern") + active_width.size = active_width.size + getkern(current) else - local kern = getfield(current,"kern") + local kern = getkern(current) if kern ~= 0 then active_width.size = active_width.size + kern if checked_expansion and expand_kerns and (getsubtype(current) == kerning_code or getattr(current,a_fontkern)) then @@ -2404,13 +2416,13 @@ function constructors.methods.basic(head,d) p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) end local active_width = par.active_width - active_width.size = active_width.size + getfield(current,"surround") + active_width.size = active_width.size + getkern(current) -- surround -- new in luatex - + getfield(current,"width") + + getwidth(current) elseif id == rule_code then - active_width.size = active_width.size + getfield(current,"width") + active_width.size = active_width.size + getwidth(current) elseif id == penalty_code then - p_active, n_active = try_break(getfield(current,"penalty"), unhyphenated_code, par, first_p, current, checked_expansion) + p_active, n_active = try_break(getpenalty(current), unhyphenated_code, par, first_p, current, checked_expansion) elseif id == dir_code then par.line_break_dir = checked_line_dir(dirstack) or par.line_break_dir elseif id == localpar_code then @@ -2492,144 +2504,190 @@ end -- standard tex logging .. will be adapted .. -local function write_esc(cs) - local esc = tex.escapechar - if esc then - write("log",utfchar(esc),cs) - else - write("log",cs) +do + + local function write_esc(cs) + local esc = tex.escapechar + if esc then + write("log",utfchar(esc),cs) + else + write("log",cs) + end end -end -function diagnostics.start() -end + function diagnostics.start() + end -function diagnostics.stop() - write_nl("log",'') -end + function diagnostics.stop() + write_nl("log",'') + end -function diagnostics.current_pass(par,what) - write_nl("log",formatters["@%s"](what)) -end + function diagnostics.current_pass(par,what) + write_nl("log",formatters["@%s"](what)) + end -local verbose = false -- true + local verbose = false -- true -local function short_display(target,a,font_in_short_display) - while a do - local char, id = isglyph(a) - if char then - local font = getfont(a) - if font ~= font_in_short_display then - write(target,tex.fontidentifier(font) .. ' ') - font_in_short_display = font - end - if getsubtype(a) == ligature_code then - font_in_short_display = short_display(target,getfield(a,"components"),font_in_short_display) - else - write(target,utfchar(char)) - end - elseif id == disc_code then - local pre, post, replace = getdisc(a) - font_in_short_display = short_display(target,pre,font_in_short_display) - font_in_short_display = short_display(target,post,font_in_short_display) - elseif verbose then - write(target,formatters["[%s]"](nodecodes[id])) - elseif id == rule_code then - write(target,"|") - elseif id == glue_code then - write(target," ") - elseif id == kern_code then - local s = getsubtype(a) - if s == userkern_code or s == italickern_code or getattr(a,a_fontkern) then - if verbose then - write(target,"[|]") - -- else - -- write(target,"") + local function short_display(target,a,font_in_short_display) + while a do + local char, id = isglyph(a) + if char then + local font = getfont(a) + if font ~= font_in_short_display then + write(target,tex.fontidentifier(font) .. ' ') + font_in_short_display = font + end + -- todo: instead of components the split tounicode string + if getsubtype(a) == ligature_code then + font_in_short_display = short_display(target,getcomponents(a),font_in_short_display) + else + write(target,utfchar(char)) + end + elseif id == disc_code then + local pre, post, replace = getdisc(a) + font_in_short_display = short_display(target,pre,font_in_short_display) + font_in_short_display = short_display(target,post,font_in_short_display) + elseif verbose then + write(target,formatters["[%s]"](nodecodes[id])) + elseif id == rule_code then + write(target,"|") + elseif id == glue_code then + write(target," ") + elseif id == kern_code then + local s = getsubtype(a) + if s == userkern_code or s == italickern_code or getattr(a,a_fontkern) then + if verbose then + write(target,"[|]") + -- else + -- write(target,"") + end + else + write(target,"[]") end + elseif id == math_code then + write(target,"$") else write(target,"[]") end - elseif id == math_code then - write(target,"$") - else - write(target,"[]") + a = getnext(a) end - a = getnext(a) + return font_in_short_display end - return font_in_short_display -end -diagnostics.short_display = short_display + diagnostics.short_display = short_display -function diagnostics.break_node(par, q, fit_class, break_type, current) -- %d ? - local passive = par.passive - local typ_ind = break_type == hyphenated_code and '-' or "" - if par.do_last_line_fit then - local s = number.toscaled(q.active_short) - local g = number.toscaled(q.active_glue) - if current then - write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s g=%s"]( - passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + function diagnostics.break_node(par, q, fit_class, break_type, current) -- %d ? + local passive = par.passive + local typ_ind = break_type == hyphenated_code and '-' or "" + if par.do_last_line_fit then + local s = number.toscaled(q.active_short) + local g = number.toscaled(q.active_glue) + if current then + write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s g=%s"]( + passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + else + write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s a=%s"]( + passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + end else - write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s a=%s"]( - passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g)) + write_nl("log",formatters["@@%d: line %d.%d%s t=%s"]( + passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits)) + end + if not passive.prev_break then + write("log"," -> @0") + else + write("log",formatters[" -> @%d"](passive.prev_break.serial or 0)) end - else - write_nl("log",formatters["@@%d: line %d.%d%s t=%s"]( - passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits)) - end - if not passive.prev_break then - write("log"," -> @0") - else - write("log",formatters[" -> @%d"](passive.prev_break.serial or 0)) end -end -function diagnostics.feasible_break(par, current, r, b, pi, d, artificial_demerits) - local printed_node = par.printed_node - if printed_node ~= current then - write_nl("log","") + function diagnostics.feasible_break(par, current, r, b, pi, d, artificial_demerits) + local printed_node = par.printed_node + if printed_node ~= current then + write_nl("log","") + if not current then + par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) + else + local save_link = getnext(current) + setnext(current) + write_nl("log","") + par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) + setnext(current,save_link) + end + par.printed_node = current + end + write_nl("log","@") if not current then - par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) + write_esc("par") else - local save_link = getnext(current) - setnext(current) - write_nl("log","") - par.font_in_short_display = short_display("log",getnext(printed_node),par.font_in_short_display) - setnext(current,save_link) + local id = getid(current) + if id == glue_code then + -- print nothing + elseif id == penalty_code then + write_esc("penalty") + elseif id == disc_code then + write_esc("discretionary") + elseif id == kern_code then + write_esc("kern") + elseif id == math_code then + write_esc("math") + else + write_esc("unknown") + end + end + local via, badness, demerits = 0, '*', '*' + if r.break_node then + via = r.break_node.serial or 0 + end + if b <= infinite_badness then + badness = tonumber(d) + end + if not artificial_demerits then + demerits = tonumber(d) end - par.printed_node = current + write("log",formatters[" via @%d b=%s p=%s d=%s"](via,badness,pi,demerits)) end - write_nl("log","@") - if not current then - write_esc("par") - else - local id = getid(current) - if id == glue_code then - -- print nothing - elseif id == penalty_code then - write_esc("penalty") - elseif id == disc_code then - write_esc("discretionary") - elseif id == kern_code then - write_esc("kern") - elseif id == math_code then - write_esc("math") + + -- + + local function common_message(hlist,line,str) + write_nl("") + if status.output_active then -- unset + write(str," has occurred while \\output is active") + else + write(str) + end + local fileline = status.linenumber + if line > 0 then + write(formatters[" in paragraph at lines %s--%s"](fileline,"--",fileline+line-1)) + elseif line < 0 then + write(formatters[" in alignment at lines "](fileline,"--",fileline-line-1)) else - write_esc("unknown") + write(formatters[" detected at line %s"](fileline)) end + write_nl("") + diagnostics.short_display(getlist(hlist),false) + write_nl("") + -- diagnostics.start() + -- show_box(getlist(hlist)) + -- diagnostics.stop() + end + + function diagnostics.overfull_hbox(hlist,line,d) + common_message(hlist,line,formatters["Overfull \\hbox (%spt too wide)"](number.toscaled(d))) end - local via, badness, demerits = 0, '*', '*' - if r.break_node then - via = r.break_node.serial or 0 + + function diagnostics.bad_hbox(hlist,line,b) + common_message(hlist,line,formatters["Tight \\hbox (badness %i)"](b)) end - if b <= infinite_badness then - badness = tonumber(d) + + function diagnostics.underfull_hbox(hlist,line,b) + common_message(hlist,line,formatters["Underfull \\hbox (badness %i)"](b)) end - if not artificial_demerits then - demerits = tonumber(d) + + function diagnostics.loose_hbox(hlist,line,b) + common_message(hlist,line,formatters["Loose \\hbox (badness %i)"](b)) end - write("log",formatters[" via @%d b=%s p=%s d=%s"](via,badness,pi,demerits)) + end -- reporting -- @@ -2640,574 +2698,536 @@ statistics.register("alternative parbuilders", function() end end) --- actually scaling kerns is not such a good idea and it will become --- configureable - --- This is no way a replacement for the built in (fast) packer --- it's just an alternative for special (testing) purposes. --- --- We could use two hpacks: one to be used in the par builder --- and one to be used for other purposes. The one in the par --- builder is much more simple as it does not need the expansion --- code but only need to register the effective expansion factor --- with the glyph. - -local function glyph_width_height_depth(curdir,pdir,p) - local wd, ht, dp = getwhd(p) - if is_rotated[curdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else - local half = wd / 2 - return ht + dp, half, half - end - elseif is_rotated[pdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half +do + + -- actually scaling kerns is not such a good idea and it will become + -- configureable + + -- This is no way a replacement for the built in (fast) packer + -- it's just an alternative for special (testing) purposes. + -- + -- We could use two hpacks: one to be used in the par builder + -- and one to be used for other purposes. The one in the par + -- builder is much more simple as it does not need the expansion + -- code but only need to register the effective expansion factor + -- with the glyph. + + local setnodecolor = nodes.tracers.colors.set + + local function glyph_width_height_depth(curdir,pdir,p) + local wd, ht, dp = getwhd(p) + if is_rotated[curdir] then + if is_parallel[curdir][pdir] then + local half = (ht + dp) / 2 + return wd, half, half + else + local half = wd / 2 + return ht + dp, half, half + end + elseif is_rotated[pdir] then + if is_parallel[curdir][pdir] then + local half = (ht + dp) / 2 + return wd, half, half + else + return ht + dp, wd, 0 -- weird + end else - return ht + dp, wd, 0 -- weird - end - else - if glyphdir_is_equal[curdir][pdir] then - return wd, ht, dp - elseif is_opposite[curdir][pdir] then - return wd, dp, ht - else -- can this happen? - return ht + dp, wd, 0 + if glyphdir_is_equal[curdir][pdir] then + return wd, ht, dp + elseif is_opposite[curdir][pdir] then + return wd, dp, ht + else -- can this happen? + return ht + dp, wd, 0 + end end end -end -local function pack_width_height_depth(curdir,pdir,p) - local wd, ht, dp = getwhd(p) - if is_rotated[curdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else -- can this happen? - local half = wd / 2 - return ht + dp, half, half - end - else - if pardir_is_equal[curdir][pdir] then - return wd, ht, dp - elseif is_opposite[curdir][pdir] then - return wd, dp, ht - else -- weird dimensions, can this happen? - return ht + dp, wd, 0 + local function pack_width_height_depth(curdir,pdir,p) + local wd, ht, dp = getwhd(p) + if is_rotated[curdir] then + if is_parallel[curdir][pdir] then + local half = (ht + dp) / 2 + return wd, half, half + else -- can this happen? + local half = wd / 2 + return ht + dp, half, half + end + else + if pardir_is_equal[curdir][pdir] then + return wd, ht, dp + elseif is_opposite[curdir][pdir] then + return wd, dp, ht + else -- weird dimensions, can this happen? + return ht + dp, wd, 0 + end end end -end --- local function xpack(head,width,method,direction,analysis) --- --- -- inspect(analysis) --- --- local expansion = method == "cal_expand_ratio" --- local natural = analysis.size --- local font_stretch = analysis.adjust_stretch --- local font_shrink = analysis.adjust_shrink --- local font_expand_ratio = 0 --- local delta = width - natural --- --- local hlist = new_hlist() --- --- setlist(hlist,head) --- setfield(hlist,"dir",direction or tex.textdir) --- setfield(hlist,"width",width) --- setfield(hlist,"height",height) --- setfield(hlist,"depth",depth) --- --- if delta == 0 then --- --- setfield(hlist,"glue_sign",0) --- setfield(hlist,"glue_order",0) --- setfield(hlist,"glue_set",0) --- --- else --- --- local order = analysis.filll ~= 0 and fillcodes.filll or --- analysis.fill ~= 0 and fillcodes.fill or --- analysis.fil ~= 0 and fillcodes.fil or --- analysis.fi ~= 0 and fillcodes.fi or 0 --- --- if delta > 0 then --- --- if expansion and order == 0 and font_stretch > 0 then --- font_expand_ratio = (delta/font_stretch) * 1000 --- else --- local stretch = analysis.stretch --- if stretch ~= 0 then --- setfield(hlist,"glue_sign",1) -- stretch --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",delta/stretch) --- else --- setfield(hlist,"glue_sign",0) -- nothing --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",0) --- end --- end --- --- else --- --- if expansion and order == 0 and font_shrink > 0 then --- font_expand_ratio = (delta/font_shrink) * 1000 --- else --- local shrink = analysis.shrink --- if shrink ~= 0 then --- setfield(hlist,"glue_sign",2) -- shrink --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",-delta/stretch) --- else --- setfield(hlist,"glue_sign",0) -- nothing --- setfield(hlist,"glue_order",order) --- setfield(hlist,"glue_set",0) --- end --- end --- --- end --- --- end --- --- if not expansion or font_expand_ratio == 0 then --- -- nothing --- elseif font_expand_ratio > 0 then --- if font_expand_ratio > 1000 then --- font_expand_ratio = 1000 --- end --- local current = head --- while current do --- local id = getid(current) --- if id == glyph_code then --- local stretch, shrink = char_stretch_shrink(current) -- get only one --- if stretch then --- if trace_expansion then --- setnodecolor(g,"hz:positive") --- end --- current.expansion_factor = font_expand_ratio * stretch --- end --- elseif id == kern_code then --- local kern = getfield(current,"kern") --- if kern ~= 0 and getsubtype(current) == kerning_code then --- setfield(current,"kern",font_expand_ratio * kern) --- end --- end --- current = getnext(current) --- end --- elseif font_expand_ratio < 0 then --- if font_expand_ratio < -1000 then --- font_expand_ratio = -1000 --- end --- local current = head --- while current do --- local id = getid(current) --- if id == glyph_code then --- local stretch, shrink = char_stretch_shrink(current) -- get only one --- if shrink then --- if trace_expansion then --- setnodecolor(g,"hz:negative") --- end --- current.expansion_factor = font_expand_ratio * shrink --- end --- elseif id == kern_code then --- local kern = getfield(current,"kern") --- if kern ~= 0 and getsubtype(current) == kerning_code then --- setfield(current,"kern",font_expand_ratio * kern) --- end --- end --- current = getnext(current) --- end --- end --- return hlist, 0 --- end - -local function hpack(head,width,method,direction,firstline,line) -- fast version when head = nil - - -- we can pass the adjust_width and adjust_height so that we don't need to recalculate them but - -- with the glue mess it's less trivial as we lack detail .. challenge - - local hlist = new_hlist() - - setfield(hlist,"dir",direction) - - if head == nil then - setfield(hlist,"width",width) - return hlist, 0 - else - setlist(hlist,head) - end + -- local function xpack(head,width,method,direction,analysis) + -- + -- -- inspect(analysis) + -- + -- local expansion = method == "cal_expand_ratio" + -- local natural = analysis.size + -- local font_stretch = analysis.adjust_stretch + -- local font_shrink = analysis.adjust_shrink + -- local font_expand_ratio = 0 + -- local delta = width - natural + -- + -- local hlist = new_hlist() + -- + -- setlist(hlist,head) + -- setdir(hlist,direction or tex.textdir) + -- setwhd(hlist,width,height,depth) + -- + -- if delta == 0 then + -- + -- setfield(hlist,"glue_sign",0) + -- setfield(hlist,"glue_order",0) + -- setfield(hlist,"glue_set",0) + -- + -- else + -- + -- local order = analysis.filll ~= 0 and fillcodes.filll or + -- analysis.fill ~= 0 and fillcodes.fill or + -- analysis.fil ~= 0 and fillcodes.fil or + -- analysis.fi ~= 0 and fillcodes.fi or 0 + -- + -- if delta > 0 then + -- + -- if expansion and order == 0 and font_stretch > 0 then + -- font_expand_ratio = (delta/font_stretch) * 1000 + -- else + -- local stretch = analysis.stretch + -- if stretch ~= 0 then + -- setfield(hlist,"glue_sign",1) -- stretch + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",delta/stretch) + -- else + -- setfield(hlist,"glue_sign",0) -- nothing + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",0) + -- end + -- end + -- + -- else + -- + -- if expansion and order == 0 and font_shrink > 0 then + -- font_expand_ratio = (delta/font_shrink) * 1000 + -- else + -- local shrink = analysis.shrink + -- if shrink ~= 0 then + -- setfield(hlist,"glue_sign",2) -- shrink + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",-delta/stretch) + -- else + -- setfield(hlist,"glue_sign",0) -- nothing + -- setfield(hlist,"glue_order",order) + -- setfield(hlist,"glue_set",0) + -- end + -- end + -- + -- end + -- + -- end + -- + -- if not expansion or font_expand_ratio == 0 then + -- -- nothing + -- elseif font_expand_ratio > 0 then + -- if font_expand_ratio > 1000 then + -- font_expand_ratio = 1000 + -- end + -- local current = head + -- while current do + -- local id = getid(current) + -- if id == glyph_code then + -- local stretch, shrink = char_stretch_shrink(current) -- get only one + -- if stretch then + -- if trace_expansion then + -- setnodecolor(g,"hz:positive") + -- end + -- current.expansion_factor = font_expand_ratio * stretch + -- end + -- elseif id == kern_code then + -- local kern = getkern(current) + -- if kern ~= 0 and getsubtype(current) == kerning_code then + -- setkern(current,font_expand_ratio * kern) + -- end + -- end + -- current = getnext(current) + -- end + -- elseif font_expand_ratio < 0 then + -- if font_expand_ratio < -1000 then + -- font_expand_ratio = -1000 + -- end + -- local current = head + -- while current do + -- local id = getid(current) + -- if id == glyph_code then + -- local stretch, shrink = char_stretch_shrink(current) -- get only one + -- if shrink then + -- if trace_expansion then + -- setnodecolor(g,"hz:negative") + -- end + -- current.expansion_factor = font_expand_ratio * shrink + -- end + -- elseif id == kern_code then + -- local kern = getkern(current) + -- if kern ~= 0 and getsubtype(current) == kerning_code then + -- setkern(current,font_expand_ratio * kern) + -- end + -- end + -- current = getnext(current) + -- end + -- end + -- return hlist, 0 + -- end + + local function hpack(head,width,method,direction,firstline,line) -- fast version when head = nil + + -- we can pass the adjust_width and adjust_height so that we don't need to recalculate them but + -- with the glue mess it's less trivial as we lack detail .. challenge + + local hlist = new_hlist() + + setdir(hlist,direction) + + if head == nil then + setwidth(hlist,width) + return hlist, 0 + else + setlist(hlist,head) + end - local cal_expand_ratio = method == "cal_expand_ratio" or method == "subst_ex_font" + local cal_expand_ratio = method == "cal_expand_ratio" or method == "subst_ex_font" - direction = direction or tex.textdir + direction = direction or tex.textdir - local line = 0 + local line = 0 - local height = 0 - local depth = 0 - local natural = 0 - local font_stretch = 0 - local font_shrink = 0 - local font_expand_ratio = 0 - local last_badness = 0 - local expansion_stack = cal_expand_ratio and { } -- todo: optionally pass this - local expansion_index = 0 - local total_stretch = { [0] = 0, 0, 0, 0, 0 } - local total_shrink = { [0] = 0, 0, 0, 0, 0 } + local height = 0 + local depth = 0 + local natural = 0 + local font_stretch = 0 + local font_shrink = 0 + local font_expand_ratio = 0 + local last_badness = 0 + local expansion_stack = cal_expand_ratio and { } -- todo: optionally pass this + local expansion_index = 0 + local total_stretch = { [0] = 0, 0, 0, 0, 0 } + local total_shrink = { [0] = 0, 0, 0, 0, 0 } - local hpack_dir = direction + local hpack_dir = direction - local adjust_head = texlists.adjust_head - local pre_adjust_head = texlists.pre_adjust_head - local adjust_tail = adjust_head and slide_node_list(adjust_head) -- todo: find_tail - local pre_adjust_tail = pre_adjust_head and slide_node_list(pre_adjust_head) -- todo: find_tail + local adjust_head = texlists.adjust_head + local pre_adjust_head = texlists.pre_adjust_head + local adjust_tail = adjust_head and slide_node_list(adjust_head) -- todo: find_tail + local pre_adjust_tail = pre_adjust_head and slide_node_list(pre_adjust_head) -- todo: find_tail - new_dir_stack(hpack_dir) + new_dir_stack(hpack_dir) - local checked_expansion = false + local checked_expansion = false - if cal_expand_ratio then - checked_expansion = { } - setmetatableindex(checked_expansion,check_expand_lines) - end + if cal_expand_ratio then + checked_expansion = { } + setmetatableindex(checked_expansion,check_expand_lines) + end - -- this one also needs to check the font, so in the end indeed we might end up with two variants + -- this one also needs to check the font, so in the end indeed we might end up with two variants - local fontexps, lastfont + local fontexps, lastfont - local function process(current) -- called nested in disc replace + local function process(current) -- called nested in disc replace - while current do - local char, id = isglyph(current) - if char then - if cal_expand_ratio then - local currentfont = getfont(current) - if currentfont ~= lastfont then - fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer - lastfont = currentfont + while current do + local char, id = isglyph(current) + if char then + if cal_expand_ratio then + local currentfont = getfont(current) + if currentfont ~= lastfont then + fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer + lastfont = currentfont + end + if fontexps then + local expansion = fontexps[char] + if expansion then + font_stretch = font_stretch + expansion.glyphstretch + font_shrink = font_shrink + expansion.glyphshrink + expansion_index = expansion_index + 1 + expansion_stack[expansion_index] = current + end + end + end + -- use inline + local wd, ht, dp = glyph_width_height_depth(hpack_dir,"TLT",current) -- was TRT ? + natural = natural + wd + if ht > height then + height = ht + end + if dp > depth then + depth = dp end - if fontexps then - local expansion = fontexps[char] - if expansion then - font_stretch = font_stretch + expansion.glyphstretch - font_shrink = font_shrink + expansion.glyphshrink + elseif id == kern_code then + local kern = getkern(current) + if kern == 0 then + -- no kern + elseif getsubtype(current) == kerning_code then -- check getkern(p) + if cal_expand_ratio then + local stretch, shrink = kern_stretch_shrink(current,kern) + font_stretch = font_stretch + stretch + font_shrink = font_shrink + shrink expansion_index = expansion_index + 1 expansion_stack[expansion_index] = current end + natural = natural + kern + else + natural = natural + kern end - end - -- use inline - local wd, ht, dp = glyph_width_height_depth(hpack_dir,"TLT",current) -- was TRT ? - natural = natural + wd - if ht > height then - height = ht - end - if dp > depth then - depth = dp - end - elseif id == kern_code then - local kern = getfield(current,"kern") - if kern == 0 then - -- no kern - elseif getsubtype(current) == kerning_code then -- check getfield(p,"kern") - if cal_expand_ratio then - local stretch, shrink = kern_stretch_shrink(current,kern) - font_stretch = font_stretch + stretch - font_shrink = font_shrink + shrink - expansion_index = expansion_index + 1 - expansion_stack[expansion_index] = current + elseif id == disc_code then + local subtype = getsubtype(current) + if subtype ~= second_disc_code then + -- todo : local stretch, shrink = char_stretch_shrink(s) + local replace = getfield(current,"replace") + if replace then + process(replace) + end end - natural = natural + kern - else - natural = natural + kern - end - elseif id == disc_code then - local subtype = getsubtype(current) - if subtype ~= second_disc_code then - -- todo : local stretch, shrink = char_stretch_shrink(s) - local replace = getfield(current,"replace") - if replace then - process(replace) + elseif id == glue_code then + local wd, stretch, shrink, stretch_order, shrink_order = getglue(current) + natural = natural + wd + total_stretch[stretch_order] = total_stretch[stretch_order] + stretch + total_shrink [shrink_order] = total_shrink[shrink_order] + shrink + if getsubtype(current) >= leaders_code then + local leader = getleader(current) + local wd, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003 + if ht > height then + height = ht + end + if dp > depth then + depth = dp + end end - end - elseif id == glue_code then - local wd, stretch, shrink, stretch_order, shrink_order = getglue(current) - natural = natural + wd - total_stretch[stretch_order] = total_stretch[stretch_order] + stretch - total_shrink [shrink_order] = total_shrink[shrink_order] + shrink - if getsubtype(current) >= leaders_code then - local leader = getleader(current) - local ht = getfield(leader,"height") - local dp = getfield(leader,"depth") + elseif id == hlist_code or id == vlist_code then + local sh = getshift(current) + local wd, ht, dp = pack_width_height_depth(hpack_dir,getdir(current) or hpack_dir,current) -- added: or pack_dir + local hs, ds = ht - sh, dp + sh + natural = natural + wd + if hs > height then + height = hs + end + if ds > depth then + depth = ds + end + elseif id == rule_code then + local wd, ht, dp = getwhd(current) + natural = natural + wd if ht > height then height = ht end if dp > depth then depth = dp end + elseif id == math_code then + natural = natural + getkern(current) -- surround + -- new in luatex + + getwidth(current) + elseif id == unset_code then + local wd, ht, dp = getwhd(current) + local sh = getshift(current) + local hs = ht - sh + local ds = dp + sh + natural = natural + wd + if hs > height then + height = hs + end + if ds > depth then + depth = ds + end + elseif id == ins_code or id == mark_code then + local prev, next = getboth(current) + if adjust_tail then -- todo + setlink(prev,next) + setlink(adjust_tail,current) + setnext(current) + adjust_tail = current + else + adjust_head = current + adjust_tail = current + setboth(current) + end + elseif id == adjust_code then + local list = getlist(current) + if adjust_tail then + setnext(adjust_tail,list) + else + adjust_head = list + end + adjust_tail = slide_node_list(list) -- find_tail(list) + elseif id == dir_code then + hpack_dir = checked_line_dir(stack,current) or hpack_dir + elseif id == marginkern_code then + local width = getwidth(current) + if cal_expand_ratio then + -- is this ok? + local glyph = getfield(current,"glyph") + local char_pw = getsubtype(current) == leftmargin_code and left_pw or right_pw + font_stretch = font_stretch - width - char_pw(glyph) + font_shrink = font_shrink - width - char_pw(glyph) + expansion_index = expansion_index + 1 + expansion_stack[expansion_index] = glyph + end + natural = natural + width end - elseif id == hlist_code or id == vlist_code then - local sh = getfield(current,"shift") - local wd, ht, dp = pack_width_height_depth(hpack_dir,getfield(current,"dir") or hpack_dir,current) -- added: or pack_dir - local hs, ds = ht - sh, dp + sh - natural = natural + wd - if hs > height then - height = hs - end - if ds > depth then - depth = ds - end - elseif id == rule_code then - local wd, ht, dp = getwhd(current) - natural = natural + wd - if ht > height then - height = ht - end - if dp > depth then - depth = dp - end - elseif id == math_code then - natural = natural + getfield(current,"surround") - -- new in luatex - + getfield(current,"width") - elseif id == unset_code then - local wd = getfield(current,"width") - local ht = getfield(current,"height") - local dp = getfield(current,"depth") - local sh = getfield(current,"shift") - local hs = ht - sh - local ds = dp + sh - natural = natural + wd - if hs > height then - height = hs - end - if ds > depth then - depth = ds - end - elseif id == ins_code or id == mark_code then - local prev, next = getboth(current) - if adjust_tail then -- todo - setlink(prev,next) - setlink(adjust_tail,current) - setnext(current) - adjust_tail = current - else - adjust_head = current - adjust_tail = current - setboth(current) - end - elseif id == adjust_code then - local list = getlist(current) - if adjust_tail then - setnext(adjust_tail,list) - else - adjust_head = list - end - adjust_tail = slide_node_list(list) -- find_tail(list) - elseif id == dir_code then - hpack_dir = checked_line_dir(stack,current) or hpack_dir - elseif id == marginkern_code then - local width = getfield(current,"width") - if cal_expand_ratio then - -- is this ok? - local glyph = getfield(current,"glyph") - local char_pw = getsubtype(current) == leftmargin_code and left_pw or right_pw - font_stretch = font_stretch - width - char_pw(glyph) - font_shrink = font_shrink - width - char_pw(glyph) - expansion_index = expansion_index + 1 - expansion_stack[expansion_index] = glyph - end - natural = natural + width + current = getnext(current) end - current = getnext(current) - end - end - - process(head) - - if adjust_tail then - adjust_tail.next = nil -- todo - end - if pre_adjust_tail then - pre_adjust_tail.next = nil -- todo - end - if method == "additional" then - width = width + natural - end + end - setwhd(hlist,width,height,depth) + process(head) - local delta = width - natural - if delta == 0 then - setfield(hlist,"glue_sign",0) - setfield(hlist,"glue_order",0) - setfield(hlist,"glue_set",0) - elseif delta > 0 then - -- natural width smaller than requested width - local order = (total_stretch[4] ~= 0 and 4 or total_stretch[3] ~= 0 and 3) or - (total_stretch[2] ~= 0 and 2 or total_stretch[1] ~= 0 and 1) or 0 - if cal_expand_ratio and order == 0 and font_stretch > 0 then -- check sign of font_stretch - font_expand_ratio = delta/font_stretch + if adjust_tail then + adjust_tail.next = nil -- todo + end + if pre_adjust_tail then + pre_adjust_tail.next = nil -- todo + end + if method == "additional" then + width = width + natural + end - if font_expand_ratio > 1 then - font_expand_ratio = 1 - end + setwhd(hlist,width,height,depth) - local fontexps, lastfont - for i=1,expansion_index do - local g = expansion_stack[i] - local e = 0 - local char = isglyph(g) - if char then - local currentfont = getfont(g) - if currentfont ~= lastfont then - fontexps = expansions[currentfont] - lastfont = currentfont - end - local data = fontexps[char] - if trace_expansion then - setnodecolor(g,"hz:positive") - end - e = font_expand_ratio * data.glyphstretch / 1000 - else - local kern = getfield(g,"kern") - local stretch, shrink = kern_stretch_shrink(g,kern) - e = font_expand_ratio * stretch / 1000 - end - setfield(g,"expansion_factor",e) - end - end - local tso = total_stretch[order] - if tso ~= 0 then - setfield(hlist,"glue_sign",1) - setfield(hlist,"glue_order",order) - setfield(hlist,"glue_set",delta/tso) - else + local delta = width - natural + if delta == 0 then setfield(hlist,"glue_sign",0) - setfield(hlist,"glue_order",order) + setfield(hlist,"glue_order",0) setfield(hlist,"glue_set",0) - end - if font_expand_ratio ~= 0 then - -- todo - elseif order == 0 then -- and getlist(hlist) then - last_badness = calculate_badness(delta,total_stretch[0]) - if last_badness > tex.hbadness then - if last_badness > 100 then - diagnostics.underfull_hbox(hlist,line,last_badness) - else - diagnostics.loose_hbox(hlist,line,last_badness) + elseif delta > 0 then + -- natural width smaller than requested width + local order = (total_stretch[4] ~= 0 and 4 or total_stretch[3] ~= 0 and 3) or + (total_stretch[2] ~= 0 and 2 or total_stretch[1] ~= 0 and 1) or 0 + if cal_expand_ratio and order == 0 and font_stretch > 0 then -- check sign of font_stretch + font_expand_ratio = delta/font_stretch + + if font_expand_ratio > 1 then + font_expand_ratio = 1 + end + + local fontexps, lastfont + for i=1,expansion_index do + local g = expansion_stack[i] + local e = 0 + local char = isglyph(g) + if char then + local currentfont = getfont(g) + if currentfont ~= lastfont then + fontexps = expansions[currentfont] + lastfont = currentfont + end + local data = fontexps[char] + if trace_expansion then + setnodecolor(g,"hz:positive") + end + e = font_expand_ratio * data.glyphstretch / 1000 + else + local kern = getkern(g) + local stretch, shrink = kern_stretch_shrink(g,kern) + e = font_expand_ratio * stretch / 1000 + end + setfield(g,"expansion_factor",e) end end - end - else - -- natural width larger than requested width - local order = total_shrink[4] ~= 0 and 4 or total_shrink[3] ~= 0 and 3 - or total_shrink[2] ~= 0 and 2 or total_shrink[1] ~= 0 and 1 or 0 - if cal_expand_ratio and order == 0 and font_shrink > 0 then -- check sign of font_shrink - font_expand_ratio = delta/font_shrink - - if font_expand_ratio < 1 then - font_expand_ratio = -1 + local tso = total_stretch[order] + if tso ~= 0 then + setfield(hlist,"glue_sign",1) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",delta/tso) + else + setfield(hlist,"glue_sign",0) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",0) end - - local fontexps, lastfont - for i=1,expansion_index do - local g = expansion_stack[i] - local e = 0 - local char = isglyph(g) - if char then - local currentfont = getfont(g) - if currentfont ~= lastfont then - fontexps = expansions[currentfont] - lastfont = currentfont - end - local data = fontexps[char] - if trace_expansion then - setnodecolor(g,"hz:negative") + if font_expand_ratio ~= 0 then + -- todo + elseif order == 0 then -- and getlist(hlist) then + last_badness = calculate_badness(delta,total_stretch[0]) + if last_badness > tex.hbadness then + if last_badness > 100 then + diagnostics.underfull_hbox(hlist,line,last_badness) + else + diagnostics.loose_hbox(hlist,line,last_badness) end - e = font_expand_ratio * data.glyphshrink / 1000 - else - local kern = getfield(g,"kern") - local stretch, shrink = kern_stretch_shrink(g,kern) - e = font_expand_ratio * shrink / 1000 end - setfield(g,"expansion_factor",e) end - end - local tso = total_shrink[order] - if tso ~= 0 then - setfield(hlist,"glue_sign",2) - setfield(hlist,"glue_order",order) - setfield(hlist,"glue_set",-delta/tso) else - setfield(hlist,"glue_sign",0) - setfield(hlist,"glue_order",order) - setfield(hlist,"glue_set",0) - end - if font_expand_ratio ~= 0 then - -- todo - elseif tso < -delta and order == 0 then -- and getlist(hlist) then - last_badness = 1000000 - setfield(hlist,"glue_set",1) - local fuzz = - delta - total_shrink[0] - local hfuzz = tex.hfuzz - if fuzz > hfuzz or tex.hbadness < 100 then - local overfullrule = tex.overfullrule - if fuzz > hfuzz and overfullrule > 0 then - -- weird, is always called and no rules shows up - setfield(slide_node_list(list),"next",new_rule(overfullrule,nil,nil,getfield(hlist,"dir"))) -- todo: find_tail + -- natural width larger than requested width + local order = total_shrink[4] ~= 0 and 4 or total_shrink[3] ~= 0 and 3 + or total_shrink[2] ~= 0 and 2 or total_shrink[1] ~= 0 and 1 or 0 + if cal_expand_ratio and order == 0 and font_shrink > 0 then -- check sign of font_shrink + font_expand_ratio = delta/font_shrink + + if font_expand_ratio < 1 then + font_expand_ratio = -1 + end + + local fontexps, lastfont + for i=1,expansion_index do + local g = expansion_stack[i] + local e = 0 + local char = isglyph(g) + if char then + local currentfont = getfont(g) + if currentfont ~= lastfont then + fontexps = expansions[currentfont] + lastfont = currentfont + end + local data = fontexps[char] + if trace_expansion then + setnodecolor(g,"hz:negative") + end + e = font_expand_ratio * data.glyphshrink / 1000 + else + local kern = getkern(g) + local stretch, shrink = kern_stretch_shrink(g,kern) + e = font_expand_ratio * shrink / 1000 + end + setfield(g,"expansion_factor",e) end - diagnostics.overfull_hbox(hlist,line,-delta) end - elseif order == 0 and getlist(hlist) and last_badness > tex.hbadness then - diagnostics.bad_hbox(hlist,line,last_badness) + local tso = total_shrink[order] + if tso ~= 0 then + setfield(hlist,"glue_sign",2) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",-delta/tso) + else + setfield(hlist,"glue_sign",0) + setfield(hlist,"glue_order",order) + setfield(hlist,"glue_set",0) + end + if font_expand_ratio ~= 0 then + -- todo + elseif tso < -delta and order == 0 then -- and getlist(hlist) then + last_badness = 1000000 + setfield(hlist,"glue_set",1) + local fuzz = - delta - total_shrink[0] + local hfuzz = tex.hfuzz + if fuzz > hfuzz or tex.hbadness < 100 then + local overfullrule = tex.overfullrule + if fuzz > hfuzz and overfullrule > 0 then + -- weird, is always called and no rules shows up + setnext(slide_node_list(list),new_rule(overfullrule,nil,nil,getdir(hlist))) -- todo: find_tail + end + diagnostics.overfull_hbox(hlist,line,-delta) + end + elseif order == 0 and getlist(hlist) and last_badness > tex.hbadness then + diagnostics.bad_hbox(hlist,line,last_badness) + end end + return hlist, last_badness end - return hlist, last_badness -end -xpack_nodes = hpack -- comment this for old fashioned expansion (we need to fix float mess) + xpack_nodes = hpack -- comment this for old fashioned expansion (we need to fix float mess) -constructors.methods.hpack = hpack - -local function common_message(hlist,line,str) - write_nl("") - if status.output_active then -- unset - write(str," has occurred while \\output is active") - else - write(str) - end - local fileline = status.linenumber - if line > 0 then - write(formatters[" in paragraph at lines %s--%s"](fileline,"--",fileline+line-1)) - elseif line < 0 then - write(formatters[" in alignment at lines "](fileline,"--",fileline-line-1)) - else - write(formatters[" detected at line %s"](fileline)) - end - write_nl("") - diagnostics.short_display(getlist(hlist),false) - write_nl("") - -- diagnostics.start() - -- show_box(getlist(hlist)) - -- diagnostics.stop() -end - -function diagnostics.overfull_hbox(hlist,line,d) - common_message(hlist,line,formatters["Overfull \\hbox (%spt too wide)"](number.toscaled(d))) -end - -function diagnostics.bad_hbox(hlist,line,b) - common_message(hlist,line,formatters["Tight \\hbox (badness %i)"](b)) -end - -function diagnostics.underfull_hbox(hlist,line,b) - common_message(hlist,line,formatters["Underfull \\hbox (badness %i)"](b)) -end + constructors.methods.hpack = hpack -function diagnostics.loose_hbox(hlist,line,b) - common_message(hlist,line,formatters["Loose \\hbox (badness %i)"](b)) end |