diff options
Diffstat (limited to 'tex/generic')
| -rw-r--r-- | tex/generic/context/luatex/luatex-fonts-def.lua | 98 | ||||
| -rw-r--r-- | tex/generic/context/luatex/luatex-fonts-gbn.lua | 301 | ||||
| -rw-r--r-- | tex/generic/context/luatex/luatex-fonts-merged.lua | 16 | ||||
| -rw-r--r-- | tex/generic/context/luatex/luatex-fonts.lua | 4 | 
4 files changed, 410 insertions, 9 deletions
diff --git a/tex/generic/context/luatex/luatex-fonts-def.lua b/tex/generic/context/luatex/luatex-fonts-def.lua new file mode 100644 index 000000000..a8bc3b06f --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-def.lua @@ -0,0 +1,98 @@ +if not modules then modules = { } end modules ['luatex-fonts-def'] = { +    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" +} + +if context then +    texio.write_nl("fatal error: this module is not for context") +    os.exit() +end + +local fonts = fonts + +-- A bit of tuning for definitions. + +fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload + +-- tricky: we sort of bypass the parser and directly feed all into +-- the sub parser + +function fonts.definers.getspecification(str) +    return "", str, "", ":", str +end + +-- the generic name parser (different from context!) + +local list = { } + +local function issome ()    list.lookup = 'name'          end -- xetex mode prefers name (not in context!) +local function isfile ()    list.lookup = 'file'          end +local function isname ()    list.lookup = 'name'          end +local function thename(s)   list.name   = s               end +local function issub  (v)   list.sub    = v               end +local function iscrap (s)   list.crap   = string.lower(s) end +local function iskey  (k,v) list[k]     = v               end +local function istrue (s)   list[s]     = true            end +local function isfalse(s)   list[s]     = false           end + +local P, S, R, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs + +local spaces     = P(" ")^0 +local namespec   = Cs((P("{")/"") * (1-S("}"))^0 * (P("}")/"") + (1-S("/:("))^0) +local crapspec   = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces +local filename_1 = P("file:")/isfile * (namespec/thename) +local filename_2 = P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]") +local fontname_1 = P("name:")/isname * (namespec/thename) +local fontname_2 = P(true)/issome * (namespec/thename) +----- sometext   = (R("az","AZ","09") + S("+-.{}"))^1 +local sometext   = (P("{")/"")*(1-P("}"))^0*(P("}")/"") + (R("az","AZ","09")+S("+-."))^1 +local truevalue  = P("+") * spaces * (sometext/istrue) +local falsevalue = P("-") * spaces * (sometext/isfalse) +local keyvalue   = (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey +local somevalue  = sometext/istrue +local subvalue   = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim +local option     = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces +local options    = P(":") * spaces * (P(";")^0  * option)^0 + +local pattern    = (filename_1 + filename_2 + fontname_1 + fontname_2) * subvalue^0 * crapspec^0 * options^0 + +local function colonized(specification) -- xetex mode +    list = { } +    lpeg.match(pattern,specification.specification) +    list.crap = nil -- style not supported, maybe some day +    if list.name then +        specification.name = list.name +        list.name = nil +    end +    if list.lookup then +        specification.lookup = list.lookup +        list.lookup = nil +    end +    if list.sub then +        specification.sub = list.sub +        list.sub = nil +    end +    specification.features.normal = fonts.handlers.otf.features.normalize(list) +    return specification +end + +fonts.definers.registersplit(":",colonized,"cryptic") +fonts.definers.registersplit("", colonized,"more cryptic") -- catches \font\text=[names] + +function fonts.definers.applypostprocessors(tfmdata) +    local postprocessors = tfmdata.postprocessors +    if postprocessors then +        for i=1,#postprocessors do +            local extrahash = postprocessors[i](tfmdata) -- after scaling etc +            if type(extrahash) == "string" and extrahash ~= "" then +                -- e.g. a reencoding needs this +                extrahash = string.gsub(lower(extrahash),"[^a-z]","-") +                tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash) +            end +        end +    end +    return tfmdata +end diff --git a/tex/generic/context/luatex/luatex-fonts-gbn.lua b/tex/generic/context/luatex/luatex-fonts-gbn.lua new file mode 100644 index 000000000..272f65e95 --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-gbn.lua @@ -0,0 +1,301 @@ +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 +    texio.write_nl("fatal error: this module is not for context") +    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() 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 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 diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 0889d7777..e0c1b7899 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@  -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua  -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date  : 06/08/18 09:31:24 +-- merge date  : 06/09/18 14:30:08  do -- begin closure to overcome local limits and interference @@ -32982,11 +32982,13 @@ local loadedfonts=constructors.loadedfonts  local designsizes=constructors.designsizes  local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end  local splitter,splitspecifiers=nil,""  -local P,C,S,Cc=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc +local P,C,S,Cc,Cs=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc,lpeg.Cs  local left=P("(")  local right=P(")")  local colon=P(":")  local space=P(" ") +local lbrace=P("{") +local rbrace=P("}")  definers.defaultlookup="file"  local prefixpattern=P(false)  local function addspecifier(symbol) @@ -32995,7 +32997,7 @@ local function addspecifier(symbol)    local lookup=C(prefixpattern)*colon    local sub=left*C(P(1-left-right-method)^1)*right    local specification=C(method)*C(P(1)^1) -  local name=C((1-sub-specification)^1) +  local name=Cs((lbrace/"")*(1-rbrace)^1*(rbrace/"")+(1-sub-specification)^1)    splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc("")))  end  local function addlookup(str,default) @@ -33376,15 +33378,15 @@ local function iscrap (s)  list.crap=string.lower(s) end  local function iskey (k,v) list[k]=v        end  local function istrue (s)  list[s]=true      end  local function isfalse(s)  list[s]=false      end -local P,S,R,C=lpeg.P,lpeg.S,lpeg.R,lpeg.C +local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs  local spaces=P(" ")^0 -local namespec=(1-S("/:("))^0  +local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0)  local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces  local filename_1=P("file:")/isfile*(namespec/thename)  local filename_2=P("[")*P(true)/isname*(((1-P("]"))^0)/thename)*P("]")  local fontname_1=P("name:")/isname*(namespec/thename)  local fontname_2=P(true)/issome*(namespec/thename) -local sometext=(R("az","AZ","09")+S("+-.{}"))^1 +local sometext=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(R("az","AZ","09")+S("+-."))^1  local truevalue=P("+")*spaces*(sometext/istrue)  local falsevalue=P("-")*spaces*(sometext/isfalse)  local keyvalue=(C(sometext)*spaces*P("=")*spaces*C(sometext))/iskey @@ -36376,7 +36378,7 @@ end -- closure  do -- begin closure to overcome local limits and interference -if not modules then modules={} end modules ['font-gbn']={ +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", diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index b80ea5564..b0f5aac3f 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -275,7 +275,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then          -- We support xetex compatible specifiers (plain/latex only). -        loadmodule('font-xtx.lua') +        loadmodule('luatex-fonts-def.lua') -- was font-xtx.lua          -- Here come some additional features. @@ -289,7 +289,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then          -- We need to plug into a callback and the following module implements the          -- handlers. Actual plugging in happens later. -        loadmodule('font-gbn.lua') +        loadmodule('luatex-fonts-gbn.lua')      end  | 
