summaryrefslogtreecommitdiff
path: root/tex/generic
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2018-06-09 15:32:09 +0200
committerContext Git Mirror Bot <phg42.2a@gmail.com>2018-06-09 15:32:09 +0200
commit93dccfc40625a754b372edd228724969b28e4342 (patch)
tree94cec6d553ccc2b797802f39085f9a4725bec8ce /tex/generic
parent86bfea5faac983d15c47eec27f43ec56e75c69ef (diff)
downloadcontext-93dccfc40625a754b372edd228724969b28e4342.tar.gz
2018-06-09 14:37:00
Diffstat (limited to 'tex/generic')
-rw-r--r--tex/generic/context/luatex/luatex-fonts-def.lua98
-rw-r--r--tex/generic/context/luatex/luatex-fonts-gbn.lua301
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua16
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua4
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