From 0cf41dff08cdc61119a2598cf1fa501cd15bfc54 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Thu, 7 Apr 2016 23:26:48 +0200 Subject: [fontloader] sync Context as of 2016-04-07 --- src/fontloader/misc/fontloader-font-gbn.lua | 236 ++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 src/fontloader/misc/fontloader-font-gbn.lua (limited to 'src/fontloader/misc/fontloader-font-gbn.lua') diff --git a/src/fontloader/misc/fontloader-font-gbn.lua b/src/fontloader/misc/fontloader-font-gbn.lua new file mode 100644 index 0000000..f81c877 --- /dev/null +++ b/src/fontloader/misc/fontloader-font-gbn.lua @@ -0,0 +1,236 @@ +if not modules then modules = { } end modules ['font-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 + texio.write_nl("fatal error: this module is not for context") + os.exit() +end + +local fonts = fonts +local nodes = nodes + +local nuts = nodes.nuts -- context abstraction of direct nodes + +local traverse_id = nuts.traverse_id +local free_node = nuts.free +local remove_node = nuts.remove + +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 getprev = nuts.getprev +local getnext = nuts.getnext +local getdisc = nuts.getdisc +local setchar = nuts.setchar +local setlink = nuts.setlink + +-- 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 ligaturing = nuts.ligaturing +local kerning = nuts.kerning + +local basemodepass = true + +local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning = nil end +local function k_warning() texio.write_nl("warning: node.kerning called 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 nodes.handlers.setbasemodepass(v) + basemodepass = v +end + +function nodes.handlers.nodepass(head) + local fontdata = fonts.hashes.identifiers + if fontdata then + local nuthead = tonut(head) + local usedfonts = { } + local basefonts = { } + local prevfont = nil + local basefont = nil + local variants = nil + local redundant = nil + for n in traverse_id(glyph_code,nuthead) 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 + 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) + if not redundant then + redundant = { n } + else + redundant[#redundant+1] = n + end + end + end + end + end + end + end + if redundant then + for i=1,#redundant do + local n = redundant[i] + remove_node(nuthead,n) + free_node(n) + end + end + for d in traverse_id(disc_code,nuthead) 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 + 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) or head + end + end + end + if basemodepass and #basefonts > 0 then + for i=1,#basefonts do + local range = basefonts[i] + local start = range[1] + local stop = range[2] + if start then + local front = nuthead == start + local prev, next + if stop then + next = getnext(stop) + start, stop = ligaturing(start,stop) + start, stop = kerning(start,stop) + else + prev = getprev(start) + start = ligaturing(start) + start = kerning(start) + end + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + if front and nuthead ~= start then + head = tonode(start) + end + end + end + end + return head, true + else + return head, false + end +end + +function nodes.handlers.basepass(head) + if not basemodepass then + head = n_ligaturing(head) + head = n_kerning(head) + end + return head, true +end + +local nodepass = nodes.handlers.nodepass +local basepass = nodes.handlers.basepass +local injectpass = nodes.injections.handler +local protectpass = nodes.handlers.protectglyphs + +function nodes.simple_font_handler(head) + if head then + head = nodepass(head) + head = injectpass(head) + if not basemodepass then + head = basepass(head) + end + protectpass(head) + return head, true + else + return head, false + end +end -- cgit v1.2.3