summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua1840
1 files changed, 952 insertions, 888 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
index 0d501890b92..dd655f93d41 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ltp.lua
@@ -8,23 +8,16 @@ if not modules then modules = { } end modules ['node-par'] = {
}
-- todo: remove nest_stack from linebreak.w
--- todo: use ex field as signal (index in ?)
--- todo: attr driven unknown/on/off
-- todo: permit global steps i.e. using an attribute that sets min/max/step and overloads the font parameters
-- todo: split the three passes into three functions
--- todo: simplify the direction stack, no copy needed
-- todo: see if we can do without delta nodes (needs thinking)
-- todo: add more mkiv like tracing
-- todo: add a couple of plugin hooks
--- todo: maybe split expansion code paths
-- todo: fix line numbers (cur_list.pg_field needed)
--- 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.*)
+-- issue: ls / rs added when zero content and normalize
+
--[[
This code is derived from traditional TeX and has bits of pdfTeX, Aleph (Omega), and of course LuaTeX. So,
@@ -126,66 +119,23 @@ if not modules then modules = { } end modules ['node-par'] = {
retrofit the same approach into the core, the overhead of expansion can be sort of nilled.
In 2013 the expansion factor method became also used at the TeX end so then I could complete the code
- here, and indeed, expansions works quite well now (not compatible of course because we use floats at the
- Lua end. The Lua base variant is still slower but quite ok, especially if we go nuts.
-
- A next iteration will provide plug-ins and more control. I will also explore the possibility to avoid the
- redundant hpack calculations (easier now, although I've only done some quick and dirty experiments.)
-
-]]--
-
---[[--
-
-#define dir_TLT 0
-#define dir_TRT 1
-#define dir_LTL 2
-#define dir_RTT 3
-
-#define dir_TLT_or_TRT(A) (A < 2)
-#define dir_LTL_or_RTT(A) (A > 1)
-
-#define textdir_parallel(A,B) (\
-(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \
-(dir_LTL_or_RTT(A) and dir_LTL_or_RTT(B))\
-)
-
-#define pardir_parallel(A,B) (\
-(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \
-(dir_LTL_or_RTT(A) and dir_LTL_or_RTT(B))\
-)
+ here, and indeed, expansions works quite well now (not compatible of course because we use floats at
+ the Lua end. The Lua base variant is still slower but quite ok, especially if we go nuts.
-#define pardir_opposite(A,B) (\
-(A == dir_LTL and B == dir_RTT) or \
-(A == dir_RTT and B == dir_LTL)\
-)
+ A next iteration will provide plug-ins and more control. I will also explore the possibility to avoid
+ the redundant hpack calculations (easier now, although I've only done some quick and dirty experiments.)
-#define textdir_opposite(A,B) (\
-(A == dir_TLT and B == dir_TRT) or \
-(A == dir_TRT and B == dir_TLT)\
-)
+ The code has been adapted to the more reasonable and simplified direction model.
-#define glyphdir_opposite(A,B) 0
+ In case I forget when I added the normalization code: it was november 2019 and it took me way more time
+ than usual because I got distracted after discovering Alyona Yarushina on YT (in november 2019) which
+ blew some fuses in the musical aware part of my brain in a similar way as when I discovered Kate Bush,
+ so I had to watch a whole lot of her perfect covers (multiple times and for sure many more times). A
+ new benchmark.
-#define pardir_equal(A,B) (\
-(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \
-(A == dir_LTL and B == dir_LTL) or \
-(A == dir_RTT and B == dir_RTT)\
-)
-
-#define textdir_equal(A,B) (\
-(A == dir_TLT and B == dir_TLT) or \
-(A == dir_TRT and B == dir_TRT) or \
-(A == dir_LTL and dir_LTL_or_RTT(B)) or \
-(A == dir_RTT and dir_LTL_or_RTT(B))\
-)
-
---]]--
+]]--
-local tonumber = tonumber
-local utfchar = utf.char
-local write, write_nl = texio.write, texio.write_nl
-local sub, formatters = string.sub, string.formatters
-local insert, remove = table.insert, table.remove
+local unpack = unpack
-- local fonts, nodes, node = fonts, nodes, node -- too many locals
@@ -199,8 +149,10 @@ local report_parbuilders = logs.reporter("nodes","parbuilders")
----- report_hpackers = logs.reporter("nodes","hpackers")
local calculate_badness = tex.badness
-local texnest = tex.nest
local texlists = tex.lists
+local texget = tex.get
+local texset = tex.set
+local texgetglue = tex.getglue
-- (t == 0 and 0) or (s <= 0 and 10000) or calculate_badness(t,s)
@@ -226,228 +178,275 @@ local texlists = tex.lists
-- end
-- end
-local parbuilders = builders.paragraphs
-local constructors = parbuilders.constructors
-
-local setmetatableindex = table.setmetatableindex
-
-local fonthashes = fonts.hashes
-local chardata = fonthashes.characters
-local quaddata = fonthashes.quads
-local parameters = fonthashes.parameters
-
-local nuts = nodes.nuts
-local tonut = nuts.tonut
-
-local getfield = nuts.getfield
-local getid = nuts.getid
-local getsubtype = nuts.getsubtype
-local getnext = nuts.getnext
-local getprev = nuts.getprev
-local getboth = nuts.getboth
-local getlist = nuts.getlist
-local getdisc = nuts.getdisc
-local getattr = nuts.getattr
-local getdisc = nuts.getdisc
-local getglue = nuts.getglue
-local getwhd = nuts.getwhd
-local getkern = nuts.getkern
-local getpenalty = nuts.getpenalty
-local getdirection = nuts.getdirection
-local getshift = nuts.getshift
-local getwidth = nuts.getwidth
-local getheight = nuts.getheight
-local getdepth = nuts.getdepth
-local getdata = nuts.getdata
-local getwhd = nuts.getwhd
-
-local isglyph = nuts.isglyph
-
-local setfield = nuts.setfield
-local setlink = nuts.setlink
-local setlist = nuts.setlist
-local setboth = nuts.setboth
-local setnext = nuts.setnext
-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 setdirection = nuts.setdirection
-local setshift = nuts.setshift
-local setwidth = nuts.setwidth
-local setexpansion = nuts.setexpansion
-
-local slide_node_list = nuts.slide -- get rid of this, probably ok > 78.2
-local find_tail = nuts.tail
-local copy_node = nuts.copy
-local flush_node = nuts.flush
-local flush_node_list = nuts.flush_list
------ hpack_nodes = nuts.hpack
-local xpack_nodes = nuts.hpack
-local replace_node = nuts.replace
-local insert_node_after = nuts.insert_after
-local insert_node_before = nuts.insert_before
-local is_zero_glue = nuts.is_zero_glue
-local is_skipable = nuts.protrusion_skippable
-
-local nodepool = nuts.pool
-
-local nodecodes = nodes.nodecodes
-local kerncodes = nodes.kerncodes
-local glyphcodes = nodes.glyphcodes
-local leadercodes = nodes.leadercodes
-local margincodes = nodes.margincodes
-local disccodes = nodes.disccodes
-local mathcodes = nodes.mathcodes
-local fillcodes = nodes.fillcodes
-local boundarycodes = nodes.boundarycodes
-
-local temp_code = nodecodes.temp
-local glyph_code = nodecodes.glyph
-local ins_code = nodecodes.ins
-local mark_code = nodecodes.mark
-local adjust_code = nodecodes.adjust
-local penalty_code = nodecodes.penalty
-local disc_code = nodecodes.disc
-local math_code = nodecodes.math
-local kern_code = nodecodes.kern
-local glue_code = nodecodes.glue
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local unset_code = nodecodes.unset
-local marginkern_code = nodecodes.marginkern
-local dir_code = nodecodes.dir
-local boundary_code = nodecodes.boundary
-
-local protrusionboundary_code = boundarycodes.protrusion
-
-local leaders_code = leadercodes.leaders
-
-local localpar_code = nodecodes.localpar
-
-local userkern_code = kerncodes.userkern
-local italickern_code = kerncodes.italiccorrection
-local fontkern_code = kerncodes.fontkern
-local accentkern_code = kerncodes.accentkern
-
-local ligatureglyph_code = glyphcodes.ligature
-
-local fillcodes = nodes.fillcodes
-
-local leftmargin_code = margincodes.left
------ rightmargin_code = margincodes.right
-
-local automaticdisc_code = disccodes.automatic
-local regulardisc_code = disccodes.regular
-local firstdisc_code = disccodes.first
-local seconddisc_code = disccodes.second
-
-local endmath_code = mathcodes.endmath
-
-local nosubtype_code = 0
-
-local unhyphenated_code = nodecodes.unhyphenated or 1
-local hyphenated_code = nodecodes.hyphenated or 2
-local delta_code = nodecodes.delta or 3
-local passive_code = nodecodes.passive or 4
-
-local maxdimen = number.maxdimen
-
-local max_halfword = 0x7FFFFFFF
-local infinite_penalty = 10000
-local eject_penalty = -10000
-local infinite_badness = 10000
-local awful_badness = 0x3FFFFFFF
-local ignore_depth = -65536000
-
-local fit_very_loose_class = 0 -- fitness for lines stretching more than their stretchability
-local fit_loose_class = 1 -- fitness for lines stretching 0.5 to 1.0 of their stretchability
-local fit_decent_class = 2 -- fitness for all other lines
-local fit_tight_class = 3 -- fitness for lines shrinking 0.5 to 1.0 of their shrinkability
-
-local new_penalty = nodepool.penalty
-local new_direction = nodepool.direction
-local new_leftmarginkern = nodepool.leftmarginkern
-local new_rightmarginkern = nodepool.rightmarginkern
-local new_leftskip = nodepool.leftskip
-local new_rightskip = nodepool.rightskip
-local new_lineskip = nodepool.lineskip
-local new_baselineskip = nodepool.baselineskip
-local new_temp = nodepool.temp
-local new_rule = nodepool.rule
-local new_hlist = nodepool.hlist
+local parbuilders = builders.paragraphs
+local constructors = parbuilders.constructors
+
+local setmetatableindex = table.setmetatableindex
+
+local fonthashes = fonts.hashes
+local chardata = fonthashes.characters
+local quaddata = fonthashes.quads
+local parameters = fonthashes.parameters
+
+local nuts = nodes.nuts
+local tonut = nuts.tonut
+
+local getfield = nuts.getfield
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getboth = nuts.getboth
+local getlist = nuts.getlist
+local getdisc = nuts.getdisc
+local getattr = nuts.getattr
+local getdisc = nuts.getdisc
+local getglue = nuts.getglue
+local getwhd = nuts.getwhd
+local getkern = nuts.getkern
+local getpenalty = nuts.getpenalty
+local getdirection = nuts.getdirection
+local getshift = nuts.getshift
+local getwidth = nuts.getwidth
+local getheight = nuts.getheight
+local getdepth = nuts.getdepth
+local getdata = nuts.getdata
+local getreplace = nuts.getreplace
+local setreplace = nuts.setreplace
+local getpost = nuts.getpost
+local setpost = nuts.setpost
+local getpre = nuts.getpre
+local setpre = nuts.setpre
+
+local isglyph = nuts.isglyph
+local start_of_par = nuts.start_of_par
+
+local setfield = nuts.setfield
+local setlink = nuts.setlink
+local setlist = nuts.setlist
+local setboth = nuts.setboth
+local setnext = nuts.setnext
+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 setdirection = nuts.setdirection
+local setshift = nuts.setshift
+local setwidth = nuts.setwidth
+local setexpansion = nuts.setexpansion
+
+local find_tail = nuts.tail
+local copy_node = nuts.copy
+local flush_node = nuts.flush
+local flush_node_list = nuts.flush_list
+----- hpack_nodes = nuts.hpack
+local xpack_nodes = nuts.hpack
+local replace_node = nuts.replace
+local remove_node = nuts.remove
+local insert_node_after = nuts.insert_after
+local insert_node_before = nuts.insert_before
+local is_zero_glue = nuts.is_zero_glue
+local is_skipable = nuts.protrusion_skippable
+local setattributelist = nuts.setattributelist
+local find_node = nuts.find_node
+
+local nextnode = nuts.traversers.node
+local nextglue = nuts.traversers.glue
+
+local nodepool = nuts.pool
+
+local nodecodes = nodes.nodecodes
+local kerncodes = nodes.kerncodes
+local margincodes = nodes.margincodes
+local disccodes = nodes.disccodes
+local mathcodes = nodes.mathcodes
+local fillcodes = nodes.fillcodes
+local gluecodes = nodes.gluecodes
+
+local temp_code = nodecodes.temp
+local glyph_code = nodecodes.glyph
+local ins_code = nodecodes.ins
+local mark_code = nodecodes.mark
+local adjust_code = nodecodes.adjust
+local penalty_code = nodecodes.penalty
+local disc_code = nodecodes.disc
+local math_code = nodecodes.math
+local kern_code = nodecodes.kern
+local glue_code = nodecodes.glue
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+local unset_code = nodecodes.unset
+local marginkern_code = nodecodes.marginkern
+local dir_code = nodecodes.dir
+local boundary_code = nodecodes.boundary
+local localpar_code = nodecodes.localpar
+
+local protrusionboundary_code = nodes.boundarycodes.protrusion
+local leaders_code = nodes.leadercodes.leaders
+local indentlist_code = nodes.listcodes.indent
+local ligatureglyph_code = nodes.glyphcodes.ligature
+local cancel_code = nodes.dircodes.cancel
+
+local userkern_code = kerncodes.userkern
+local italickern_code = kerncodes.italiccorrection
+local fontkern_code = kerncodes.fontkern
+local accentkern_code = kerncodes.accentkern
+
+local leftmargin_code = margincodes.left
+----- rightmargin_code = margincodes.right
+
+local automaticdisc_code = disccodes.automatic
+local regulardisc_code = disccodes.regular
+local firstdisc_code = disccodes.first
+local seconddisc_code = disccodes.second
+
+local spaceskip_code = gluecodes.spaceskip
+local xspaceskip_code = gluecodes.xspaceskip
+local rightskip_code = gluecodes.rightskip
+
+local endmath_code = mathcodes.endmath
+
+local righttoleft_code = nodes.dirvalues.righttoleft
+
+local nosubtype_code = 0
+
+local unhyphenated_code = nodecodes.unhyphenated or 1
+local hyphenated_code = nodecodes.hyphenated or 2
+local delta_code = nodecodes.delta or 3
+local passive_code = nodecodes.passive or 4
+
+local maxdimen = number.maxdimen
+
+local max_halfword = 0x7FFFFFFF
+local infinite_penalty = 10000
+local eject_penalty = -10000
+local infinite_badness = 10000
+local awful_badness = 0x3FFFFFFF
+local ignore_depth = -65536000
+
+local fit_very_loose_class = 0 -- fitness for lines stretching more than their stretchability
+local fit_loose_class = 1 -- fitness for lines stretching 0.5 to 1.0 of their stretchability
+local fit_decent_class = 2 -- fitness for all other lines
+local fit_tight_class = 3 -- fitness for lines shrinking 0.5 to 1.0 of their shrinkability
+
+local new_penalty = nodepool.penalty
+local new_direction = nodepool.direction
+local new_leftmarginkern = nodepool.leftmarginkern
+local new_rightmarginkern = nodepool.rightmarginkern
+local new_leftskip = nodepool.leftskip
+local new_rightskip = nodepool.rightskip
+local new_lefthangskip = nodepool.lefthangskip
+local new_righthangskip = nodepool.righthangskip
+local new_indentskip = nodepool.indentskip
+local new_correctionskip = nodepool.correctionskip
+local new_lineskip = nodepool.lineskip
+local new_baselineskip = nodepool.baselineskip
+local new_temp = nodepool.temp
+local new_rule = nodepool.rule
+local new_hlist = nodepool.hlist
+
+local getnormalizeline = nuts.getnormalizeline
-- helpers --
-- It makes more sense to move the somewhat messy dir state tracking
-- out of the main functions. First we create a stack allocator.
-local function new_dir_stack(dir) -- also use elsewhere
- return { n = 0, dir }
-end
-
-- The next function checks a dir node and returns the new dir state. By
-- using a static table we are quite efficient. This function is used
-- in the parbuilder.
-local function checked_line_dir(stack,current)
+local function checked_line_dir(stack,current) -- can be inlined now
local direction, pop = getdirection(current)
+ local n = stack.n
if not pop then
- local n = stack.n + 1
+ n = n + 1
stack.n = n
- stack[n] = current
+ stack[n] = direction
return direction
elseif n > 0 then
- local n = stack.n
- local dirnode = stack[n]
- dirstack.n = n - 1
- direction = getdirection(dirnode) -- we could save it
- return direction
+ n = n - 1
+ stack.n = n
+ return stack[n]
else
report_parbuilders("warning: missing pop node (%a)",1) -- in line ...
end
end
--- The next function checks dir nodes in a list and appends the negations
--- that are currently needed (some day LuaTeX will be more tolerant). We use
--- the negations for the next line.
+-- The next function checks dir nodes in a list and injects dir nodes
+-- that are currently needed.
+
+local function inject_dirs_at_begin_of_line(stack,current)
+ local n = stack.n
+ if n > 0 then
+ local h = current
+ for i=1,n do
+ local d = new_direction(stack[i])
+ setattributelist(d,current)
+ h, current = insert_node_after(h,current,d)
+ end
+ stack.n = 0
+ return h
+ else
+ return current
+ end
+end
local function inject_dirs_at_end_of_line(stack,current,start,stop)
- local e = start
local n = stack.n
- local h = nil
- -- todo: traverse
while start and start ~= stop do
local id = getid(start)
if id == dir_code then
local direction, pop = getdirection(start)
if not pop then
n = n + 1
- stack[n] = start
+ stack[n] = direction
elseif n > 0 then
+if direction == stack[n] then
+ -- like in the engine
n = n - 1
+end
else
report_parbuilders("warning: missing pop node (%a)",2) -- in line ...
end
end
start = getnext(start)
end
- for i=n,1,-1 do
- h, current = insert_node_after(current,current,new_direction(getdirection(stack[i]),true))
+ if n > 0 then
+ -- from 1,n and before
+ local h = start
+ for i=n,1,-1 do
+ local d = new_direction(stack[i],true)
+ setattributelist(d,start)
+ h, current = insert_node_after(h,current,d)
+ end
end
stack.n = n
return current
end
-local function inject_dirs_at_begin_of_line(stack,current)
- local h = nil
- for i=stack.n,1,-1 do
- h, current = insert_node_after(current,current,new_direction(stack[i]))
+local ignore_math_skip = node.direct.ignore_math_skip or function(current)
+ local mode = texget("mathskipmode")
+ if mode == 6 or mode == 7 then
+ local b = true
+ local n = getsubtype(current) == endmath_code and getnext(current) or getprev(current)
+ if n and getid(n) == glue_code then
+ local s = getsubtype(n)
+ if s == spaceskip_code or s == xspaceskip_code then
+ b = false
+ end
+ end
+ if mode == 7 then
+ b = not b
+ end
+ if b then
+ setglue(current)
+ return true
+ end
end
- stack.n = 0
- return current
+ return false
end
-- diagnostics --
@@ -487,59 +486,117 @@ local function calculate_fraction(x,n,d,max_answer)
end
end
-local function check_shrinkage(par,n)
- -- called often, so maybe move inline -- use NORMAL
- if getfield(n,"shrink_order") ~= 0 and getfield(n,"shrink") ~= 0 then
- if par.no_shrink_error_yet then
- par.no_shrink_error_yet = false
- report_parbuilders("infinite glue shrinkage found in a paragraph and removed")
- end
- n = copy_node(n)
- setfield(n,"shrink_order",0)
+local function infinite_shrinkage_error(par)
+ if par.no_shrink_error_yet then
+ par.no_shrink_error_yet = false
+ report_parbuilders("infinite glue shrinkage found in a paragraph and removed")
end
- return n
end
-- It doesn't really speed up much but the additional memory usage is
-- rather small so it doesn't hurt too much.
local expansions = { }
-local nothing = { stretch = 0, shrink = 0 }
+local nothing = { stretch = 0, shrink = 0 } -- or just true or so
+
+-- setmetatableindex(expansions,function(t,font) -- we can store this in tfmdata if needed
+-- local expansion = parameters[font].expansion -- can be an extra hash
+-- if expansion and expansion.step ~= 0 then
+-- local stretch = expansion.stretch
+-- local shrink = expansion.shrink
+-- if shrink ~= 0 or stretch ~= 0 then
+-- local factors = { }
+-- local c = chardata[font]
+-- setmetatableindex(factors,function(t,char)
+-- local fc = c[char]
+-- local ef = fc.expansion_factor
+-- if ef and ef > 0 then
+-- if stretch ~= 0 or shrink ~= 0 then
+-- -- todo in lmtx: get rid of quad related scaling
+-- local factor = ef / 1000
+-- local ef_quad = factor * quaddata[font] / 1000
+-- local v = {
+-- glyphstretch = stretch * ef_quad,
+-- glyphshrink = shrink * ef_quad,
+-- factor = factor, -- do we need these, if not then we
+-- stretch = stretch, -- can as well use the chardata table
+-- shrink = shrink, -- to store the two above
+-- }
+-- t[char] = v
+-- return v
+-- end
+-- end
+-- t[char] = nothing
+-- return nothing
+-- end)
+-- t[font] = factors
+-- return factors
+-- end
+-- end
+-- t[font] = false
+-- return false
+-- end)
+
+-- local function kern_stretch_shrink(p,d)
+-- local left = getprev(p)
+-- if left then
+-- local char, font = isglyph(left)
+-- if char then
+-- local data = expansions[font]
+-- if data then
+-- data = data[char]
+-- if data then
+-- local stretch = data.stretch
+-- local shrink = data.shrink
+-- if stretch ~= 0 then
+-- stretch = data.factor * d * (stretch - 1)
+-- end
+-- if shrink ~= 0 then
+-- shrink = data.factor * d * (shrink - 1)
+-- end
+-- return stretch, shrink
+-- end
+-- end
+-- end
+-- end
+-- return 0, 0
+-- end
setmetatableindex(expansions,function(t,font) -- we can store this in tfmdata if needed
local expansion = parameters[font].expansion -- can be an extra hash
- if expansion and expansion.auto then
- local factors = { }
- local c = chardata[font]
- setmetatableindex(factors,function(t,char)
- local fc = c[char]
- local ef = fc.expansion_factor
- if ef and ef > 0 then
- local stretch = expansion.stretch
- local shrink = expansion.shrink
- if stretch ~= 0 or shrink ~= 0 then
+ if expansion and expansion.step ~= 0 then
+ local stretch = expansion.stretch
+ local shrink = expansion.shrink
+ if shrink ~= 0 or stretch ~= 0 then
+ local factors = {
+ stretch = stretch,
+ shrink = shrink,
+ }
+ local c = chardata[font]
+ setmetatableindex(factors,function(t,char)
+ local fc = c[char]
+ local ef = fc.expansion_factor
+ if ef and ef > 0 and stretch ~= 0 or shrink ~= 0 then
+ -- todo in lmtx: get rid of quad related scaling
local factor = ef / 1000
local ef_quad = factor * quaddata[font] / 1000
local v = {
glyphstretch = stretch * ef_quad,
glyphshrink = shrink * ef_quad,
factor = factor,
- stretch = stretch,
- shrink = shrink,
}
t[char] = v
return v
end
- end
- t[char] = nothing
- return nothing
- end)
- t[font] = factors
- return factors
- else
- t[font] = false
- return false
+ t[char] = nothing
+ return nothing
+ end)
+ t[font] = factors
+ return factors
+ end
end
+ t[font] = false
+ return false
end)
local function kern_stretch_shrink(p,d)
@@ -547,19 +604,21 @@ local function kern_stretch_shrink(p,d)
if left then
local char, font = isglyph(left)
if char then
- local data = expansions[font][char]
- if data then
- local stretch = data.stretch
- local shrink = data.shrink
- if stretch ~= 0 then
- -- stretch = data.factor * (d * stretch - d)
- stretch = data.factor * d * (stretch - 1)
- end
- if shrink ~= 0 then
- -- shrink = data.factor * (d * shrink - d)
- shrink = data.factor * d * (shrink - 1)
+ local fdata = expansions[font]
+ if fdata then
+ local cdata = fdata[char]
+ if cdata then
+ local stretch = fdata.stretch
+ local shrink = fdata.shrink
+ local factor = cdata.factor * d
+ if stretch ~= 0 then
+ stretch = factor * (stretch - 1)
+ end
+ if shrink ~= 0 then
+ shrink = factor * (shrink - 1)
+ end
+ return stretch, shrink
end
- return stretch, shrink
end
end
end
@@ -583,6 +642,9 @@ end)
-- state:
+-- the step criterium is no longer an issue, we can be way more tolerant in
+-- luatex as we act per glyph
+
local function check_expand_pars(checked_expansion,f)
local expansion = parameters[f].expansion
if not expansion then
@@ -670,7 +732,7 @@ local function find(head) -- do we really want to recurse into an hlist?
elseif id == boundary_code then
if getsubtype(head) == protrusionboundary_code then
local v = getdata(head)
- if v == 1 or v == 3 then
+ if v == 1 or v == 3 then -- brrr
head = getnext(head)
if head then
head = getnext(head)
@@ -754,7 +816,7 @@ local function left_pw(p)
if not prot or prot == 0 then
return 0
end
- return prot * quaddata[font] / 1000, p
+ return prot, p
end
local function right_pw(p)
@@ -763,7 +825,7 @@ local function right_pw(p)
if not prot or prot == 0 then
return 0
end
- return prot * quaddata[font] / 1000, p
+ return prot, p
end
-- par parameters
@@ -785,12 +847,7 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw
while s do
local char, id = isglyph(s)
if char then
- local wd, ht, dp = getwhd(s)
- if is_rotated(line_break_dir) then
- size = size + ht + dp
- else
- size = size + wd
- end
+ size = size + getwidth(s)
if checked_expansion then
local data = checked_expansion[id] -- id == font
if data then
@@ -802,12 +859,7 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw
end
end
elseif id == hlist_code or id == vlist_code then
- local wd, ht, dp = getwhd(s)
- if textdir_parallel(getdirection(s),line_break_dir) then
- size = size + wd
- else
- size = size + ht + dp
- end
+ size = size + getwidth(s)
elseif id == kern_code then
local kern = getkern(s)
if kern ~= 0 then
@@ -910,20 +962,21 @@ do
local function append_to_vlist(par, b)
local prev_depth = par.prev_depth
local head_field = par.head_field
- local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail
+ local tail_field = head_field and find_tail(head_field)
local is_hlist = getid(b) == hlist_code
- -- if prev_depth > par.ignored_dimen then
if prev_depth > ignore_depth then
if is_hlist then
- local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip)
+ -- we can fetch the skips values earlier if needed
+ local width, stretch, shrink, stretch_order, shrink_order = unpack(par.baseline_skip)
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)
+ width, stretch, shrink, stretch_order, shrink_order = unpack(par.lineskip)
skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order)
else
skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order)
end
+ setattributelist(skip,par.head)
if head_field then
setlink(tail_field,skip)
else
@@ -941,14 +994,14 @@ do
if is_hlist then
local pd = getdepth(b)
par.prev_depth = pd
- texnest[texnest.ptr].prevdepth = pd
+ texset("prevdepth",pd)
end
end
local function append_list(par, b)
local head_field = par.head_field
if head_field then
- local n = slide_node_list(head_field) -- todo: find_tail
+ local n = find_tail(head_field)
setlink(n,b)
else
par.head_field = b
@@ -961,18 +1014,18 @@ do
local function initialize_line_break(head,display)
- local hang_indent = tex.hangindent or 0
- local hsize = tex.hsize or 0
- local hang_after = tex.hangafter or 0
- local par_shape_ptr = tex.parshape
- local left_skip = tonut(tex.leftskip) -- nodes
- local right_skip = tonut(tex.rightskip) -- nodes
- local pretolerance = tex.pretolerance
- local tolerance = tex.tolerance
- local adjust_spacing = tex.adjustspacing
- local protrude_chars = tex.protrudechars
- local last_line_fit = tex.lastlinefit
- local par_dir = tex.pardirection
+ local hang_indent = texget("hangindent")
+ local hsize = texget("hsize")
+ local hang_after = texget("hangafter")
+ local par_shape_ptr = texget("parshape")
+ local left_skip = { texgetglue("leftskip") }
+ local right_skip = { texgetglue("rightskip") }
+ local pretolerance = texget("pretolerance")
+ local tolerance = texget("tolerance")
+ local adjust_spacing = texget("adjustspacing")
+ local protrude_chars = texget("protrudechars")
+ local last_line_fit = texget("lastlinefit")
+ local par_dir = texget("pardirection")
local newhead = new_temp()
setnext(newhead,head)
@@ -996,11 +1049,11 @@ do
pass_number = 0, -- the number of passive nodes allocated on this pass
auto_breaking = 0, -- make auto_breaking accessible out of line_break
- active_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
- break_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
- disc_width = { size = 0, adjust_stretch = 0, adjust_shrink = 0 },
- fill_width = { stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
- background = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
+ active_width = { size = 0, normal = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
+ break_width = { size = 0, normal = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 },
+ disc_width = { size = 0, adjust_stretch = 0, adjust_shrink = 0 },
+ fill_width = { normal = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
+ background = { size = 0, normal = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 },
hang_indent = hang_indent,
hsize = hsize,
@@ -1017,39 +1070,29 @@ do
max_shrink_ratio = adjust_spacing_status,
cur_font_step = adjust_spacing_status,
checked_expansion = false,
- tracing_paragraphs = tex.tracingparagraphs > 0,
-
- emergency_stretch = tex.emergencystretch or 0,
- looseness = tex.looseness or 0,
- line_penalty = tex.linepenalty or 0,
- hyphen_penalty = tex.hyphenpenalty or 0,
- broken_penalty = tex.brokenpenalty or 0,
- inter_line_penalty = tex.interlinepenalty or 0,
- club_penalty = tex.clubpenalty or 0,
- widow_penalty = tex.widowpenalty or 0,
- display_widow_penalty = tex.displaywidowpenalty or 0,
- ex_hyphen_penalty = tex.exhyphenpenalty or 0,
+ tracing_paragraphs = texget("tracingparagraphs") > 0,
- adj_demerits = tex.adjdemerits or 0,
- double_hyphen_demerits = tex.doublehyphendemerits or 0,
- final_hyphen_demerits = tex.finalhyphendemerits or 0,
+ emergency_stretch = texget("emergencystretch") or 0,
+ looseness = texget("looseness") or 0,
+ line_penalty = texget("linepenalty") or 0,
+ broken_penalty = texget("brokenpenalty") or 0,
+ inter_line_penalty = texget("interlinepenalty") or 0,
+ club_penalty = texget("clubpenalty") or 0,
+ widow_penalty = texget("widowpenalty") or 0,
+ display_widow_penalty = texget("displaywidowpenalty") or 0,
- first_line = 0, -- texnest[texnest.ptr].modeline, -- 0, -- cur_list.pg_field
+ adj_demerits = texget("adjdemerits") or 0,
+ double_hyphen_demerits = texget("doublehyphendemerits") or 0,
+ final_hyphen_demerits = texget("finalhyphendemerits") or 0,
- -- each_line_height = tex.pdfeachlineheight or 0, -- this will go away
- -- each_line_depth = tex.pdfeachlinedepth or 0, -- this will go away
- -- first_line_height = tex.pdffirstlineheight or 0, -- this will go away
- -- last_line_depth = tex.pdflastlinedepth or 0, -- this will go away
+ first_line = texget("prevgraf"),
+ prev_depth = texget("prevdepth"),
- -- ignored_dimen = tex.pdfignoreddimen or 0,
+ baseline_skip = { texgetglue("baselineskip") },
+ lineskip = { texgetglue("lineskip") },
+ line_skip_limit = texget("lineskiplimit"),
- baseline_skip = tonut(tex.baselineskip),
- lineskip = tonut(tex.lineskip),
- line_skip_limit = tex.lineskiplimit,
-
- prev_depth = texnest[texnest.ptr].prevdepth,
-
- final_par_glue = slide_node_list(head), -- todo: we know tail already, slow
+ final_par_glue = find_tail(head),
par_break_dir = par_dir,
line_break_dir = par_dir,
@@ -1118,11 +1161,6 @@ do
}
- -- optimizers
-
- par.used_left_skip = used_skip(par.left_skip)
- par.used_right_skip = used_skip(par.right_skip)
-
-- so far
if adjust_spacing > 1 then
@@ -1138,7 +1176,7 @@ do
par.tolerance = hztolerance
end
- expand_kerns = expand_kerns_mode or (adjust_spacing == 2)
+ expand_kerns = expand_kerns_mode or (adjust_spacing == 2) -- why not > 1 ?
end
@@ -1146,11 +1184,17 @@ do
local background = par.background
- local l = check_shrinkage(par,left_skip)
- local r = check_shrinkage(par,right_skip)
+ local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = unpack(left_skip)
+ local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = unpack(right_skip)
- local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = getglue(l)
- local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = getglue(r)
+ if lshrink_order ~= 0 and lshrink ~= 0 then
+ infinite_shrinkage_error(par)
+ lshrink_order = 0
+ end
+ if rshrink_order ~= 0 and rshrink ~= 0 then
+ infinite_shrinkage_error(par)
+ rshrink_order = 0
+ end
local l_order = fillcodes[lstretch_order]
local r_order = fillcodes[rstretch_order]
@@ -1167,8 +1211,8 @@ do
par.second_width = hsize
par.second_indent = 0
else
- local abs_hang_after = hang_after >0 and hang_after or -hang_after
- local abs_hang_indent = hang_indent>0 and hang_indent or -hang_indent
+ local abs_hang_after = hang_after > 0 and hang_after or -hang_after
+ local abs_hang_indent = hang_indent > 0 and hang_indent or -hang_indent
par.last_special_line = abs_hang_after
if hang_after < 0 then
par.first_width = hsize - abs_hang_indent
@@ -1243,21 +1287,19 @@ do
local function post_line_break(par)
- local prevgraf = texnest[texnest.ptr].prevgraf
+ local prevgraf = par.first_line -- or texget("prevgraf")
local current_line = prevgraf + 1 -- the current line number being justified
-
local adjust_spacing = par.adjust_spacing
local protrude_chars = par.protrude_chars
local statistics = par.statistics
-
- local stack = new_dir_stack()
-
- local leftskip = par.used_left_skip -- used or normal ?
+ local leftskip = par.left_skip
local rightskip = par.right_skip
local parshape = par.par_shape_ptr
- ----- ignored_dimen = par.ignored_dimen
+ -- local adapt_width = par.adapt_width
+ local hsize = par.hsize
- local adapt_width = par.adapt_width
+ local dirstack = par.dirstack
+ local normalize = getnormalizeline()
-- reverse the links of the relevant passive nodes, goto first breakpoint
@@ -1273,11 +1315,15 @@ do
local head = par.head
- -- maybe : each_...
+ -- when we normalize and have no content still ls/rs gets appended while
+ -- the engine doesnt' do that so there is some test missing that prevents
+ -- entering here
while current_break do
- inject_dirs_at_begin_of_line(stack,head)
+ -- hm, here we have head == localpar and in the engine it's a temp node
+
+ head = inject_dirs_at_begin_of_line(dirstack,head)
local disc_break = false
local post_disc_break = false
@@ -1285,10 +1331,9 @@ do
local lineend = nil -- lineend : the last node of the line (and paragraph)
local lastnode = current_break.cur_break -- lastnode: the node after which the dir nodes should be closed
-
if not lastnode then
-- only at the end
- lastnode = slide_node_list(head) -- todo: find_tail
+ lastnode = find_tail(head)
if lastnode == par.final_par_glue then
lineend = lastnode
lastnode = getprev(lastnode)
@@ -1296,16 +1341,16 @@ do
else -- todo: use insert_list_after
local id = getid(lastnode)
if id == glue_code then
- -- lastnode is normal skip
- lastnode = replace_node(lastnode,new_rightskip(rightskip))
+ local r = new_rightskip(unpack(rightskip))
+ setattributelist(r,lastnode)
+ lastnode = replace_node(lastnode,r)
glue_break = true
lineend = lastnode
lastnode = getprev(lastnode)
elseif id == disc_code then
- local prevlast = getprev(lastnode)
- local nextlast = getnext(lastnode)
- local subtype = getsubtype(lastnode)
+ local prevlast, nextlast = getboth(lastnode)
local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode,true)
+ local subtype = getsubtype(lastnode)
if subtype == seconddisc_code then
if not (getid(prevlast) == disc_code and getsubtype(prevlast) == firstdisc_code) then
report_parbuilders('unsupported disc at location %a',3)
@@ -1337,8 +1382,8 @@ do
report_parbuilders('unsupported disc at location %a',4)
end
setsubtype(nextlast,regulardisc_code)
- setfield(nextlast,"replace",post)
- setfield(lastnode,"post") -- nil
+ setreplace(nextlast,post)
+ setpost(lastnode)
end
if replace then
flush_node_list(replace)
@@ -1356,13 +1401,16 @@ do
disc_break = true
elseif id == kern_code then
setkern(lastnode,0)
- elseif getid(lastnode) == math_code then
+ elseif id == math_code then
setkern(lastnode,0) -- surround
-- new in luatex
setglue(lastnode) -- zeros
end
end
- lastnode = inject_dirs_at_end_of_line(stack,lastnode,getnext(head),current_break.cur_break)
+ -- todo: clean up this mess which results from all kind of engine merges
+ -- (start/end nodes)
+ -- hm, head ?
+ lastnode = inject_dirs_at_end_of_line(dirstack,lastnode,getnext(head),current_break.cur_break)
local rightbox = current_break.passive_right_box
if rightbox then
lastnode = insert_node_after(lastnode,lastnode,copy_node(rightbox))
@@ -1371,50 +1419,186 @@ do
lineend = lastnode
end
if lineend and lineend ~= head and protrude_chars > 0 then
- local id = getid(lineend)
- local c = (disc_break and (id == glyph_code or id ~= disc_code) and lineend) or getprev(lineend)
- local p = find_protchar_right(getnext(head),c)
- if p and getid(p) == glyph_code then
- local w, last_rightmost_char = right_pw(p)
- if last_rightmost_char and w ~= 0 then
- -- so we inherit attributes, lineend is new pseudo head
- lineend, c = insert_node_after(lineend,c,new_rightmarginkern(copy_node(last_rightmost_char),-w))
+ if par.line_break_dir == righttoleft_code then
+ if protrude_chars > 2 then
+ local p = lineend
+ local l = nil
+ -- Backtrack over the last zero glues and dirs.
+ while p do
+ local id = getid(p)
+ if id == dir_code then
+ if getsubtype(p) ~= cancel_code then
+ break
+ end
+ p = getprev(p)
+ elseif id == glue_code then
+ if getwidth(p) == 0 then
+ p = getprev(p)
+ else
+ p = nil
+ break
+ end
+ elseif id == glyph_code then
+ break
+ else
+ p = nil
+ break
+ end
+ end
+ -- When |p| is non zero we have something.
+ while p do
+ local id = getid(p)
+ if id == glyph_code then
+ l = p
+ elseif id == glue_code then
+ if getwidth(p) == 0 then
+ -- No harm done.
+ else
+ l = nil
+ end
+ elseif id == dir_code then
+ if getdirection(p) ~= righttoleft_code then
+ p = nil
+ end
+ break
+ elseif id == localpar_code then
+ break
+ elseif id == temp_code then
+ -- Go on.
+ else
+ l = nil
+ end
+ p = getprev(p)
+ end
+ if l and p then
+ local w, last_rightmost_char = right_pw(l)
+ if last_rightmost_char and w ~= 0 then
+ local k = new_rightmarginkern(copy_node(last_rightmost_char),-w)
+ setattributelist(k,l)
+ setlink(p,k,l)
+ end
+ end
+ end
+ else
+ local id = getid(lineend)
+ local c = nil
+ if disc_break and (id == glyph_code or id ~= disc_code) then
+ c = lineend
+ else
+ c = getprev(lineend)
+ end
+ local p = find_protchar_right(getnext(head),c)
+ if p and getid(p) == glyph_code then
+ local w, last_rightmost_char = right_pw(p)
+ if last_rightmost_char and w ~= 0 then
+ -- so we inherit attributes, lineend is new pseudo head
+ local k = new_rightmarginkern(copy_node(last_rightmost_char),-w)
+ setattributelist(k,p)
+-- insert_node_after(c,c,k)
+ insert_node_after(p,p,k)
+-- if c == lineend then
+-- lineend = getnext(c)
+-- end
+ end
end
end
end
-- we finish the line
local r = getnext(lineend)
- setnext(lineend)
+ setnext(lineend) -- lineend moves on as pseudo head
+ local start = getnext(head)
+ setlink(head,r)
if not glue_break then
- if rightskip then
- insert_node_after(lineend,lineend,new_rightskip(right_skip)) -- lineend moves on as pseudo head
- end
+ local rs = new_rightskip(unpack(rightskip))
+ setattributelist(rs,lineend)
+ start, lineend = insert_node_after(start,lineend,rs)
end
- -- each time ?
- local q = getnext(head)
- setlink(head,r)
+ local rs = lineend
-- insert leftbox (if needed after parindent)
local leftbox = current_break.passive_left_box
if leftbox then
- local first = getnext(q)
+ local first = getnext(start)
if first and current_line == (par.first_line + 1) and getid(first) == hlist_code and not getlist(first) then
- insert_node_after(q,q,copy_node(leftbox))
+ insert_node_after(start,start,copy_node(leftbox))
else
- q = insert_node_before(q,q,copy_node(leftbox))
+ start = insert_node_before(start,start,copy_node(leftbox))
end
end
if protrude_chars > 0 then
- local p = find_protchar_left(q)
- if p and getid(p) == glyph_code then
- local w, last_leftmost_char = left_pw(p)
- if last_leftmost_char and w ~= 0 then
- -- so we inherit attributes, q is pseudo head and moves back
- q = insert_node_before(q,q,new_leftmarginkern(copy_node(last_leftmost_char),-w))
+ if par.line_break_dir == righttoleft_code then
+ if protrude_chars > 2 then
+ local p = find_protchar_left(start)
+ if p then
+ local w, last_leftmost_char = right_pw(p)
+ if last_leftmost_char and w ~= 0 then
+ local k = new_rightmarginkern(copy_node(last_leftmost_char),-w)
+ setattributelist(k,p)
+ start = insert_node_before(start,start,k)
+ end
+ end
+ end
+ else
+ local p = find_protchar_left(start)
+ if p and getid(p) == glyph_code then
+ local w, last_leftmost_char = left_pw(p)
+ if last_leftmost_char and w ~= 0 then
+ -- so we inherit attributes, start is pseudo head and moves back
+ local k = new_leftmarginkern(copy_node(last_leftmost_char),-w)
+ setattributelist(k,p)
+ start = insert_node_before(start,start,k)
+ end
end
end
end
- if leftskip then
- q = insert_node_before(q,q,new_leftskip(leftskip))
+ local ls
+ if leftskip or normalize > 0 then
+ -- we could check for non zero but we will normalize anyway
+ ls = new_leftskip(unpack(leftskip))
+ setattributelist(ls,start)
+ start = insert_node_before(start,start,ls)
+ end
+ if normalize > 0 then
+ local localpar = nil
+ local localdir = nil
+ local indent = nil
+ local localpars = nil
+ local notflocal = 0
+ for n, id, subtype in nextnode, start do
+ if id == hlist_code then
+ if normalize > 1 and subtype == indentlist_code then
+ indent = n
+ end
+ elseif id == localpar_code then
+ if start_of_par(n) then --- maybe subtype check instead
+ localpar = n
+ elseif noflocals then
+ noflocals = noflocals + 1
+ localpars[noflocals] = n
+ else
+ noflocals = 1
+ localpars = { n }
+ end
+ elseif id == dir_code then
+ if localpar and not localdir and subtype(n) == cancel_code then
+ localdir = n
+ end
+ end
+ end
+ if indent then
+ local i = new_indentskip(getwidth(indent))
+ setattributelist(i,start)
+ replace_node(indent,i)
+ end
+ if localdir then
+ local d = new_direction((getdirection(localpar)))
+ setattributelist(d,start)
+ replace_node(localpar,d)
+ end
+ if localpars then
+ for i=1,noflocals do
+ start = remove_node(start,localpars[i],true)
+ end
+ end
end
local cur_width, cur_indent
if current_line > par.last_special_line then
@@ -1428,20 +1612,48 @@ do
cur_indent = par.first_indent
cur_width = par.first_width
end
-
- if adapt_width then -- extension
- local l, r = adapt_width(par,current_line)
- cur_indent = cur_indent + l
- cur_width = cur_width - l - r
+ -- extension
+ -- if adapt_width then
+ -- local l, r = adapt_width(par,current_line)
+ -- cur_indent = cur_indent + l
+ -- cur_width = cur_width - l - r
+ -- end
+ --
+ if normalize > 2 then
+ local l = new_lefthangskip()
+ local r = new_righthangskip()
+ if cur_width ~= hsize then
+ cur_indent = hsize - cur_width
+ end
+ if cur_indent > 0 then
+ setwidth(l,cur_indent)
+ elseif cur_indent < 0 then
+ setwidth(r,-cur_indent)
+ end
+ setattributelist(l,start)
+ setattributelist(r,start)
+ if normalize > 3 then
+ -- makes most sense
+ start = insert_node_after(start,ls,l)
+ start = insert_node_before(start,rs,r)
+ else
+ start = insert_node_before(start,ls,l)
+ start = insert_node_after(start,rs,r)
+ end
+ cur_width = hsize
+ cur_indent = 0
end
-
+ --
statistics.noflines = statistics.noflines + 1
+ --
+ -- here we could cleanup: remove all if we have (zero) skips only
+ --
local finished_line = nil
if adjust_spacing > 0 then
statistics.nofadjustedlines = statistics.nofadjustedlines + 1
- finished_line = xpack_nodes(q,cur_width,"cal_expand_ratio",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
+ finished_line = xpack_nodes(start,cur_width,"cal_expand_ratio",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
else
- finished_line = xpack_nodes(q,cur_width,"exactly",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
+ finished_line = xpack_nodes(start,cur_width,"exactly",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis)
end
if protrude_chars > 0 then
statistics.nofprotrudedlines = statistics.nofprotrudedlines + 1
@@ -1451,22 +1663,7 @@ do
local pre_adjust_head = texlists.pre_adjust_head
--
setshift(finished_line,cur_indent)
- --
- -- -- this is gone:
- --
- -- if par.each_line_height ~= ignored_dimen then
- -- setheight(finished_line,par.each_line_height)
- -- end
- -- if par.each_line_depth ~= ignored_dimen then
- -- setdepth(finished_line,par.each_line_depth)
- -- end
- -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then
- -- setheight(finished_line,par.first_line_height)
- -- end
- -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then
- -- setdepth(finished_line,par.last_line_depth)
- -- end
- --
+ --
if texlists.pre_adjust_head ~= pre_adjust_head then
append_list(par, texlists.pre_adjust_head)
texlists.pre_adjust_head = pre_adjust_head
@@ -1502,7 +1699,9 @@ do
end
end
if pen ~= 0 then
- append_to_vlist(par,new_penalty(pen))
+ local p = new_penalty(pen)
+ setattributelist(p,par.head)
+ append_to_vlist(par,p)
end
end
current_line = current_line + 1
@@ -1544,16 +1743,29 @@ do
setlink(head,next)
end
end
+par.head = head
end
-- if current_line ~= par.best_line then
-- report_parbuilders("line breaking")
-- end
- par.head = nil -- needs checking
+ local h = par.head -- hm, head
+ if h then
+ if trace_basic then
+ if getnext(h) then
+ report_parbuilders("something is left over")
+ end
+ if getid(h) ~= localpar_code then
+ report_parbuilders("no local par node")
+ end
+ end
+ flush_node(h)
+ par.head = nil -- needs checking
+ end
current_line = current_line - 1
if trace_basic then
report_parbuilders("paragraph broken into %a lines",current_line)
end
- texnest[texnest.ptr].prevgraf = current_line
+ texset("prevgraf",current_line)
end
local function wrap_up(par)
@@ -1578,10 +1790,14 @@ do
end
end
end
- -- we have a bunch of glue and and temp nodes not freed
+ -- This differs from the engine, where the temp node is removed elsewhere.
local head = par.head
- if getid(head) == temp_code then
- par.head = getnext(head)
+ if head and getid(head) == temp_code then
+ local next = getnext(head)
+ par.head = next
+ if next then
+ setprev(next)
+ end
flush_node(head)
end
post_line_break(par)
@@ -1603,13 +1819,13 @@ do
if prev_r == active then
r = active.next
if r.id == delta_code then
- local aw = active_width.size + r.size active_width.size = aw cur_active_width.size = aw
- local aw = active_width.stretch + r.stretch active_width.stretch = aw cur_active_width.stretch = aw
- local aw = active_width.fi + r.fi active_width.fi = aw cur_active_width.fi = aw
- local aw = active_width.fil + r.fil active_width.fil = aw cur_active_width.fil = aw
- local aw = active_width.fill + r.fill active_width.fill = aw cur_active_width.fill = aw
- local aw = active_width.filll + r.filll active_width.filll = aw cur_active_width.filll = aw
- local aw = active_width.shrink + r.shrink active_width.shrink = aw cur_active_width.shrink = aw
+ local aw = active_width.size + r.size active_width.size = aw cur_active_width.size = aw
+ local aw = active_width.normal + r.normal active_width.normal = aw cur_active_width.normal = aw
+ local aw = active_width.fi + r.fi active_width.fi = aw cur_active_width.fi = aw
+ local aw = active_width.fil + r.fil active_width.fil = aw cur_active_width.fil = aw
+ local aw = active_width.fill + r.fill active_width.fill = aw cur_active_width.fill = aw
+ local aw = active_width.filll + r.filll active_width.filll = aw cur_active_width.filll = aw
+ local aw = active_width.shrink + r.shrink active_width.shrink = aw cur_active_width.shrink = aw
if checked_expansion then
local aw = active_width.adjust_stretch + r.adjust_stretch active_width.adjust_stretch = aw cur_active_width.adjust_stretch = aw
local aw = active_width.adjust_shrink + r.adjust_shrink active_width.adjust_shrink = aw cur_active_width.adjust_shrink = aw
@@ -1621,13 +1837,13 @@ do
elseif prev_r.id == delta_code then
r = prev_r.next
if r == active then
- cur_active_width.size = cur_active_width.size - prev_r.size
- cur_active_width.stretch = cur_active_width.stretch - prev_r.stretch
- cur_active_width.fi = cur_active_width.fi - prev_r.fi
- cur_active_width.fil = cur_active_width.fil - prev_r.fil
- cur_active_width.fill = cur_active_width.fill - prev_r.fill
- cur_active_width.filll = cur_active_width.filll - prev_r.filll
- cur_active_width.shrink = cur_active_width.shrink - prev_r.shrink
+ cur_active_width.size = cur_active_width.size - prev_r.size
+ cur_active_width.normal = cur_active_width.normal - prev_r.normal
+ cur_active_width.fi = cur_active_width.fi - prev_r.fi
+ cur_active_width.fil = cur_active_width.fil - prev_r.fil
+ cur_active_width.fill = cur_active_width.fill - prev_r.fill
+ cur_active_width.filll = cur_active_width.filll - prev_r.filll
+ cur_active_width.shrink = cur_active_width.shrink - prev_r.shrink
if checked_expansion then
cur_active_width.adjust_stretch = cur_active_width.adjust_stretch - prev_r.adjust_stretch
cur_active_width.adjust_shrink = cur_active_width.adjust_shrink - prev_r.adjust_shrink
@@ -1637,13 +1853,13 @@ do
-- prev_r = nil
prev_r = prev_prev_r
elseif r.id == delta_code then
- local rn = r.size cur_active_width.size = cur_active_width.size + rn prev_r.size = prev_r.size + rn
- local rn = r.stretch cur_active_width.stretch = cur_active_width.stretch + rn prev_r.stretch = prev_r.stretch + rn
- local rn = r.fi cur_active_width.fi = cur_active_width.fi + rn prev_r.fi = prev_r.fi + rn
- local rn = r.fil cur_active_width.fil = cur_active_width.fil + rn prev_r.fil = prev_r.fil + rn
- local rn = r.fill cur_active_width.fill = cur_active_width.fill + rn prev_r.fill = prev_r.fill + rn
- local rn = r.filll cur_active_width.filll = cur_active_width.filll + rn prev_r.filll = prev_r.fill + rn
- local rn = r.shrink cur_active_width.shrink = cur_active_width.shrink + rn prev_r.shrink = prev_r.shrink + rn
+ local rn = r.size cur_active_width.size = cur_active_width.size + rn prev_r.size = prev_r.size + rn
+ local rn = r.normal cur_active_width.normal = cur_active_width.normal + rn prev_r.normal = prev_r.normal + rn
+ local rn = r.fi cur_active_width.fi = cur_active_width.fi + rn prev_r.fi = prev_r.fi + rn
+ local rn = r.fil cur_active_width.fil = cur_active_width.fil + rn prev_r.fil = prev_r.fil + rn
+ local rn = r.fill cur_active_width.fill = cur_active_width.fill + rn prev_r.fill = prev_r.fill + rn
+ local rn = r.filll cur_active_width.filll = cur_active_width.filll + rn prev_r.filll = prev_r.fill + rn
+ local rn = r.shrink cur_active_width.shrink = cur_active_width.shrink + rn prev_r.shrink = prev_r.shrink + rn
if checked_expansion then
local rn = r.adjust_stretch cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + rn prev_r.adjust_stretch = prev_r.adjust_stretch + rn
local rn = r.adjust_shrink cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + rn prev_r.adjust_shrink = prev_r.adjust_shrink + rn
@@ -1663,7 +1879,7 @@ do
if cur_active_width.fi ~= fill_width.fi or cur_active_width.fil ~= fill_width.fil or cur_active_width.fill ~= fill_width.fill or cur_active_width.filll ~= fill_width.filll then
return false, 0, fit_decent_class, 0, 0
end
- local adjustment = active_short > 0 and cur_active_width.stretch or cur_active_width.shrink
+ local adjustment = active_short > 0 and cur_active_width.normal or cur_active_width.shrink
if adjustment <= 0 then
return false, 0, fit_decent_class, adjustment, 0
end
@@ -1673,7 +1889,7 @@ do
end
local fit_class = fit_decent_class
if adjustment > 0 then
- local stretch = cur_active_width.stretch
+ local stretch = cur_active_width.normal
if adjustment > shortfall then
adjustment = shortfall
end
@@ -1750,13 +1966,13 @@ do
local tracing_paragraphs = par.tracing_paragraphs
-- local par_active = par.active
- local adapt_width = par.adapt_width
+ -- local adapt_width = par.adapt_width
local parshape = par.par_shape_ptr
local cur_active_width = checked_expansion and { -- distance from current active node
size = active_width.size,
- stretch = active_width.stretch,
+ normal = active_width.normal,
fi = active_width.fi,
fil = active_width.fil,
fill = active_width.fill,
@@ -1766,7 +1982,7 @@ do
adjust_shrink = active_width.adjust_shrink,
} or {
size = active_width.size,
- stretch = active_width.stretch,
+ normal = active_width.normal,
fi = active_width.fi,
fil = active_width.fil,
fill = active_width.fill,
@@ -1777,13 +1993,13 @@ do
while true do
r = prev_r.next
if r.id == delta_code then
- cur_active_width.size = cur_active_width.size + r.size
- cur_active_width.stretch = cur_active_width.stretch + r.stretch
- cur_active_width.fi = cur_active_width.fi + r.fi
- cur_active_width.fil = cur_active_width.fil + r.fil
- cur_active_width.fill = cur_active_width.fill + r.fill
- cur_active_width.filll = cur_active_width.filll + r.filll
- cur_active_width.shrink = cur_active_width.shrink + r.shrink
+ cur_active_width.size = cur_active_width.size + r.size
+ cur_active_width.normal = cur_active_width.normal + r.normal
+ cur_active_width.fi = cur_active_width.fi + r.fi
+ cur_active_width.fil = cur_active_width.fil + r.fil
+ cur_active_width.fill = cur_active_width.fill + r.fill
+ cur_active_width.filll = cur_active_width.filll + r.filll
+ cur_active_width.shrink = cur_active_width.shrink + r.shrink
if checked_expansion then
cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + r.adjust_stretch
cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + r.adjust_shrink
@@ -1797,13 +2013,13 @@ do
if minimum_demerits < awful_badness and (old_line_number ~= par.easy_line or r == par.active) then
if no_break_yet then
no_break_yet = false
- break_width.size = background.size
- break_width.stretch = background.stretch
- break_width.fi = background.fi
- break_width.fil = background.fil
- break_width.fill = background.fill
- break_width.filll = background.filll
- break_width.shrink = background.shrink
+ break_width.size = background.size
+ break_width.normal = background.normal
+ break_width.fi = background.fi
+ break_width.fil = background.fil
+ break_width.fill = background.fill
+ break_width.filll = background.filll
+ break_width.shrink = background.shrink
if checked_expansion then
break_width.adjust_stretch = 0
break_width.adjust_shrink = 0
@@ -1813,25 +2029,25 @@ do
end
end
if prev_r.id == delta_code then
- prev_r.size = prev_r.size - cur_active_width.size + break_width.size
- prev_r.stretch = prev_r.stretch - cur_active_width.stretc + break_width.stretch
- prev_r.fi = prev_r.fi - cur_active_width.fi + break_width.fi
- prev_r.fil = prev_r.fil - cur_active_width.fil + break_width.fil
- prev_r.fill = prev_r.fill - cur_active_width.fill + break_width.fill
- prev_r.filll = prev_r.filll - cur_active_width.filll + break_width.filll
- prev_r.shrink = prev_r.shrink - cur_active_width.shrink + break_width.shrink
+ prev_r.size = prev_r.size - cur_active_width.size + break_width.size
+ prev_r.normal = prev_r.normal - cur_active_width.normal + break_width.normal
+ prev_r.fi = prev_r.fi - cur_active_width.fi + break_width.fi
+ prev_r.fil = prev_r.fil - cur_active_width.fil + break_width.fil
+ prev_r.fill = prev_r.fill - cur_active_width.fill + break_width.fill
+ prev_r.filll = prev_r.filll - cur_active_width.filll + break_width.filll
+ prev_r.shrink = prev_r.shrink - cur_active_width.shrink + break_width.shrink
if checked_expansion then
prev_r.adjust_stretch = prev_r.adjust_stretch - cur_active_width.adjust_stretch + break_width.adjust_stretch
prev_r.adjust_shrink = prev_r.adjust_shrink - cur_active_width.adjust_shrink + break_width.adjust_shrink
end
elseif prev_r == par.active then
- active_width.size = break_width.size
- active_width.stretch = break_width.stretch
- active_width.fi = break_width.fi
- active_width.fil = break_width.fil
- active_width.fill = break_width.fill
- active_width.filll = break_width.filll
- active_width.shrink = break_width.shrink
+ active_width.size = break_width.size
+ active_width.normal = break_width.normal
+ active_width.fi = break_width.fi
+ active_width.fil = break_width.fil
+ active_width.fill = break_width.fill
+ active_width.filll = break_width.filll
+ active_width.shrink = break_width.shrink
if checked_expansion then
active_width.adjust_stretch = break_width.adjust_stretch
active_width.adjust_shrink = break_width.adjust_shrink
@@ -1842,7 +2058,7 @@ do
subtype = nosubtype_code,
next = r,
size = break_width.size - cur_active_width.size,
- stretch = break_width.stretch - cur_active_width.stretch,
+ normal = break_width.normal - cur_active_width.normal,
fi = break_width.fi - cur_active_width.fi,
fil = break_width.fil - cur_active_width.fil,
fill = break_width.fill - cur_active_width.fill,
@@ -1851,16 +2067,16 @@ do
adjust_stretch = break_width.adjust_stretch - cur_active_width.adjust_stretch,
adjust_shrink = break_width.adjust_shrink - cur_active_width.adjust_shrink,
} or {
- id = delta_code,
- subtype = nosubtype_code,
- next = r,
- size = break_width.size - cur_active_width.size,
- stretch = break_width.stretch - cur_active_width.stretch,
- fi = break_width.fi - cur_active_width.fi,
- fil = break_width.fil - cur_active_width.fil,
- fill = break_width.fill - cur_active_width.fill,
- filll = break_width.filll - cur_active_width.filll,
- shrink = break_width.shrink - cur_active_width.shrink,
+ id = delta_code,
+ subtype = nosubtype_code,
+ next = r,
+ size = break_width.size - cur_active_width.size,
+ normal = break_width.normal - cur_active_width.normal,
+ fi = break_width.fi - cur_active_width.fi,
+ fil = break_width.fil - cur_active_width.fil,
+ fill = break_width.fill - cur_active_width.fill,
+ filll = break_width.filll - cur_active_width.filll,
+ shrink = break_width.shrink - cur_active_width.shrink,
}
prev_r.next = q
prev_prev_r = prev_r
@@ -1893,7 +2109,6 @@ do
passive_left_box_width = prev_break and prev_break.passive_last_left_box_width or par.init_internal_left_box_width,
passive_right_box = par.internal_right_box,
passive_right_box_width = par.internal_right_box_width,
- -- analysis = table.fastcopy(cur_active_width),
}
par.passive = passive
local q = {
@@ -1929,7 +2144,7 @@ do
subtype = nosubtype_code,
next = r,
size = cur_active_width.size - break_width.size,
- stretch = cur_active_width.stretch - break_width.stretch,
+ normal = cur_active_width.normal - break_width.normal,
fi = cur_active_width.fi - break_width.fi,
fil = cur_active_width.fil - break_width.fil,
fill = cur_active_width.fill - break_width.fill,
@@ -1938,16 +2153,16 @@ do
adjust_stretch = cur_active_width.adjust_stretch - break_width.adjust_stretch,
adjust_shrink = cur_active_width.adjust_shrink - break_width.adjust_shrink,
} or {
- id = delta_code,
- subtype = nosubtype_code,
- next = r,
- size = cur_active_width.size - break_width.size,
- stretch = cur_active_width.stretch - break_width.stretch,
- fi = cur_active_width.fi - break_width.fi,
- fil = cur_active_width.fil - break_width.fil,
- fill = cur_active_width.fill - break_width.fill,
- filll = cur_active_width.filll - break_width.filll,
- shrink = cur_active_width.shrink - break_width.shrink,
+ id = delta_code,
+ subtype = nosubtype_code,
+ next = r,
+ size = cur_active_width.size - break_width.size,
+ normal = cur_active_width.normal - break_width.normal,
+ fi = cur_active_width.fi - break_width.fi,
+ fil = cur_active_width.fil - break_width.fil,
+ fill = cur_active_width.fill - break_width.fill,
+ filll = cur_active_width.filll - break_width.filll,
+ shrink = cur_active_width.shrink - break_width.shrink,
}
-- q.next = r -- already done
prev_r.next = q
@@ -1971,10 +2186,10 @@ do
line_width = par.first_width
end
end
- if adapt_width then
- local l, r = adapt_width(par,line_number)
- line_width = line_width - l - r
- end
+ -- if adapt_width then
+ -- local l, r = adapt_width(par,line_number)
+ -- line_width = line_width - l - r
+ -- end
end
local artificial_demerits = false -- has d been forced to zero
local shortfall = line_width - cur_active_width.size - par.internal_right_box_width -- used in badness calculations
@@ -1983,69 +2198,53 @@ do
else
shortfall = shortfall - (r.break_node.passive_last_left_box_width or 0)
end
- local pw, lp, rp -- used later on
if protrude_chars > 1 then
- -- this is quite time consuming
- local b = r.break_node
- local l = b and b.cur_break or first_p
- local o = current and getprev(current)
- if current and getid(current) == disc_code then
- local pre, _, _, pretail = getdisc(current,true)
- if pre then
- o = pretail
+ if par.line_break_dir == righttoleft_code then
+ -- not now, we need to keep more track
+ else
+ -- this is quite time consuming
+ local b = r.break_node
+ local l = b and b.cur_break or first_p
+ local o = current and getprev(current)
+ if current and getid(current) == disc_code then
+ local pre, _, _, pretail = getdisc(current,true)
+ if pre then
+ o = pretail
+ else
+ o = find_protchar_right(l,o)
+ end
else
o = find_protchar_right(l,o)
end
- else
- o = find_protchar_right(l,o)
- end
- if o and getid(o) == glyph_code then
- pw, rp = right_pw(o)
- shortfall = shortfall + pw
- end
- local id = getid(l)
- if id == glyph_code then
- -- ok ?
- elseif id == disc_code and getfield(l,"post") then
- l = getfield(l,"post") -- TODO: first char could be a disc
- else
- l = find_protchar_left(l)
- end
- if l and getid(l) == glyph_code then
- pw, lp = left_pw(l)
- shortfall = shortfall + pw
+ if o and getid(o) == glyph_code then
+ shortfall = shortfall + right_pw(o)
+ end
+ local id = getid(l)
+ if id == glyph_code then
+ -- ok ?
+ elseif id == disc_code and getpost(l) then
+ l = getpost(l) -- TODO: first char could be a disc
+ else
+ l = find_protchar_left(l)
+ end
+ if l and getid(l) == glyph_code then
+ shortfall = shortfall + left_pw(l)
+ end
end
end
if checked_expansion and shortfall ~= 0 then
- local margin_kern_stretch = 0
- local margin_kern_shrink = 0
- if protrude_chars > 1 then
- if lp then
- local char, font = isglyph(lp)
- local data = expansions[font][char]
- if data then
- margin_kern_stretch, margin_kern_shrink = data.glyphstretch, data.glyphshrink
- end
- end
- if rp then
- local char, font = isglyph(rp)
- local data = expansions[font][char]
- if data then
- margin_kern_stretch = margin_kern_stretch + data.glyphstretch
- margin_kern_shrink = margin_kern_shrink + data.glyphshrink
+ if shortfall > 0 then
+ local total = cur_active_width.adjust_stretch
+ if total > 0 then
+ if total > shortfall then
+ shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2
+ else
+ shortfall = shortfall - total
end
end
- end
- local total = cur_active_width.adjust_stretch + margin_kern_stretch
- if shortfall > 0 and total > 0 then
- if total > shortfall then
- shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2
- else
- shortfall = shortfall - total
- end
- else
- total = cur_active_width.adjust_shrink + margin_kern_shrink
- if shortfall < 0 and total > 0 then
+ elseif shortfall < 0 then
+ local total = cur_active_width.adjust_shrink
+ if total > 0 then
if total > - shortfall then
shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2
else
@@ -2068,7 +2267,7 @@ do
shortfall = 0
end
else
- local stretch = cur_active_width.stretch
+ local stretch = cur_active_width.normal
if shortfall > 7230584 and stretch < 1663497 then
b = infinite_badness
fit_class = fit_very_loose_class
@@ -2101,7 +2300,7 @@ do
-- g = 0
shortfall = 0
elseif shortfall > 0 then
- g = cur_active_width.stretch
+ g = cur_active_width.normal
elseif shortfall < 0 then
g = cur_active_width.shrink
else
@@ -2192,7 +2391,6 @@ do
if trace_basic then
report_parbuilders("starting at %a",head)
end
-
local par = initialize_line_break(head,d)
local checked_expansion = par.checked_expansion
@@ -2200,8 +2398,9 @@ do
local disc_width = par.disc_width
local background = par.background
local tracing_paragraphs = par.tracing_paragraphs
+ local dirstack = { n = 0 }
- local dirstack = new_dir_stack()
+ par.dirstack = dirstack
if tracing_paragraphs then
diagnostics.start()
@@ -2225,13 +2424,13 @@ do
active_short = 0,
active_glue = 0,
}
- active_width.size = background.size
- active_width.stretch = background.stretch
- active_width.fi = background.fi
- active_width.fil = background.fil
- active_width.fill = background.fill
- active_width.filll = background.filll
- active_width.shrink = background.shrink
+ active_width.size = background.size
+ active_width.normal = background.normal
+ active_width.fi = background.fi
+ active_width.fil = background.fil
+ active_width.fill = background.fill
+ active_width.filll = background.filll
+ active_width.shrink = background.shrink
if checked_expansion then
active_width.adjust_stretch = 0
@@ -2241,13 +2440,12 @@ do
par.passive = nil -- = 0
par.printed_node = temp_head -- only when tracing, shared
par.pass_number = 0
- -- par.auto_breaking = true
+ -- par.auto_breaking = true
setnext(temp_head,head)
local current = head
local first_p = current
-
local auto_breaking = true
par.font_in_short_display = 0
@@ -2288,12 +2486,7 @@ do
while current and p_active ~= n_active do
local char, id = isglyph(current)
if char then
- local wd, ht, dp = getwhd(current)
- if is_rotated(par.line_break_dir) then
- active_width.size = active_width.size + ht + dp
- else
- active_width.size = active_width.size + wd
- end
+ active_width.size = active_width.size + getwidth(current)
if checked_expansion then
local font = id -- == font
local data = checked_expansion[font]
@@ -2312,44 +2505,15 @@ do
end
end
elseif id == hlist_code or id == vlist_code then
- local wd, ht, dp = getwhd(current)
- if textdir_parallel(getdirection(current),par.line_break_dir) then
- active_width.size = active_width.size + wd
- else
- active_width.size = active_width.size + ht + dp
- end
+ active_width.size = active_width.size + getwidth(current)
elseif id == glue_code then
- -- if par.auto_breaking then
- if auto_breaking then
- local prev_p = getprev(current)
- if prev_p and prev_p ~= temp_head then
- local id = getid(prev_p)
- -- we need to check this with the latest patches to the tex kernel
- if (id == glyph_code) or (id < math_code) then
- p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
- elseif id == kern_code then
- local s = getsubtype(prev_p)
- if s ~= userkern_code and s ~= italickern_code then
- p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
- end
- end
- end
- end
- check_shrinkage(par,current)
- local width, stretch, shrink, stretch_order = getglue(current)
- local order = fillcodes[stretch_order]
- active_width.size = active_width.size + width
- active_width[order] = active_width[order] + stretch
- active_width.shrink = active_width.shrink + shrink
+ goto glue
elseif id == disc_code then
local subtype = getsubtype(current)
if subtype ~= seconddisc_code then
local line_break_dir = par.line_break_dir
if second_pass or subtype <= automaticdisc_code then
- local actual_pen = subtype == automaticdisc_code and par.ex_hyphen_penalty or par.hyphen_penalty
- -- 0.81 :
- -- local actual_pen = getpenalty(current)
- --
+ local actual_pen = getpenalty(current)
local pre, post, replace = getdisc(current)
if not pre then -- trivial pre-break
disc_width.size = 0
@@ -2377,7 +2541,7 @@ do
if getid(cur_p_next) ~= disc_code or getsubtype(cur_p_next) ~= seconddisc_code then
report_parbuilders("unsupported disc at location %a",1)
else
- local pre = getfield(cur_p_next,"pre")
+ local pre = getpre(cur_p_next)
if pre then
local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre)
disc_width.size = disc_width.size + size
@@ -2386,16 +2550,7 @@ do
disc_width.adjust_shrink = disc_width.adjust_shrink + adjust_shrink
end
p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, cur_p_next, checked_expansion)
- --
- -- I will look into this some day ... comment in linebreak.w says that this fails,
- -- maybe this is what Taco means with his comment in the luatex manual.
- --
- -- do_one_seven_eight(sub_disc_width_from_active_width);
- -- do_one_seven_eight(reset_disc_width);
- -- s = vlink_no_break(vlink(current));
- -- add_to_widths(s, line_break_dir, adjust_spacing,disc_width);
- -- ext_try_break(...,first_p,vlink(current));
- --
+ -- there is a comment about something messy here in the source
else
report_parbuilders("unsupported disc at location %a",2)
end
@@ -2420,49 +2575,46 @@ do
end
elseif id == kern_code then
local s = getsubtype(current)
+ local kern = getkern(current)
if s == userkern_code or s == italickern_code then
local v = getnext(current)
- -- if par.auto_breaking and getid(v) == glue_code then
if auto_breaking and getid(v) == glue_code then
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 + getkern(current)
- else
- local kern = getkern(current)
- if kern ~= 0 then
- active_width.size = active_width.size + kern
- if checked_expansion and expand_kerns and getsubtype(current) == fontkern_code then
- local stretch, shrink = kern_stretch_shrink(current,kern)
- if expand_kerns == "stretch" then
- active_width.adjust_stretch = active_width.adjust_stretch + stretch
- elseif expand_kerns == "shrink" then
- active_width.adjust_shrink = active_width.adjust_shrink + shrink
- else
- active_width.adjust_stretch = active_width.adjust_stretch + stretch
- active_width.adjust_shrink = active_width.adjust_shrink + shrink
- end
+ active_width.size = active_width.size + kern
+ elseif kern ~= 0 then
+ active_width.size = active_width.size + kern
+ if checked_expansion and expand_kerns and s == fontkern_code then
+ local stretch, shrink = kern_stretch_shrink(current,kern)
+ if expand_kerns == "stretch" then
+ active_width.adjust_stretch = active_width.adjust_stretch + stretch
+ elseif expand_kerns == "shrink" then
+ active_width.adjust_shrink = active_width.adjust_shrink + shrink
+ else
+ active_width.adjust_stretch = active_width.adjust_stretch + stretch
+ active_width.adjust_shrink = active_width.adjust_shrink + shrink
end
end
end
elseif id == math_code then
- -- par.auto_breaking = getsubtype(current) == endmath_code
auto_breaking = getsubtype(current) == endmath_code
- local v = getnext(current)
- -- if par.auto_breaking and getid(v) == glue_code then
- if auto_breaking and getid(v) == glue_code then
- p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
+ if is_zero_glue(current) or ignore_math_skip(current) then
+ local v = getnext(current)
+ if auto_breaking and getid(v) == glue_code then
+ 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 + getkern(current) + getwidth(current)
+ else
+ goto glue
end
- local active_width = par.active_width
- active_width.size = active_width.size + getkern(current) -- surround
- -- new in luatex
- + getwidth(current)
elseif id == rule_code then
active_width.size = active_width.size + getwidth(current)
elseif id == penalty_code then
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
+ par.line_break_dir = checked_line_dir(dirstack,current) or par.line_break_dir
elseif id == localpar_code then
par.internal_pen_inter = getfield(current,"pen_inter")
par.internal_pen_broken = getfield(current,"pen_broken")
@@ -2477,6 +2629,35 @@ do
report_parbuilders("node of type %a found in paragraph",type(id))
end
end
+ goto done
+ ::glue::
+ do
+ if auto_breaking then
+ local prev_p = getprev(current)
+ if prev_p and prev_p ~= temp_head then
+ local id = getid(prev_p)
+ -- we need to check this with the latest patches to the tex kernel
+ if (id == glyph_code) or (id < math_code) then
+ p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
+ elseif id == kern_code then
+ local s = getsubtype(prev_p)
+ if s ~= userkern_code and s ~= italickern_code then
+ p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion)
+ end
+ end
+ end
+ end
+ local width, stretch, shrink, stretch_order, shrink_order = getglue(current)
+ if shrink_order ~= 0 and shrink ~= 0 then
+ infinite_shrinkage_error(par)
+ shrink_order = 0
+ end
+ local order = fillcodes[stretch_order]
+ active_width.size = active_width.size + width
+ active_width[order] = active_width[order] + stretch
+ active_width.shrink = active_width.shrink + shrink
+ end
+ ::done::
current = getnext(current)
end
if not current then
@@ -2533,8 +2714,8 @@ do
if tracing_paragraphs then
diagnostics.current_pass(par,"emergencypass")
end
- par.background.stretch = par.background.stretch + par.emergency_stretch
- par.final_pass = true
+ par.background.normal = par.background.normal + par.emergency_stretch
+ par.final_pass = true
end
end
return wrap_up(par)
@@ -2546,8 +2727,14 @@ end
do
+ local tonumber = tonumber
+ local utfchar = utf.char
+ local write = texio.write
+ local write_nl = texio.write_nl
+ local formatters = string.formatters
+
local function write_esc(cs)
- local esc = tex.escapechar
+ local esc = texget("escapechar")
if esc then
write("log",utfchar(esc),cs)
else
@@ -2623,13 +2810,13 @@ do
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)
+ local s = q.active_short
+ local g = q.active_glue
if current then
- write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%s g=%s"](
+ write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%p g=%p"](
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"](
+ write_nl("log",formatters["@@%d: line %d.%d%s t=%s s=%p a=%p"](
passive.serial or 0,q.line_number-1,fit_class,typ_ind,q.total_demerits,s,g))
end
else
@@ -2716,7 +2903,7 @@ do
end
function diagnostics.overfull_hbox(hlist,line,d)
- common_message(hlist,line,formatters["Overfull \\hbox (%spt too wide)"](number.toscaled(d)))
+ common_message(hlist,line,formatters["Overfull \\hbox (%p too wide)"](d))
end
function diagnostics.bad_hbox(hlist,line,b)
@@ -2731,15 +2918,15 @@ do
common_message(hlist,line,formatters["Loose \\hbox (badness %i)"](b))
end
-end
+ -- reporting --
--- reporting --
+ statistics.register("alternative parbuilders", function()
+ if nofpars > 0 then
+ return formatters["%s paragraphs, %s lines (%s protruded, %s adjusted)"](nofpars,noflines,nofprotrudedlines,nofadjustedlines)
+ end
+ end)
-statistics.register("alternative parbuilders", function()
- if nofpars > 0 then
- return formatters["%s paragraphs, %s lines (%s protruded, %s adjusted)"](nofpars,noflines,nofprotrudedlines,nofadjustedlines)
- end
-end)
+end
do
@@ -2757,126 +2944,6 @@ do
local setnodecolor = nodes.tracers.colors.set
- -- 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)
- -- setdirection(hlist,direction or tex.textdirection)
- -- 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) == fontkern_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) == fontkern_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
@@ -2885,6 +2952,7 @@ do
local hlist = new_hlist()
setdirection(hlist,direction)
+ setattributelist(hlist,head)
if head == nil then
setwidth(hlist,width)
@@ -2895,7 +2963,7 @@ do
local cal_expand_ratio = method == "cal_expand_ratio" or method == "subst_ex_font"
- direction = direction or tex.textdir
+ direction = direction or texget("textdir")
local line = 0
@@ -2915,10 +2983,8 @@ do
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)
+ local adjust_tail = adjust_head and find_tail(adjust_head)
+ local pre_adjust_tail = pre_adjust_head and find_tail(pre_adjust_head)
local checked_expansion = false
@@ -2929,10 +2995,11 @@ do
-- this one also needs to check the font, so in the end indeed we might end up with two variants
+ -- we now have fast loops so maybe no longer a need for an expansion stack
+
local fontexps, lastfont
local function process(current) -- called nested in disc replace
-
while current do
local char, id = isglyph(current)
if char then
@@ -2952,20 +3019,19 @@ do
end
end
end
- -- use inline
local wd, ht, dp = getwhd(current)
- natural = natural + wd
if ht > height then
height = ht
end
if dp > depth then
depth = dp
end
+ natural = natural + wd
elseif id == kern_code then
local kern = getkern(current)
if kern == 0 then
-- no kern
- elseif getsubtype(current) == fontkern_code then -- check getkern(p)
+ elseif getsubtype(current) == fontkern_code then
if cal_expand_ratio then
local stretch, shrink = kern_stretch_shrink(current,kern)
font_stretch = font_stretch + stretch
@@ -2981,19 +3047,18 @@ do
local subtype = getsubtype(current)
if subtype ~= seconddisc_code then
-- todo : local stretch, shrink = char_stretch_shrink(s)
- local replace = getfield(current,"replace")
+ local replace = getreplace(current)
if replace then
process(replace)
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 wd, ht, dp = getwhd(leader)
local leader = getleader(current)
- local wd, ht, dp = getwhd(leader) -- can become getwhd(current) after 1.003
if ht > height then
height = ht
end
@@ -3001,41 +3066,36 @@ do
depth = dp
end
end
+ natural = natural + wd
elseif id == hlist_code or id == vlist_code then
- local sh = getshift(current)
local wd, ht, dp = getwhd(current)
- local hs, ds = ht - sh, dp + sh
- natural = natural + wd
+ local sh = getshift(current)
+ local hs = ht - sh
+ local ds = dp + sh
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
+ elseif id == rule_code or id == unset_code then
+ local wd, ht, dp = getwhd(current)
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
+ elseif id == math_code then
+ if is_zero_glue(current) or ignore_math_skip(current) then
+ natural = natural + getkern(current)
+ else
+ local wd, stretch, shrink, stretch_order, shrink_order = getglue(current)
+ total_stretch[stretch_order] = total_stretch[stretch_order] + stretch
+ total_shrink [shrink_order] = total_shrink[shrink_order] + shrink
+ natural = natural + wd
end
elseif id == ins_code or id == mark_code then
local prev, next = getboth(current)
@@ -3056,21 +3116,11 @@ do
else
adjust_head = list
end
- adjust_tail = slide_node_list(list) -- find_tail(list)
+ adjust_tail = find_tail(list)
elseif id == dir_code then
- hpack_dir = checked_line_dir(stack,current) or hpack_dir
+ -- no need to deal with directions here (as we only support two)
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
+ natural = natural + getwidth(current)
end
current = getnext(current)
end
@@ -3088,25 +3138,21 @@ do
if method == "additional" then
width = width + natural
end
-
setwhd(hlist,width,height,depth)
-
local delta = width - natural
if delta == 0 then
- setfield(hlist,"glue_sign",0)
- setfield(hlist,"glue_order",0)
- setfield(hlist,"glue_set",0)
+ setglue(hlist,0,0,0) -- set order sign
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
+ 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
+ elseif font_expand_ratio < -1 then
+ font_expand_ratio = -1
end
-
local fontexps, lastfont
for i=1,expansion_index do
local g = expansion_stack[i]
@@ -3118,33 +3164,33 @@ do
lastfont = font
end
local data = fontexps[char]
- if trace_expansion then
- setnodecolor(g,"hz:positive")
+ if data then
+ if trace_expansion then
+ setnodecolor(g,"hz:positive")
+ end
+ e = font_expand_ratio * data.glyphstretch
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
+ e = font_expand_ratio * stretch
end
setexpansion(g,e)
end
+ font_stretch = font_expand_ratio * font_stretch
+ delta = delta - font_stretch
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)
+ setglue(hlist,delta/tso,order,1) -- set order sign
else
- setfield(hlist,"glue_sign",0)
- setfield(hlist,"glue_order",order)
- setfield(hlist,"glue_set",0)
+ setglue(hlist,0,order,0) -- set order sign
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 > texget("hbadness") then
if last_badness > 100 then
diagnostics.underfull_hbox(hlist,line,last_badness)
else
@@ -3154,15 +3200,15 @@ do
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
+ 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
+ if font_expand_ratio > 1 then
+ font_expand_ratio = 1
+ elseif font_expand_ratio < -1 then
font_expand_ratio = -1
end
-
local fontexps, lastfont
for i=1,expansion_index do
local g = expansion_stack[i]
@@ -3174,44 +3220,62 @@ do
lastfont = font
end
local data = fontexps[char]
- if trace_expansion then
- setnodecolor(g,"hz:negative")
+ if data then
+ if trace_expansion then
+ setnodecolor(g,"hz:negative")
+ end
+ e = font_expand_ratio * data.glyphshrink
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
+ e = font_expand_ratio * shrink
end
setexpansion(g,e)
end
+ font_shrink = font_expand_ratio * font_shrink
+ delta = delta - font_shrink
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)
+ setglue(hlist,-delta/tso,order,2) -- set order sign
else
- setfield(hlist,"glue_sign",0)
- setfield(hlist,"glue_order",order)
- setfield(hlist,"glue_set",0)
+ setglue(hlist,0,order,0) -- set order sign
end
if font_expand_ratio ~= 0 then
-- todo
- elseif tso < -delta and order == 0 then -- and getlist(hlist) then
+ elseif tso < -delta and order == 0 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
+ local fuzz = - delta - tso
+ local hfuzz = texget("hfuzz")
+ if fuzz > hfuzz or texget("hbadness") < 100 then
+ local overfullrule = texget("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,getdirection(hlist))) -- todo: find_tail
+ setnext(find_tail(list),new_rule(overfullrule,nil,nil,getdirection(hlist)))
+ end
+ diagnostics.overfull_hbox(hlist,line,fuzz)
+ if head and getnormalizeline() > 4 then
+ -- we need to get rid of this one when we unpack a box but on the
+ -- other hand, we only do this when a specific width is set so
+ -- probably we have a fixed box then
+ local h = getnext(head)
+ if h then
+ local found = find_node(glue_code,rightskip_code)
+ if found then
+ local p = getprev(found)
+ local g = new_correctionskip(-fuzz)
+ setattributelist(g,found)
+ if p and getid(p) == marginkern_code then
+ found = p
+ end
+ insert_node_before(head,found,g)
+ end
+ end
end
- diagnostics.overfull_hbox(hlist,line,-delta)
end
- elseif order == 0 and getlist(hlist) and last_badness > tex.hbadness then
+ elseif order == 0 and getlist(hlist) and last_badness > texget("hbadness") then
diagnostics.bad_hbox(hlist,line,last_badness)
end
end