diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua | 156 |
1 files changed, 121 insertions, 35 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua b/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua index 1e1a2c44a69..cef77cea109 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/typo-fln.lua @@ -21,7 +21,10 @@ typesetters.firstlines = typesetters.firstlines or { } local firstlines = typesetters.firstlines local nodes = nodes + local tasks = nodes.tasks +local enableaction = tasks.enableaction +local disableaction = tasks.disableaction local context = context local implement = interfaces.implement @@ -31,6 +34,9 @@ local tonut = nuts.tonut local tonode = nuts.tonode local getnext = nuts.getnext +local getprev = nuts.getprev +local getboth = nuts.getboth +local setboth = nuts.setboth local getid = nuts.getid local getfield = nuts.getfield local setfield = nuts.setfield @@ -39,6 +45,10 @@ local setlist = nuts.setlist local getattr = nuts.getattr local setattr = nuts.setattr local getbox = nuts.getbox +local getdisc = nuts.getdisc +local setdisc = nuts.setdisc +local setlink = nuts.setlink +local setfont = nuts.setfont local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph @@ -46,13 +56,12 @@ local disc_code = nodecodes.disc local kern_code = nodecodes.kern local traverse_id = nuts.traverse_id -local free_node_list = nuts.flush_list -local free_node = nuts.flush_node +local flush_node_list = nuts.flush_list +local flush_node = nuts.flush_node local copy_node_list = nuts.copy_list local insert_node_after = nuts.insert_after -local insert_node_before = nuts.insert_before -local hpack_node_list = nuts.hpack local remove_node = nuts.remove +local list_dimensions = nuts.dimensions local nodepool = nuts.pool local newpenalty = nodepool.penalty @@ -65,7 +74,7 @@ firstlines.actions = actions local a_firstline = attributes.private('firstline') local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') -local a_colorspace = attributes.private('colormodel') +local a_colormodel = attributes.private('colormodel') local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue @@ -82,7 +91,7 @@ local settings = nil function firstlines.set(specification) settings = specification or { } - tasks.enableaction("processors","typesetters.firstlines.handler") + enableaction("processors","typesetters.firstlines.handler") if trace_firstlines then report_firstlines("enabling firstlines") end @@ -120,12 +129,31 @@ actions[v_line] = function(head,setting) local n = 0 local temp = copy_node_list(head) local linebreaks = { } - for g in traverse_id(glyph_code,temp) do - if dynamic > 0 then - setattr(g,0,dynamic) + + local function set(head) + for g in traverse_id(glyph_code,head) do + if dynamic > 0 then + setattr(g,0,dynamic) + end + setfont(g,font) + end + end + + set(temp) + + for g in traverse_id(disc_code,temp) do + local pre, post, replace = getdisc(g) + if pre then + set(pre) + end + if post then + set(post) + end + if replace then + set(replace) end - setfield(g,"font",font) end + local start = temp local list = temp local prev = temp @@ -137,25 +165,37 @@ actions[v_line] = function(head,setting) if i <= - hangafter then hsize = hsize - hangindent end + + local function try(extra) + local width = list_dimensions(list,start) + if extra then + width = width + list_dimensions(extra) + end + if width > hsize then + list = prev + return true + else + linebreaks[i] = n + prev = start + nofchars = n + end + end + while start do local id = getid(start) if id == glyph_code then n = n + 1 elseif id == disc_code then -- this could be an option + n = n + 1 + if try(getfield(start,"pre")) then + break + end elseif id == kern_code then -- todo: fontkern -- this could be an option elseif n > 0 then - local pack = hpack_node_list(copy_node_list(list,start)) - if getfield(pack,"width") > hsize then - free_node_list(pack) - list = prev + if try() then break - else - linebreaks[i] = n - prev = start - free_node_list(pack) - nofchars = n end end start = getnext(start) @@ -166,23 +206,69 @@ actions[v_line] = function(head,setting) end local start = head local n = 0 + + local function update(start) + if dynamic > 0 then + setattr(start,0,dynamic) + end + setfont(start,font) + if ca and ca > 0 then + setattr(start,a_colormodel,ma == 0 and 1 or ma) + setattr(start,a_color,ca) + end + if ta and ta > 0 then + setattr(start,a_transparency,ta) + end + end + for i=1,noflines do local linebreak = linebreaks[i] while start and n < nofchars do local id = getid(start) - if id == glyph_code then -- or id == disc_code then - if dynamic > 0 then - setattr(start,0,dynamic) - end - setfield(start,"font",font) - if ca and ca > 0 then - setattr(start,a_colorspace,ma == 0 and 1 or ma) - setattr(start,a_color,ca) - end - if ta and ta > 0 then - setattr(start,a_transparency,ta) - end + if id == glyph_code then n = n + 1 + update(start) + elseif id == disc_code then + n = n + 1 + local disc = start + local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true) + if linebreak == n then + local p, n = getboth(start) + if pre then + for current in traverse_id(glyph_code,pre) do + update(current) + end + setlink(pretail,n) + setlink(p,pre) + start = pretail + pre = nil + else + setlink(p,n) + start = p + end + if post then + local p, n = getboth(start) + setlink(posttail,n) + setlink(start,post) + post = nil + end + else + local p, n = getboth(start) + if replace then + for current in traverse_id(glyph_code,replace) do + update(current) + end + setlink(replacetail,n) + setlink(p,replace) + start = replacetail + replace = nil + else + setlink(p,n) + start = p + end + end + setdisc(disc,pre,post,replace) + flush_node(disc) end if linebreak == n then if trace_firstlines then @@ -196,7 +282,7 @@ actions[v_line] = function(head,setting) start = getnext(start) end end - free_node_list(temp) + flush_node_list(temp) return head, true end @@ -220,7 +306,7 @@ actions[v_word] = function(head,setting) ok = true end if ca and ca > 0 then - setattr(start,a_colorspace,ma == 0 and 1 or ma) + setattr(start,a_colormodel,ma == 0 and 1 or ma) setattr(start,a_color,ca) end if ta and ta > 0 then @@ -229,7 +315,7 @@ actions[v_word] = function(head,setting) if dynamic > 0 then setattr(start,0,dynamic) end - setfield(start,"font",font) + setfont(start,font) elseif id == disc_code then -- continue elseif id == kern_code then -- todo: fontkern @@ -263,7 +349,7 @@ function firstlines.handler(head) end if attr then -- here as we can process nested boxes first so we need to keep state - tasks.disableaction("processors","typesetters.firstlines.handler") + disableaction("processors","typesetters.firstlines.handler") -- texsetattribute(attribute,unsetvalue) local alternative = settings.alternative or v_default local action = actions[alternative] or actions[v_default] |