diff options
author | Hans Hagen <pragma@wxs.nl> | 2018-08-15 19:40:19 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2018-08-15 19:40:19 +0200 |
commit | d6850b00fa0f937514389e8d090db87b0163a703 (patch) | |
tree | 145d9be2d7f5c5bddf908c014954911e50e1c6ea /tex/context/base/mkiv/node-fnt.lua | |
parent | 36a37da721032b8d02fad41f22ad717ee8136f34 (diff) | |
download | context-d6850b00fa0f937514389e8d090db87b0163a703.tar.gz |
2018-08-15 18:54:00
Diffstat (limited to 'tex/context/base/mkiv/node-fnt.lua')
-rw-r--r-- | tex/context/base/mkiv/node-fnt.lua | 477 |
1 files changed, 250 insertions, 227 deletions
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua index f606e393c..ee0119d49 100644 --- a/tex/context/base/mkiv/node-fnt.lua +++ b/tex/context/base/mkiv/node-fnt.lua @@ -215,6 +215,7 @@ function handlers.characters(head,groupcode,size,packtype,direction) local prevattr = 0 local variants = nil local redundant = nil + local firstnone = nil local lastfont = nil local lastproc = nil local lastnone = nil @@ -261,7 +262,7 @@ function handlers.characters(head,groupcode,size,packtype,direction) end end - local function setnode(n,font,attr) -- we could use prevfont and prevattr when we set then first + local function setnode(n,font,attr) -- we could use prevfont and prevattr when we set them first if firstnone then protectnone() end @@ -554,30 +555,22 @@ end if LUATEXVERSION >= 1.090 then - function handlers.characters(head,groupcode,size,packtype,direction) - -- either next or not, but definitely no already processed list - starttiming(nodes) - - local usedfonts = { } - local attrfonts = { } - local basefonts = { } - local basefont = nil - local prevfont = nil - local prevattr = 0 - local variants = nil - local redundant = nil - local lastfont = nil - local lastproc = nil - local lastnone = nil - - local a, u, b, r, e = 0, 0, 0, 0, 0 - - if trace_fontrun then - start_trace(head) - end + do + + local usedfonts + local attrfonts + local basefonts + local basefont + local prevfont + local prevattr + local variants + local redundant + local firstnone + local lastfont + local lastproc + local lastnone - -- There is no gain in checking for a single glyph and then having a fast path. On the - -- metafun manual (with some 2500 single char lists) the difference is just noise. + local a, u, b, r, e local function protectnone() protect_glyphs(firstnone,lastnone) @@ -646,262 +639,292 @@ if LUATEXVERSION >= 1.090 then end end - for n, char, font in nextchar, head do - -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context - local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context - if font ~= prevfont or attr ~= prevattr then - prevfont = font - prevattr = attr - variants = fontvariants[font] - local fontmode = fontmodes[font] - if fontmode == "none" then - setnone(n) - elseif fontmode == "base" then - setbase(n) - else - setnode(n,font,attr) + function handlers.characters(head,groupcode,size,packtype,direction) + -- either next or not, but definitely no already processed list + starttiming(nodes) + + usedfonts = { } + attrfonts = { } + basefonts = { } + basefont = nil + prevfont = nil + prevattr = 0 + variants = nil + redundant = nil + firstnone = nil + lastfont = nil + lastproc = nil + lastnone = nil + + a, u, b, r, e = 0, 0, 0, 0, 0 + + if trace_fontrun then + start_trace(head) + end + + -- There is no gain in checking for a single glyph and then having a fast path. On the + -- metafun manual (with some 2500 single char lists) the difference is just noise. + + for n, char, font in nextchar, head do + -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context + local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context + if font ~= prevfont or attr ~= prevattr then + prevfont = font + prevattr = attr + variants = fontvariants[font] + local fontmode = fontmodes[font] + if fontmode == "none" then + setnone(n) + elseif fontmode == "base" then + setbase(n) + else + setnode(n,font,attr) + end + elseif firstnone then + lastnone = n end - elseif firstnone then - lastnone = n - end - if variants then - if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then - local hash = variants[char] - if hash then - local p = getprev(n) - if p then - local char = ischar(p) -- checked - local variant = hash[char] - if variant then - if trace_variants then - report_fonts("replacing %C by %C",char,variant) - end - setchar(p,variant) - if redundant then - r = r + 1 - redundant[r] = n - else - r = 1 - redundant = { n } + if variants then + if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then + local hash = variants[char] + if hash then + local p = getprev(n) + if p then + local char = ischar(p) -- checked + local variant = hash[char] + if variant then + if trace_variants then + report_fonts("replacing %C by %C",char,variant) + end + setchar(p,variant) + if redundant then + r = r + 1 + redundant[r] = n + else + r = 1 + redundant = { n } + end end end + elseif keep_redundant then + -- go on, can be used for tracing + elseif redundant then + r = r + 1 + redundant[r] = n + else + r = 1 + redundant = { n } end - elseif keep_redundant then - -- go on, can be used for tracing - elseif redundant then - r = r + 1 - redundant[r] = n - else - r = 1 - redundant = { n } end end end - end - if firstnone then - protectnone() - end + if firstnone then + protectnone() + end - if force_boundaryrun then + if force_boundaryrun then - -- we can inject wordboundaries and then let the hyphenator do its work - -- but we need to get rid of those nodes in order to build ligatures - -- and kern (a rather context thing) + -- we can inject wordboundaries and then let the hyphenator do its work + -- but we need to get rid of those nodes in order to build ligatures + -- and kern (a rather context thing) - for b, subtype in nextboundary, head do - if subtype == word_boundary then - if redundant then - r = r + 1 - redundant[r] = b - else - r = 1 - redundant = { b } + for b, subtype in nextboundary, head do + if subtype == word_boundary then + if redundant then + r = r + 1 + redundant[r] = b + else + r = 1 + redundant = { b } + end end end - end - end + end - if redundant then - for i=1,r do - local r = redundant[i] - local p, n = getboth(r) - if r == head then - head = n - setprev(n) - else - setlink(p,n) - end - if b > 0 then - for i=1,b do - local bi = basefonts[i] - local b1 = bi[1] - local b2 = bi[2] - if b1 == b2 then - if b1 == r then - bi[1] = false - bi[2] = false + if redundant then + for i=1,r do + local r = redundant[i] + local p, n = getboth(r) + if r == head then + head = n + setprev(n) + else + setlink(p,n) + end + if b > 0 then + for i=1,b do + local bi = basefonts[i] + local b1 = bi[1] + local b2 = bi[2] + if b1 == b2 then + if b1 == r then + bi[1] = false + bi[2] = false + end + elseif b1 == r then + bi[1] = n + elseif b2 == r then + bi[2] = p end - elseif b1 == r then - bi[1] = n - elseif b2 == r then - bi[2] = p end end + flush_node(r) end - flush_node(r) end - end - if force_discrun then - - -- basefont is not supported in disc only runs ... it would mean a lot of - -- ranges .. we could try to run basemode as a separate processor run but - -- not for now (we can consider it when the new node code is tested - for d in nextdisc, head do - -- we could use first_glyph, only doing replace is good enough because - -- pre and post are normally used for hyphens and these come from fonts - -- that part of the hyphenated word - local _, _, r = getdisc(d) - if r then - local prevfont = nil - local prevattr = nil - local none = false - for n, char, font in nextchar, r do - local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context - if font ~= prevfont or attr ~= prevattr then - prevfont = font - prevattr = attr - local fontmode = fontmodes[font] - if fontmode == "none" then - setnone(n) - elseif fontmode == "base" then - setbase(n) - else - setnode(n,font,attr) + if force_discrun then + + -- basefont is not supported in disc only runs ... it would mean a lot of + -- ranges .. we could try to run basemode as a separate processor run but + -- not for now (we can consider it when the new node code is tested + for d in nextdisc, head do + -- we could use first_glyph, only doing replace is good enough because + -- pre and post are normally used for hyphens and these come from fonts + -- that part of the hyphenated word + local _, _, r = getdisc(d) + if r then + local prevfont = nil + local prevattr = nil + local none = false + for n, char, font in nextchar, r do + local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context + if font ~= prevfont or attr ~= prevattr then + prevfont = font + prevattr = attr + local fontmode = fontmodes[font] + if fontmode == "none" then + setnone(n) + elseif fontmode == "base" then + setbase(n) + else + setnode(n,font,attr) + end + elseif firstnone then + -- lastnone = n + lastnone = nil end - elseif firstnone then - -- lastnone = n - lastnone = nil + -- we assume one font for now (and if there are more and we get into issues then + -- we can always remove the break) + break end - -- we assume one font for now (and if there are more and we get into issues then - -- we can always remove the break) - break - end - if firstnone then - protectnone() + if firstnone then + protectnone() + end + -- elseif expanders then + -- local subtype = getsubtype(d) + -- if subtype == automatic_code or subtype == explicit_code then + -- expanders[subtype](d) + -- e = e + 1 + -- end end - -- elseif expanders then - -- local subtype = getsubtype(d) - -- if subtype == automatic_code or subtype == explicit_code then - -- expanders[subtype](d) - -- e = e + 1 - -- end end - end - - end - if trace_fontrun then - stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders) - end + end - -- in context we always have at least 2 processors - if u == 0 then - -- skip - elseif u == 1 then - local attr = a > 0 and 0 or false -- 0 is the savest way - for i=1,#lastproc do - head = lastproc[i](head,lastfont,attr,direction) + if trace_fontrun then + stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders) end - else - -- local attr = a == 0 and false or 0 -- 0 is the savest way - local attr = a > 0 and 0 or false -- 0 is the savest way - for font, processors in next, usedfonts do -- unordered - for i=1,#processors do - head = processors[i](head,font,attr,direction,u) + + -- in context we always have at least 2 processors + if u == 0 then + -- skip + elseif u == 1 then + local attr = a > 0 and 0 or false -- 0 is the savest way + for i=1,#lastproc do + head = lastproc[i](head,lastfont,attr,direction) end - end - end - if a == 0 then - -- skip - elseif a == 1 then - local font, dynamics = next(attrfonts) - for attribute, processors in next, dynamics do -- unordered, attr can switch in between - for i=1,#processors do - head = processors[i](head,font,attribute,direction) + else + -- local attr = a == 0 and false or 0 -- 0 is the savest way + local attr = a > 0 and 0 or false -- 0 is the savest way + for font, processors in next, usedfonts do -- unordered + for i=1,#processors do + head = processors[i](head,font,attr,direction,u) + end end end - else - for font, dynamics in next, attrfonts do + if a == 0 then + -- skip + elseif a == 1 then + local font, dynamics = next(attrfonts) for attribute, processors in next, dynamics do -- unordered, attr can switch in between for i=1,#processors do - head = processors[i](head,font,attribute,direction,a) + head = processors[i](head,font,attribute,direction) end end - end - end - if b == 0 then - -- skip - elseif b == 1 then - -- only one font - local range = basefonts[1] - local start = range[1] - local stop = range[2] - if (start or stop) and (start ~= stop) then - local front = head == start - if stop then - start = ligaturing(start,stop) - start = kerning(start,stop) - elseif start then -- safeguard - start = ligaturing(start) - start = kerning(start) - end - if front and head ~= start then - head = start + else + for font, dynamics in next, attrfonts do + for attribute, processors in next, dynamics do -- unordered, attr can switch in between + for i=1,#processors do + head = processors[i](head,font,attribute,direction,a) + end + end end end - else - -- multiple fonts - for i=1,b do - local range = basefonts[i] + if b == 0 then + -- skip + elseif b == 1 then + -- only one font + local range = basefonts[1] local start = range[1] local stop = range[2] - if start then -- and start ~= stop but that seldom happens + if (start or stop) and (start ~= stop) then local front = head == start - local prev = getprev(start) - local next = getnext(stop) if stop then - start, stop = ligaturing(start,stop) - start, stop = kerning(start,stop) - else + start = ligaturing(start,stop) + start = kerning(start,stop) + elseif start then -- safeguard start = ligaturing(start) start = kerning(start) end - -- is done automatically - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) - end - -- till here if front and head ~= start then head = start end end + else + -- multiple fonts + for i=1,b do + local range = basefonts[i] + local start = range[1] + local stop = range[2] + if start then -- and start ~= stop but that seldom happens + local front = head == start + local prev = getprev(start) + local next = getnext(stop) + if stop then + start, stop = ligaturing(start,stop) + start, stop = kerning(start,stop) + else + start = ligaturing(start) + start = kerning(start) + end + -- is done automatically + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + -- till here + if front and head ~= start then + head = start + end + end + end end + + stoptiming(nodes) + + if trace_characters then + nodes.report(head) + end + + return head end - stoptiming(nodes) - if trace_characters then - nodes.report(head) - end - return head + end end - handlers.protectglyphs = protect_glyphs handlers.unprotectglyphs = unprotect_glyphs |