From 78334b0d4607b242273f9d0cde94f6a6fba51832 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 26 Sep 2018 20:50:34 +0000 Subject: luaotfload (26sep18) git-svn-id: svn://tug.org/texlive/trunk@48771 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/luatex/luaotfload/fontloader-fonts-gbn.lua | 300 +++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-gbn.lua (limited to 'Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-gbn.lua') diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-gbn.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-gbn.lua new file mode 100644 index 00000000000..53be41c7ed4 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-fonts-gbn.lua @@ -0,0 +1,300 @@ +if not modules then modules = { } end modules ['luatex-fonts-gbn'] = { + version = 1.001, + comment = "companion to luatex-*.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- generic [base|node] mode handler + +if context then + os.exit() +end + +local next = next + +local fonts = fonts +local nodes = nodes + +local nuts = nodes.nuts -- context abstraction of direct nodes + +local traverse_id = nuts.traverse_id +local flush_node = nuts.flush_node + +local glyph_code = nodes.nodecodes.glyph +local disc_code = nodes.nodecodes.disc + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfont = nuts.getfont +local getchar = nuts.getchar +local getid = nuts.getid +local getboth = nuts.getboth +local getprev = nuts.getprev +local getnext = nuts.getnext +local getdisc = nuts.getdisc +local setchar = nuts.setchar +local setlink = nuts.setlink +local setprev = nuts.setprev + +-- from now on we apply ligaturing and kerning here because it might interfere with complex +-- opentype discretionary handling where the base ligature pass expect some weird extra +-- pointers (which then confuse the tail slider that has some checking built in) + +local n_ligaturing = node.ligaturing +local n_kerning = node.kerning + +local d_ligaturing = nuts.ligaturing +local d_kerning = nuts.kerning + +local basemodepass = true + +local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning = nil end +local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning = nil end + +function node.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return n_ligaturing(...) +end + +function node.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return n_kerning(...) +end + +function nuts.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return d_ligaturing(...) +end + +function nuts.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return d_kerning(...) +end + +-- direct.ligaturing = nuts.ligaturing +-- direct.kerning = nuts.kerning + +function nodes.handlers.setbasemodepass(v) + basemodepass = v +end + +local function nodepass(head,groupcode,size,packtype,direction) + local fontdata = fonts.hashes.identifiers + if fontdata then + local usedfonts = { } + local basefonts = { } + local prevfont = nil + local basefont = nil + local variants = nil + local redundant = nil + local nofused = 0 + for n in traverse_id(glyph_code,head) do + local font = getfont(n) + if font ~= prevfont then + if basefont then + basefont[2] = getprev(n) + end + prevfont = font + local used = usedfonts[font] + if not used then + local tfmdata = fontdata[font] -- + if tfmdata then + local shared = tfmdata.shared -- we need to check shared, only when same features + if shared then + local processors = shared.processes + if processors and #processors > 0 then + usedfonts[font] = processors + nofused = nofused + 1 + elseif basemodepass then + basefont = { n, nil } + basefonts[#basefonts+1] = basefont + end + end + local resources = tfmdata.resources + variants = resources and resources.variants + variants = variants and next(variants) and variants or false + end + else + local tfmdata = fontdata[prevfont] + if tfmdata then + local resources = tfmdata.resources + variants = resources and resources.variants + variants = variants and next(variants) and variants or false + end + end + end + if variants then + local char = getchar(n) + 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 and getid(p) == glyph_code then + local variant = hash[getchar(p)] + if variant then + setchar(p,variant) + end + end + end + -- per generic user request we always remove selectors + if not redundant then + redundant = { n } + else + redundant[#redundant+1] = n + end + end + end + end + local nofbasefonts = #basefonts + if redundant then + for i=1,#redundant do + local r = redundant[i] + local p, n = getboth(r) + if r == head then + head = n + setprev(n) + else + setlink(p,n) + end + if nofbasefonts > 0 then + for i=1,nofbasefonts do + local bi = basefonts[i] + if r == bi[1] then + bi[1] = n + end + if r == bi[2] then + bi[2] = n + end + end + end + flush_node(r) + end + end + for d in traverse_id(disc_code,head) do + local _, _, r = getdisc(d) + if r then + for n in traverse_id(glyph_code,r) do + local font = getfont(n) + if font ~= prevfont then + prevfont = font + local used = usedfonts[font] + if not used then + local tfmdata = fontdata[font] -- + if tfmdata then + local shared = tfmdata.shared -- we need to check shared, only when same features + if shared then + local processors = shared.processes + if processors and #processors > 0 then + usedfonts[font] = processors + nofused = nofused + 1 + end + end + end + end + end + end + end + end + if next(usedfonts) then + for font, processors in next, usedfonts do + for i=1,#processors do + head = processors[i](head,font,0,direction,nofused) or head + end + end + end + if basemodepass and nofbasefonts > 0 then + for i=1,nofbasefonts do + local range = basefonts[i] + local start = range[1] + local stop = range[2] + if start then + local front = head == start + local prev, next + if stop then + next = getnext(stop) + start, stop = d_ligaturing(start,stop) + start, stop = d_kerning(start,stop) + else + prev = getprev(start) + start = d_ligaturing(start) + start = d_kerning(start) + end + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + if front and head ~= start then + head = start + end + end + end + end + end + return head +end + +local function basepass(head) + if basemodepass then + head = d_ligaturing(head) + head = d_kerning(head) + end + return head +end + +local protectpass = node.direct.protect_glyphs +local injectpass = nodes.injections.handler + +-- This is the only official public interface and this one can be hooked into a callback (chain) and +-- everything else can change!@ Functione being visibel doesn't mean that it's part of the api. + +function nodes.handlers.nodepass(head,...) + if head then + return tonode(nodepass(tonut(head),...)) + end +end + +function nodes.handlers.basepass(head) + if head then + return tonode(basepass(tonut(head))) + end +end + +function nodes.handlers.injectpass(head) + if head then + return tonode(injectpass(tonut(head))) + end +end + +function nodes.handlers.protectpass(head) + if head then + protectpass(tonut(head)) + return head + end +end + +function nodes.simple_font_handler(head,groupcode,size,packtype,direction) + if head then + head = tonut(head) + head = nodepass(head,groupcode,size,packtype,direction) + head = injectpass(head) + if not basemodepass then + head = basepass(head) + end + protectpass(head) + head = tonode(head) + end + return head +end -- cgit v1.2.3