summaryrefslogtreecommitdiff
path: root/tex/generic
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2013-10-20 01:20:14 +0300
committerMarius <mariausol@gmail.com>2013-10-20 01:20:14 +0300
commit965214d981e6129b782c67adcaf3a81aedcb0bac (patch)
tree84f5945aae8efc9b6eb1898b873be5453cafe43d /tex/generic
parente7d0d90a434e5452ff9e86c8abab5a4cac35e2f1 (diff)
downloadcontext-965214d981e6129b782c67adcaf3a81aedcb0bac.tar.gz
stable 2013.05.28 00:36
Diffstat (limited to 'tex/generic')
-rw-r--r--tex/generic/context/luatex/luatex-basics-gen.lua28
-rw-r--r--tex/generic/context/luatex/luatex-basics-nod.lua79
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua2902
-rw-r--r--tex/generic/context/luatex/luatex-fonts-syn.lua4
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua8
-rw-r--r--tex/generic/context/luatex/luatex-test.tex4
6 files changed, 747 insertions, 2278 deletions
diff --git a/tex/generic/context/luatex/luatex-basics-gen.lua b/tex/generic/context/luatex/luatex-basics-gen.lua
index 9cf5b9317..4a46fbb07 100644
--- a/tex/generic/context/luatex/luatex-basics-gen.lua
+++ b/tex/generic/context/luatex/luatex-basics-gen.lua
@@ -89,7 +89,6 @@ local remapper = {
fea = "font feature files",
pfa = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this!
pfb = "type1 fonts", -- this is for Khaled, in ConTeXt we don't use this!
- afm = "afm",
}
function resolvers.findfile(name,fileformat)
@@ -118,11 +117,6 @@ end
resolvers.findbinfile = resolvers.findfile
-function resolvers.loadbinfile(filename,filetype)
- local data = io.loaddata(filename)
- return true, data, #data
-end
-
function resolvers.resolve(s)
return s
end
@@ -155,29 +149,19 @@ do
local cachepaths = kpse.expand_var('$TEXMFCACHE') or ""
- -- quite like tex live or so (the weird $TEXMFCACHE test seems to be needed on miktex)
+ -- quite like tex live or so
- if cachepaths == "" or cachepaths == "$TEXMFCACHE" then
+ if cachepaths == "" then
cachepaths = kpse.expand_var('$TEXMFVAR') or ""
end
- -- this also happened to be used (the weird $TEXMFVAR test seems to be needed on miktex)
+ -- this also happened to be used
- if cachepaths == "" or cachepaths == "$TEXMFVAR" then
+ if cachepaths == "" then
cachepaths = kpse.expand_var('$VARTEXMF') or ""
end
- -- and this is a last resort (hm, we could use TEMP or TEMPDIR)
-
- if cachepaths == "" then
- local fallbacks = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" }
- for i=1,#fallbacks do
- cachepaths = os.getenv(fallbacks[i]) or ""
- if cachepath ~= "" and lfs.isdir(cachepath) then
- break
- end
- end
- end
+ -- and this is a last resort
if cachepaths == "" then
cachepaths = "."
@@ -283,7 +267,7 @@ function caches.savedata(path,name,data)
local luaname, lucname = makefullname(path,name)
if luaname then
texio.write(string.format("(save: %s)",luaname))
- table.tofile(luaname,data,true)
+ table.tofile(luaname,data,true,{ reduce = true })
if lucname and type(caches.compile) == "function" then
os.remove(lucname) -- better be safe
texio.write(string.format("(save: %s)",lucname))
diff --git a/tex/generic/context/luatex/luatex-basics-nod.lua b/tex/generic/context/luatex/luatex-basics-nod.lua
index 50a1e8627..5ab9df7f9 100644
--- a/tex/generic/context/luatex/luatex-basics-nod.lua
+++ b/tex/generic/context/luatex/luatex-basics-nod.lua
@@ -88,80 +88,17 @@ function nodes.delete(head,current)
return nodes.remove(head,current,true)
end
+nodes.before = node.insert_before
+nodes.after = node.insert_after
+
function nodes.pool.kern(k)
local n = new_node("kern",1)
n.kern = k
return n
end
--- experimental
-
-local getfield = node.getfield or function(n,tag) return n[tag] end
-local setfield = node.setfield or function(n,tag,value) n[tag] = value end
-
-nodes.getfield = getfield
-nodes.setfield = setfield
-
-nodes.getattr = getfield
-nodes.setattr = setfield
-
-if node.getid then nodes.getid = node.getid else function nodes.getid (n) return getfield(n,"id") end end
-if node.getsubtype then nodes.getsubtype = node.getsubtype else function nodes.getsubtype(n) return getfield(n,"subtype") end end
-if node.getnext then nodes.getnext = node.getnext else function nodes.getnext (n) return getfield(n,"next") end end
-if node.getprev then nodes.getprev = node.getprev else function nodes.getprev (n) return getfield(n,"prev") end end
-if node.getchar then nodes.getchar = node.getchar else function nodes.getchar (n) return getfield(n,"char") end end
-if node.getfont then nodes.getfont = node.getfont else function nodes.getfont (n) return getfield(n,"font") end end
-if node.getlist then nodes.getlist = node.getlist else function nodes.getlist (n) return getfield(n,"list") end end
-
-function nodes.tonut (n) return n end
-function nodes.tonode(n) return n end
-
--- being lazy ... just copy a bunch ... not all needed in generic but we assume
--- nodes to be kind of private anyway
-
-nodes.tostring = node.tostring or tostring
-nodes.copy = node.copy
-nodes.copy_list = node.copy_list
-nodes.delete = node.delete
-nodes.dimensions = node.dimensions
-nodes.end_of_math = node.end_of_math
-nodes.flush_list = node.flush_list
-nodes.flush_node = node.flush_node
-nodes.free = node.free
-nodes.insert_after = node.insert_after
-nodes.insert_before = node.insert_before
-nodes.hpack = node.hpack
-nodes.new = node.new
-nodes.tail = node.tail
-nodes.traverse = node.traverse
-nodes.traverse_id = node.traverse_id
-nodes.slide = node.slide
-nodes.vpack = node.vpack
-
-nodes.first_glyph = node.first_glyph
-nodes.first_character = node.first_character
-nodes.has_glyph = node.has_glyph or node.first_glyph
-
-nodes.current_attr = node.current_attr
-nodes.do_ligature_n = node.do_ligature_n
-nodes.has_field = node.has_field
-nodes.last_node = node.last_node
-nodes.usedlist = node.usedlist
-nodes.protrusion_skippable = node.protrusion_skippable
-nodes.write = node.write
-
-nodes.has_attribute = node.has_attribute
-nodes.set_attribute = node.set_attribute
-nodes.unset_attribute = node.unset_attribute
-
-nodes.protect_glyphs = node.protect_glyphs
-nodes.unprotect_glyphs = node.unprotect_glyphs
-nodes.kerning = node.kerning
-nodes.ligaturing = node.ligaturing
-nodes.mlist_to_hlist = node.mlist_to_hlist
-
--- in generic code, at least for some time, we stay nodes, while in context
--- we can go nuts (e.g. experimental); this split permits us us keep code
--- used elsewhere stable but at the same time play around in context
-
-nodes.nuts = nodes
+function nodes.endofmath(n)
+ for n in traverse_id(math_code,n.next) do
+ return n
+ end
+end
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 8fe2ad9c1..cf5862ca9 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 : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 10/15/13 13:52:35
+-- merge date : 05/28/13 00:34:00
do -- begin closure to overcome local limits and interference
@@ -95,7 +95,6 @@ if not modules then modules={} end modules ['l-lpeg']={
license="see context related readme files"
}
lpeg=require("lpeg")
-if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
local type,next,tostring=type,next,tostring
local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format
local floor=math.floor
@@ -111,46 +110,28 @@ patterns.anything=anything
patterns.endofstring=endofstring
patterns.beginofstring=alwaysmatched
patterns.alwaysmatched=alwaysmatched
-local sign=S('+-')
-local zero=P('0')
-local digit=R('09')
-local octdigit=R("07")
-local lowercase=R("az")
-local uppercase=R("AZ")
-local underscore=P("_")
-local hexdigit=digit+lowercase+uppercase
+local digit,sign=R('09'),S('+-')
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
local newline=crlf+S("\r\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
local space=P(" ")
-local period=P(".")
-local comma=P(",")
-local utfbom_32_be=P('\000\000\254\255')
-local utfbom_32_le=P('\255\254\000\000')
-local utfbom_16_be=P('\254\255')
-local utfbom_16_le=P('\255\254')
-local utfbom_8=P('\239\187\191')
+local utfbom_32_be=P('\000\000\254\255')
+local utfbom_32_le=P('\255\254\000\000')
+local utfbom_16_be=P('\255\254')
+local utfbom_16_le=P('\254\255')
+local utfbom_8=P('\239\187\191')
local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8
local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8")
-local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")
local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0)
local utf8next=R("\128\191")
-patterns.utfbom_32_be=utfbom_32_be
-patterns.utfbom_32_le=utfbom_32_le
-patterns.utfbom_16_be=utfbom_16_be
-patterns.utfbom_16_le=utfbom_16_le
-patterns.utfbom_8=utfbom_8
-patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n")
-patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000")
patterns.utf8one=R("\000\127")
patterns.utf8two=R("\194\223")*utf8next
patterns.utf8three=R("\224\239")*utf8next*utf8next
patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next
patterns.utfbom=utfbom
patterns.utftype=utftype
-patterns.utfstricttype=utfstricttype
patterns.utfoffset=utfoffset
local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four
local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false)
@@ -174,8 +155,23 @@ local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
patterns.stripper=stripper
patterns.collapser=collapser
-patterns.lowercase=lowercase
-patterns.uppercase=uppercase
+patterns.digit=digit
+patterns.sign=sign
+patterns.cardinal=sign^0*digit^1
+patterns.integer=sign^0*digit^1
+patterns.unsigned=digit^0*P('.')*digit^1
+patterns.float=sign^0*patterns.unsigned
+patterns.cunsigned=digit^0*P(',')*digit^1
+patterns.cfloat=sign^0*patterns.cunsigned
+patterns.number=patterns.float+patterns.integer
+patterns.cnumber=patterns.cfloat+patterns.integer
+patterns.oct=P("0")*R("07")^1
+patterns.octal=patterns.oct
+patterns.HEX=P("0x")*R("09","AF")^1
+patterns.hex=P("0x")*R("09","af")^1
+patterns.hexadecimal=P("0x")*R("09","AF","af")^1
+patterns.lowercase=R("az")
+patterns.uppercase=R("AZ")
patterns.letter=patterns.lowercase+patterns.uppercase
patterns.space=space
patterns.tab=P("\t")
@@ -183,12 +179,12 @@ patterns.spaceortab=patterns.space+patterns.tab
patterns.newline=newline
patterns.emptyline=newline^1
patterns.equal=P("=")
-patterns.comma=comma
-patterns.commaspacer=comma*spacer^0
-patterns.period=period
+patterns.comma=P(",")
+patterns.commaspacer=P(",")*spacer^0
+patterns.period=P(".")
patterns.colon=P(":")
patterns.semicolon=P(";")
-patterns.underscore=underscore
+patterns.underscore=P("_")
patterns.escaped=escaped
patterns.squote=squote
patterns.dquote=dquote
@@ -201,29 +197,10 @@ patterns.unspacer=((patterns.spacer^1)/"")^0
patterns.singlequoted=squote*patterns.nosquote*squote
patterns.doublequoted=dquote*patterns.nodquote*dquote
patterns.quoted=patterns.doublequoted+patterns.singlequoted
-patterns.digit=digit
-patterns.octdigit=octdigit
-patterns.hexdigit=hexdigit
-patterns.sign=sign
-patterns.cardinal=digit^1
-patterns.integer=sign^-1*digit^1
-patterns.unsigned=digit^0*period*digit^1
-patterns.float=sign^-1*patterns.unsigned
-patterns.cunsigned=digit^0*comma*digit^1
-patterns.cfloat=sign^-1*patterns.cunsigned
-patterns.number=patterns.float+patterns.integer
-patterns.cnumber=patterns.cfloat+patterns.integer
-patterns.oct=zero*octdigit^1
-patterns.octal=patterns.oct
-patterns.HEX=zero*P("X")*(digit+uppercase)^1
-patterns.hex=zero*P("x")*(digit+lowercase)^1
-patterns.hexadecimal=zero*S("xX")*hexdigit^1
-patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigit^1+hexdigit^1*period*hexdigit^0+hexdigit^1)*(S("pP")*sign^-1*hexdigit^1)^-1
-patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^1)*S("eE")*sign^-1*digit^1
-patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
+patterns.propername=R("AZ","az","__")*R("09","AZ","az","__")^0*P(-1)
patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
-patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0))
+patterns.longtostring=Cs(whitespace^0/""*nonwhitespace^0*((whitespace^0/" "*(patterns.quoted+nonwhitespace)^1)^0))
local function anywhere(pattern)
return P { P(pattern)+1*V(1) }
end
@@ -395,7 +372,7 @@ function lpeg.replacer(one,two,makefunction,isutf)
return pattern
end
end
-function lpeg.finder(lst,makefunction)
+function lpeg.finder(lst,makefunction)
local pattern
if type(lst)=="table" then
pattern=P(false)
@@ -424,8 +401,8 @@ local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
local splitter=splitters_f[separator]
if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)
+ separator=P(separator)
+ splitter=C((1-separator)^0)
splitters_f[separator]=splitter
end
return splitter
@@ -433,31 +410,12 @@ end
function lpeg.secondofsplit(separator)
local splitter=splitters_s[separator]
if not splitter then
- local pattern=P(separator)
- splitter=(1-pattern)^0*pattern*C(anything^0)
- splitters_s[separator]=splitter
- end
- return splitter
-end
-local splitters_s,splitters_p={},{}
-function lpeg.beforesuffix(separator)
- local splitter=splitters_s[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=C((1-pattern)^0)*pattern*endofstring
+ separator=P(separator)
+ splitter=(1-separator)^0*separator*C(anything^0)
splitters_s[separator]=splitter
end
return splitter
end
-function lpeg.afterprefix(separator)
- local splitter=splitters_p[separator]
- if not splitter then
- local pattern=P(separator)
- splitter=pattern*C(anything^0)
- splitters_p[separator]=splitter
- end
- return splitter
-end
function lpeg.balancer(left,right)
left,right=P(left),P(right)
return P { left*((1-left-right)+V(1))^0*right }
@@ -689,6 +647,9 @@ end
function lpeg.times(pattern,n)
return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
+local digit=R("09")
+local period=P(".")
+local zero=P("0")
local trailingzeros=zero^0*-digit
local case_1=period*trailingzeros/""
local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"")
@@ -1076,7 +1037,6 @@ local noquotes,hexify,handle,reduce,compact,inline,functions
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
}
local function simple_table(t)
if #t>0 then
@@ -1096,12 +1056,12 @@ local function simple_table(t)
else
tt[nt]=tostring(v)
end
+ elseif tv=="boolean" then
+ nt=nt+1
+ tt[nt]=tostring(v)
elseif tv=="string" then
nt=nt+1
tt[nt]=format("%q",v)
- elseif tv=="boolean" then
- nt=nt+1
- tt[nt]=v and "true" or "false"
else
tt=nil
break
@@ -1134,7 +1094,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s[%q]={",depth,name))
end
elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,name and "true" or "false"))
+ handle(format("%s[%s]={",depth,tostring(name)))
else
handle(format("%s{",depth))
end
@@ -1158,21 +1118,21 @@ local function do_serialize(root,name,depth,level,indexed)
for i=1,#sk do
local k=sk[i]
local v=root[k]
- local tv,tk=type(v),type(k)
+ local t,tk=type(v),type(k)
if compact and first and tk=="number" and k>=first and k<=last then
- if tv=="number" then
+ if t=="number" then
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
handle(format("%s %s,",depth,v))
end
- elseif tv=="string" then
+ elseif t=="string" then
if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
end
- elseif tv=="table" then
+ elseif t=="table" then
if not next(v) then
handle(format("%s {},",depth))
elseif inline then
@@ -1185,11 +1145,11 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1,true)
end
- elseif tv=="boolean" then
- handle(format("%s %s,",depth,v and "true" or "false"))
- elseif tv=="function" then
+ elseif t=="boolean" then
+ handle(format("%s %s,",depth,tostring(v)))
+ elseif t=="function" then
if functions then
- handle(format('%s load(%q),',depth,dump(v)))
+ handle(format('%s load(%q),',depth,dump(v)))
else
handle(format('%s "function",',depth))
end
@@ -1200,7 +1160,7 @@ local function do_serialize(root,name,depth,level,indexed)
if false then
handle(format("%s __p__=nil,",depth))
end
- elseif tv=="number" then
+ elseif t=="number" then
if tk=="number" then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
@@ -1209,9 +1169,9 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tk=="boolean" then
if hexify then
- handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v))
+ handle(format("%s [%s]=0x%04X,",depth,tostring(k),v))
else
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ handle(format("%s [%s]=%s,",depth,tostring(k),v))
end
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
@@ -1226,7 +1186,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]=%s,",depth,k,v))
end
end
- elseif tv=="string" then
+ elseif t=="string" then
if reduce and tonumber(v) then
if tk=="number" then
if hexify then
@@ -1235,7 +1195,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ handle(format("%s [%s]=%s,",depth,tostring(k),v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%s,",depth,k,v))
else
@@ -1249,14 +1209,14 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,v))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ handle(format("%s [%s]=%q,",depth,tostring(k),v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s [%q]=%q,",depth,k,v))
end
end
- elseif tv=="table" then
+ elseif t=="table" then
if not next(v) then
if tk=="number" then
if hexify then
@@ -1265,7 +1225,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={},",depth,k))
end
elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,k and "true" or "false"))
+ handle(format("%s [%s]={},",depth,tostring(k)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={},",depth,k))
else
@@ -1281,7 +1241,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
+ handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", ")))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
else
@@ -1293,21 +1253,21 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1)
end
- elseif tv=="boolean" then
+ elseif t=="boolean" then
if tk=="number" then
if hexify then
- handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false"))
+ handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
else
- handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
+ handle(format("%s [%s]=%s,",depth,k,tostring(v)))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
+ handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
+ handle(format("%s %s=%s,",depth,k,tostring(v)))
else
- handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
+ handle(format("%s [%q]=%s,",depth,k,tostring(v)))
end
- elseif tv=="function" then
+ elseif t=="function" then
if functions then
local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
if tk=="number" then
@@ -1317,7 +1277,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=load(%q),",depth,k,f))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
+ handle(format("%s [%s]=load(%q),",depth,tostring(k),f))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=load(%q),",depth,k,f))
else
@@ -1332,7 +1292,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
+ handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,tostring(v)))
else
@@ -1702,7 +1662,6 @@ local function readall(f)
return f:read('*all')
else
local done=f:seek("set",0)
- local step
if size<1024*1024 then
step=1024*1024
elseif size>16*1024*1024 then
@@ -2226,24 +2185,17 @@ end
function file.joinpath(tab,separator)
return tab and concat(tab,separator or io.pathseparator)
end
-local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
-local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon
+local isnetwork=fwslash*fwslash*(1-fwslash)+(1-fwslash-colon)^1*colon
local isroot=fwslash^1*-1
local hasroot=fwslash^1
-local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(...)
local lst={... }
local one=lst[1]
if lpegmatch(isnetwork,one) then
- local one=lpegmatch(reslasher,one)
local two=lpegmatch(deslasher,concat(lst,"/",2))
- if lpegmatch(hasroot,two) then
- return one..two
- else
- return one.."/"..two
- end
+ return one.."/"..two
elseif lpegmatch(isroot,one) then
local two=lpegmatch(deslasher,concat(lst,"/",2))
if lpegmatch(hasroot,two) then
@@ -2260,9 +2212,7 @@ end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
local untouched=periods+(1-period)^1*P(-1)
-local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0)
-local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
-local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
+local splitstarter=(Cs(drivespec*(bwslash/"/"+fwslash)^0)+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
if not str then
@@ -2425,9 +2375,9 @@ function string.booleanstring(str)
end
function string.is_boolean(str,default)
if type(str)=="string" then
- if str=="true" or str=="yes" or str=="on" or str=="t" or str=="1" then
+ if str=="true" or str=="yes" or str=="on" or str=="t" then
return true
- elseif str=="false" or str=="no" or str=="off" or str=="f" or str=="0" then
+ elseif str=="false" or str=="no" or str=="off" or str=="f" then
return false
end
end
@@ -2630,7 +2580,6 @@ local tracedchar = string.tracedchar
local autosingle = string.autosingle
local autodouble = string.autodouble
local sequenced = table.sequenced
-local formattednumber = number.formatted
]]
local template=[[
%s
@@ -2645,7 +2594,7 @@ setmetatable(arguments,{ __index=function(t,k)
end
})
local prefix_any=C((S("+- .")+R("09"))^0)
-local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0)
+local prefix_tab=C((1-R("az","AZ","09","%%"))^0)
local format_s=function(f)
n=n+1
if f and f~="" then
@@ -2675,7 +2624,7 @@ local format_i=function(f)
if f and f~="" then
return format("format('%%%si',a%s)",f,n)
else
- return format("format('%%i',a%s)",n)
+ return format("a%s",n)
end
end
local format_d=format_i
@@ -2827,39 +2776,6 @@ end
local format_W=function(f)
return format("nspaces[%s]",tonumber(f) or 0)
end
-local digit=patterns.digit
-local period=patterns.period
-local three=digit*digit*digit
-local splitter=Cs (
- (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2)
-)
-patterns.formattednumber=splitter
-function number.formatted(n,sep1,sep2)
- local s=type(s)=="string" and n or format("%0.2f",n)
- if sep1==true then
- return lpegmatch(splitter,s,1,".",",")
- elseif sep1=="." then
- return lpegmatch(splitter,s,1,sep1,sep2 or ",")
- elseif sep1=="," then
- return lpegmatch(splitter,s,1,sep1,sep2 or ".")
- else
- return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".")
- end
-end
-local format_m=function(f)
- n=n+1
- if not f or f=="" then
- f=","
- end
- return format([[formattednumber(a%s,%q,".")]],n,f)
-end
-local format_M=function(f)
- n=n+1
- if not f or f=="" then
- f="."
- end
- return format([[formattednumber(a%s,%q,",")]],n,f)
-end
local format_rest=function(s)
return format("%q",s)
end
@@ -2897,8 +2813,7 @@ local builder=Cs { "start",
+V("w")
+V("W")
+V("a")
-+V("A")
-+V("m")+V("M")
++V("A")
+V("*")
)+V("*")
)*(P(-1)+Carg(1))
@@ -2929,16 +2844,14 @@ local builder=Cs { "start",
["b"]=(prefix_any*P("b"))/format_b,
["t"]=(prefix_tab*P("t"))/format_t,
["T"]=(prefix_tab*P("T"))/format_T,
- ["l"]=(prefix_any*P("l"))/format_l,
- ["L"]=(prefix_any*P("L"))/format_L,
+ ["l"]=(prefix_tab*P("l"))/format_l,
+ ["L"]=(prefix_tab*P("L"))/format_L,
["I"]=(prefix_any*P("I"))/format_I,
["w"]=(prefix_any*P("w"))/format_w,
["W"]=(prefix_any*P("W"))/format_W,
- ["m"]=(prefix_tab*P("m"))/format_m,
- ["M"]=(prefix_tab*P("M"))/format_M,
["a"]=(prefix_any*P("a"))/format_a,
["A"]=(prefix_any*P("A"))/format_A,
- ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest,
+ ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%%%")^1)/format_rest,
["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension,
}
local direct=Cs (
@@ -2984,13 +2897,10 @@ local function add(t,name,template,preamble)
end
end
strings.formatters.add=add
-patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
-patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
-patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
+lpeg.patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
+lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]])
add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]])
-add(formatters,"lua",[[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]])
end -- closure
@@ -3069,7 +2979,6 @@ local remapper={
fea="font feature files",
pfa="type1 fonts",
pfb="type1 fonts",
- afm="afm",
}
function resolvers.findfile(name,fileformat)
name=string.gsub(name,"\\","/")
@@ -3088,10 +2997,6 @@ function resolvers.findfile(name,fileformat)
return found
end
resolvers.findbinfile=resolvers.findfile
-function resolvers.loadbinfile(filename,filetype)
- local data=io.loaddata(filename)
- return true,data,#data
-end
function resolvers.resolve(s)
return s
end
@@ -3107,20 +3012,11 @@ if not caches.namespace or caches.namespace=="" or caches.namespace=="context" t
end
do
local cachepaths=kpse.expand_var('$TEXMFCACHE') or ""
- if cachepaths=="" or cachepaths=="$TEXMFCACHE" then
+ if cachepaths=="" then
cachepaths=kpse.expand_var('$TEXMFVAR') or ""
end
- if cachepaths=="" or cachepaths=="$TEXMFVAR" then
- cachepaths=kpse.expand_var('$VARTEXMF') or ""
- end
if cachepaths=="" then
- local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
- for i=1,#fallbacks do
- cachepaths=os.getenv(fallbacks[i]) or ""
- if cachepath~="" and lfs.isdir(cachepath) then
- break
- end
- end
+ cachepaths=kpse.expand_var('$VARTEXMF') or ""
end
if cachepaths=="" then
cachepaths="."
@@ -3215,7 +3111,7 @@ function caches.savedata(path,name,data)
local luaname,lucname=makefullname(path,name)
if luaname then
texio.write(string.format("(save: %s)",luaname))
- table.tofile(luaname,data,true)
+ table.tofile(luaname,data,true,{ reduce=true })
if lucname and type(caches.compile)=="function" then
os.remove(lucname)
texio.write(string.format("(save: %s)",lucname))
@@ -3427,63 +3323,18 @@ end
function nodes.delete(head,current)
return nodes.remove(head,current,true)
end
+nodes.before=node.insert_before
+nodes.after=node.insert_after
function nodes.pool.kern(k)
local n=new_node("kern",1)
n.kern=k
return n
end
-local getfield=node.getfield or function(n,tag) return n[tag] end
-local setfield=node.setfield or function(n,tag,value) n[tag]=value end
-nodes.getfield=getfield
-nodes.setfield=setfield
-nodes.getattr=getfield
-nodes.setattr=setfield
-if node.getid then nodes.getid=node.getid else function nodes.getid (n) return getfield(n,"id") end end
-if node.getsubtype then nodes.getsubtype=node.getsubtype else function nodes.getsubtype(n) return getfield(n,"subtype") end end
-if node.getnext then nodes.getnext=node.getnext else function nodes.getnext (n) return getfield(n,"next") end end
-if node.getprev then nodes.getprev=node.getprev else function nodes.getprev (n) return getfield(n,"prev") end end
-if node.getchar then nodes.getchar=node.getchar else function nodes.getchar (n) return getfield(n,"char") end end
-if node.getfont then nodes.getfont=node.getfont else function nodes.getfont (n) return getfield(n,"font") end end
-if node.getlist then nodes.getlist=node.getlist else function nodes.getlist (n) return getfield(n,"list") end end
-function nodes.tonut (n) return n end
-function nodes.tonode(n) return n end
-nodes.tostring=node.tostring or tostring
-nodes.copy=node.copy
-nodes.copy_list=node.copy_list
-nodes.delete=node.delete
-nodes.dimensions=node.dimensions
-nodes.end_of_math=node.end_of_math
-nodes.flush_list=node.flush_list
-nodes.flush_node=node.flush_node
-nodes.free=node.free
-nodes.insert_after=node.insert_after
-nodes.insert_before=node.insert_before
-nodes.hpack=node.hpack
-nodes.new=node.new
-nodes.tail=node.tail
-nodes.traverse=node.traverse
-nodes.traverse_id=node.traverse_id
-nodes.slide=node.slide
-nodes.vpack=node.vpack
-nodes.first_glyph=node.first_glyph
-nodes.first_character=node.first_character
-nodes.has_glyph=node.has_glyph or node.first_glyph
-nodes.current_attr=node.current_attr
-nodes.do_ligature_n=node.do_ligature_n
-nodes.has_field=node.has_field
-nodes.last_node=node.last_node
-nodes.usedlist=node.usedlist
-nodes.protrusion_skippable=node.protrusion_skippable
-nodes.write=node.write
-nodes.has_attribute=node.has_attribute
-nodes.set_attribute=node.set_attribute
-nodes.unset_attribute=node.unset_attribute
-nodes.protect_glyphs=node.protect_glyphs
-nodes.unprotect_glyphs=node.unprotect_glyphs
-nodes.kerning=node.kerning
-nodes.ligaturing=node.ligaturing
-nodes.mlist_to_hlist=node.mlist_to_hlist
-nodes.nuts=nodes
+function nodes.endofmath(n)
+ for n in traverse_id(math_code,n.next) do
+ return n
+ end
+end
end -- closure
@@ -3727,7 +3578,6 @@ function constructors.scale(tfmdata,specification)
if tonumber(specification) then
specification={ size=specification }
end
- target.specification=specification
local scaledpoints=specification.size
local relativeid=specification.relativeid
local properties=tfmdata.properties or {}
@@ -3779,7 +3629,7 @@ function constructors.scale(tfmdata,specification)
targetproperties.script=properties.script or "dflt"
targetproperties.mode=properties.mode or "base"
local askedscaledpoints=scaledpoints
- local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification)
+ local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints)
local hdelta=delta
local vdelta=delta
target.designsize=parameters.designsize
@@ -3853,7 +3703,7 @@ function constructors.scale(tfmdata,specification)
end
target.type=isvirtual and "virtual" or "real"
target.postprocessors=tfmdata.postprocessors
- local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt
+ local targetslant=(parameters.slant or parameters[1] or 0)
local targetspace=(parameters.space or parameters[2] or 0)*hdelta
local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta
local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta
@@ -4171,7 +4021,7 @@ function constructors.finalize(tfmdata)
parameters.slantfactor=tfmdata.slant or 0
end
if not parameters.designsize then
- parameters.designsize=tfmdata.designsize or (factors.pt*10)
+ parameters.designsize=tfmdata.designsize or 655360
end
if not parameters.units then
parameters.units=tfmdata.units_per_em or 1000
@@ -4295,11 +4145,11 @@ function constructors.hashinstance(specification,force)
size=math.round(constructors.scaled(size,designsizes[hash]))
specification.size=size
end
- if fallbacks then
- return hash..' @ '..tostring(size)..' @ '..fallbacks
- else
- return hash..' @ '..tostring(size)
- end
+ if fallbacks then
+ return hash..' @ '..tostring(size)..' @ '..fallbacks
+ else
+ return hash..' @ '..tostring(size)
+ end
end
function constructors.setname(tfmdata,specification)
if constructors.namemode=="specification" then
@@ -4533,8 +4383,7 @@ function constructors.collectprocessors(what,tfmdata,features,trace,report)
local whathandler=handlers[what]
local whatfeatures=whathandler.features
local whatprocessors=whatfeatures.processors
- local mode=properties.mode
- local processors=whatprocessors[mode]
+ local processors=whatprocessors[properties.mode]
if processors then
for i=1,#processors do
local step=processors[i]
@@ -4551,7 +4400,7 @@ function constructors.collectprocessors(what,tfmdata,features,trace,report)
end
end
elseif trace then
- report("no feature processors for mode %a for font %a",mode,properties.fullname)
+ report("no feature processors for mode %a for font %a",mode,tfmdata.properties.fullname)
end
end
return processes
@@ -4562,8 +4411,7 @@ function constructors.applymanipulators(what,tfmdata,features,trace,report)
local whathandler=handlers[what]
local whatfeatures=whathandler.features
local whatmanipulators=whatfeatures.manipulators
- local mode=properties.mode
- local manipulators=whatmanipulators[mode]
+ local manipulators=whatmanipulators[properties.mode]
if manipulators then
for i=1,#manipulators do
local step=manipulators[i]
@@ -4572,7 +4420,7 @@ function constructors.applymanipulators(what,tfmdata,features,trace,report)
if value then
local action=step.action
if trace then
- report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname)
+ report("applying feature manipulator %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname)
end
if action then
action(tfmdata,feature,value)
@@ -4932,38 +4780,33 @@ function mappings.addtounicode(data,filename)
if not unicode or unicode=="" then
local split=lpegmatch(namesplitter,name)
local nsplit=split and #split or 0
- local t,n={},0
- unicode=true
- for l=1,nsplit do
- local base=split[l]
- local u=unicodes[base] or unicodevector[base]
- if not u then
- break
- elseif type(u)=="table" then
- if u[1]>=private then
- unicode=false
+ if nsplit>=2 then
+ local t,n={},0
+ for l=1,nsplit do
+ local base=split[l]
+ local u=unicodes[base] or unicodevector[base]
+ if not u then
break
+ elseif type(u)=="table" then
+ n=n+1
+ t[n]=u[1]
+ else
+ n=n+1
+ t[n]=u
end
- n=n+1
- t[n]=u[1]
+ end
+ if n==0 then
+ elseif n==1 then
+ originals[index]=t[1]
+ tounicode[index]=tounicode16(t[1],name)
else
- if u>=private then
- unicode=false
- break
- end
- n=n+1
- t[n]=u
+ originals[index]=t
+ tounicode[index]=tounicode16sequence(t)
end
- end
- if n==0 then
- elseif n==1 then
- originals[index]=t[1]
- tounicode[index]=tounicode16(t[1],name)
+ nl=nl+1
+ unicode=true
else
- originals[index]=t
- tounicode[index]=tounicode16sequence(t)
end
- nl=nl+1
end
if not unicode or unicode=="" then
local foundcodes,multiple=lpegmatch(uparser,name)
@@ -5074,1104 +4917,6 @@ fonts.names.resolvespec=fonts.names.resolve
function fonts.names.getfilename(askedname,suffix)
return ""
end
-function fonts.names.ignoredfile(filename)
- return true
-end
-
-end -- closure
-
-do -- begin closure to overcome local limits and interference
-
-if not modules then modules={} end modules ['font-tfm']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local next=next
-local match=string.match
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end)
-local report_defining=logs.reporter("fonts","defining")
-local report_tfm=logs.reporter("fonts","tfm loading")
-local findbinfile=resolvers.findbinfile
-local fonts=fonts
-local handlers=fonts.handlers
-local readers=fonts.readers
-local constructors=fonts.constructors
-local encodings=fonts.encodings
-local tfm=constructors.newhandler("tfm")
-local tfmfeatures=constructors.newfeatures("tfm")
-local registertfmfeature=tfmfeatures.register
-constructors.resolvevirtualtoo=false
-fonts.formats.tfm="type1"
-function tfm.setfeatures(tfmdata,features)
- local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm)
- if okay then
- return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm)
- else
- return {}
- end
-end
-local function read_from_tfm(specification)
- local filename=specification.filename
- local size=specification.size
- if trace_defining then
- report_defining("loading tfm file %a at size %s",filename,size)
- end
- local tfmdata=font.read_tfm(filename,size)
- if tfmdata then
- local features=specification.features and specification.features.normal or {}
- local resources=tfmdata.resources or {}
- local properties=tfmdata.properties or {}
- local parameters=tfmdata.parameters or {}
- local shared=tfmdata.shared or {}
- properties.name=tfmdata.name
- properties.fontname=tfmdata.fontname
- properties.psname=tfmdata.psname
- properties.filename=specification.filename
- parameters.size=size
- shared.rawdata={}
- shared.features=features
- shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil
- tfmdata.properties=properties
- tfmdata.resources=resources
- tfmdata.parameters=parameters
- tfmdata.shared=shared
- parameters.slant=parameters.slant or parameters[1] or 0
- parameters.space=parameters.space or parameters[2] or 0
- parameters.space_stretch=parameters.space_stretch or parameters[3] or 0
- parameters.space_shrink=parameters.space_shrink or parameters[4] or 0
- parameters.x_height=parameters.x_height or parameters[5] or 0
- parameters.quad=parameters.quad or parameters[6] or 0
- parameters.extra_space=parameters.extra_space or parameters[7] or 0
- constructors.enhanceparameters(parameters)
- if constructors.resolvevirtualtoo then
- fonts.loggers.register(tfmdata,file.suffix(filename),specification)
- local vfname=findbinfile(specification.name,'ovf')
- if vfname and vfname~="" then
- local vfdata=font.read_vf(vfname,size)
- if vfdata then
- local chars=tfmdata.characters
- for k,v in next,vfdata.characters do
- chars[k].commands=v.commands
- end
- properties.virtualized=true
- tfmdata.fonts=vfdata.fonts
- end
- end
- end
- local allfeatures=tfmdata.shared.features or specification.features.normal
- constructors.applymanipulators("tfm",tfmdata,allfeatures.normal,trace_features,report_tfm)
- if not features.encoding then
- local encoding,filename=match(properties.filename,"^(.-)%-(.*)$")
- if filename and encoding and encodings.known and encodings.known[encoding] then
- features.encoding=encoding
- end
- end
- return tfmdata
- end
-end
-local function check_tfm(specification,fullname)
- local foundname=findbinfile(fullname,'tfm') or ""
- if foundname=="" then
- foundname=findbinfile(fullname,'ofm') or ""
- end
- if foundname=="" then
- foundname=fonts.names.getfilename(fullname,"tfm") or ""
- end
- if foundname~="" then
- specification.filename=foundname
- specification.format="ofm"
- return read_from_tfm(specification)
- elseif trace_defining then
- report_defining("loading tfm with name %a fails",specification.name)
- end
-end
-readers.check_tfm=check_tfm
-function readers.tfm(specification)
- local fullname=specification.filename or ""
- if fullname=="" then
- local forced=specification.forced or ""
- if forced~="" then
- fullname=specification.name.."."..forced
- else
- fullname=specification.name
- end
- end
- return check_tfm(specification,fullname)
-end
-
-end -- closure
-
-do -- begin closure to overcome local limits and interference
-
-if not modules then modules={} end modules ['font-afm']={
- version=1.001,
- comment="companion to font-ini.mkiv",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files"
-}
-local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers
-local next,type,tonumber=next,type,tonumber
-local format,match,gmatch,lower,gsub,strip=string.format,string.match,string.gmatch,string.lower,string.gsub,string.strip
-local abs=math.abs
-local P,S,C,R,lpegmatch,patterns=lpeg.P,lpeg.S,lpeg.C,lpeg.R,lpeg.match,lpeg.patterns
-local derivetable=table.derive
-local trace_features=false trackers.register("afm.features",function(v) trace_features=v end)
-local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end)
-local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end)
-local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end)
-local report_afm=logs.reporter("fonts","afm loading")
-local findbinfile=resolvers.findbinfile
-local definers=fonts.definers
-local readers=fonts.readers
-local constructors=fonts.constructors
-local afm=constructors.newhandler("afm")
-local pfb=constructors.newhandler("pfb")
-local afmfeatures=constructors.newfeatures("afm")
-local registerafmfeature=afmfeatures.register
-afm.version=1.410
-afm.cache=containers.define("fonts","afm",afm.version,true)
-afm.autoprefixed=true
-afm.helpdata={}
-afm.syncspace=true
-afm.addligatures=true
-afm.addtexligatures=true
-afm.addkerns=true
-local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
-local function setmode(tfmdata,value)
- if value then
- tfmdata.properties.mode=lower(value)
- end
-end
-registerafmfeature {
- name="mode",
- description="mode",
- initializers={
- base=setmode,
- node=setmode,
- }
-}
-local comment=P("Comment")
-local spacing=patterns.spacer
-local lineend=patterns.newline
-local words=C((1-lineend)^1)
-local number=C((R("09")+S("."))^1)/tonumber*spacing^0
-local data=lpeg.Carg(1)
-local pattern=(
- comment*spacing*(
- data*(
- ("CODINGSCHEME"*spacing*words )/function(fd,a) end+("DESIGNSIZE"*spacing*number*words )/function(fd,a) fd[ 1]=a end+("CHECKSUM"*spacing*number*words )/function(fd,a) fd[ 2]=a end+("SPACE"*spacing*number*"plus"*number*"minus"*number)/function(fd,a,b,c) fd[ 3],fd[ 4],fd[ 5]=a,b,c end+("QUAD"*spacing*number )/function(fd,a) fd[ 6]=a end+("EXTRASPACE"*spacing*number )/function(fd,a) fd[ 7]=a end+("NUM"*spacing*number*number*number )/function(fd,a,b,c) fd[ 8],fd[ 9],fd[10]=a,b,c end+("DENOM"*spacing*number*number )/function(fd,a,b ) fd[11],fd[12]=a,b end+("SUP"*spacing*number*number*number )/function(fd,a,b,c) fd[13],fd[14],fd[15]=a,b,c end+("SUB"*spacing*number*number )/function(fd,a,b) fd[16],fd[17]=a,b end+("SUPDROP"*spacing*number )/function(fd,a) fd[18]=a end+("SUBDROP"*spacing*number )/function(fd,a) fd[19]=a end+("DELIM"*spacing*number*number )/function(fd,a,b) fd[20],fd[21]=a,b end+("AXISHEIGHT"*spacing*number )/function(fd,a) fd[22]=a end
- )+(1-lineend)^0
- )+(1-comment)^1
-)^0
-local function scan_comment(str)
- local fd={}
- lpegmatch(pattern,str,1,fd)
- return fd
-end
-local keys={}
-function keys.FontName (data,line) data.metadata.fontname=strip (line)
- data.metadata.fullname=strip (line) end
-function keys.ItalicAngle (data,line) data.metadata.italicangle=tonumber (line) end
-function keys.IsFixedPitch(data,line) data.metadata.isfixedpitch=toboolean(line,true) end
-function keys.CharWidth (data,line) data.metadata.charwidth=tonumber (line) end
-function keys.XHeight (data,line) data.metadata.xheight=tonumber (line) end
-function keys.Descender (data,line) data.metadata.descender=tonumber (line) end
-function keys.Ascender (data,line) data.metadata.ascender=tonumber (line) end
-function keys.Comment (data,line)
- line=lower(line)
- local designsize=match(line,"designsize[^%d]*(%d+)")
- if designsize then data.metadata.designsize=tonumber(designsize) end
-end
-local function get_charmetrics(data,charmetrics,vector)
- local characters=data.characters
- local chr,ind={},0
- for k,v in gmatch(charmetrics,"([%a]+) +(.-) *;") do
- if k=='C' then
- v=tonumber(v)
- if v<0 then
- ind=ind+1
- else
- ind=v
- end
- chr={
- index=ind
- }
- elseif k=='WX' then
- chr.width=tonumber(v)
- elseif k=='N' then
- characters[v]=chr
- elseif k=='B' then
- local llx,lly,urx,ury=match(v,"^ *(.-) +(.-) +(.-) +(.-)$")
- chr.boundingbox={ tonumber(llx),tonumber(lly),tonumber(urx),tonumber(ury) }
- elseif k=='L' then
- local plus,becomes=match(v,"^(.-) +(.-)$")
- local ligatures=chr.ligatures
- if ligatures then
- ligatures[plus]=becomes
- else
- chr.ligatures={ [plus]=becomes }
- end
- end
- end
-end
-local function get_kernpairs(data,kernpairs)
- local characters=data.characters
- for one,two,value in gmatch(kernpairs,"KPX +(.-) +(.-) +(.-)\n") do
- local chr=characters[one]
- if chr then
- local kerns=chr.kerns
- if kerns then
- kerns[two]=tonumber(value)
- else
- chr.kerns={ [two]=tonumber(value) }
- end
- end
- end
-end
-local function get_variables(data,fontmetrics)
- for key,rest in gmatch(fontmetrics,"(%a+) *(.-)[\n\r]") do
- local keyhandler=keys[key]
- if keyhandler then
- keyhandler(data,rest)
- end
- end
-end
-local function get_indexes(data,pfbname)
- data.resources.filename=resolvers.unresolve(pfbname)
- local pfbblob=fontloader.open(pfbname)
- if pfbblob then
- local characters=data.characters
- local pfbdata=fontloader.to_table(pfbblob)
- if pfbdata then
- local glyphs=pfbdata.glyphs
- if glyphs then
- if trace_loading then
- report_afm("getting index data from %a",pfbname)
- end
- for index,glyph in next,glyphs do
- local name=glyph.name
- if name then
- local char=characters[name]
- if char then
- if trace_indexing then
- report_afm("glyph %a has index %a",name,index)
- end
- char.index=index
- end
- end
- end
- elseif trace_loading then
- report_afm("no glyph data in pfb file %a",pfbname)
- end
- elseif trace_loading then
- report_afm("no data in pfb file %a",pfbname)
- end
- fontloader.close(pfbblob)
- elseif trace_loading then
- report_afm("invalid pfb file %a",pfbname)
- end
-end
-local function readafm(filename)
- local ok,afmblob,size=resolvers.loadbinfile(filename)
- if ok and afmblob then
- local data={
- resources={
- filename=resolvers.unresolve(filename),
- version=afm.version,
- creator="context mkiv",
- },
- properties={
- hasitalics=false,
- },
- goodies={},
- metadata={
- filename=file.removesuffix(file.basename(filename))
- },
- characters={
- },
- descriptions={
- },
- }
- afmblob=gsub(afmblob,"StartCharMetrics(.-)EndCharMetrics",function(charmetrics)
- if trace_loading then
- report_afm("loading char metrics")
- end
- get_charmetrics(data,charmetrics,vector)
- return ""
- end)
- afmblob=gsub(afmblob,"StartKernPairs(.-)EndKernPairs",function(kernpairs)
- if trace_loading then
- report_afm("loading kern pairs")
- end
- get_kernpairs(data,kernpairs)
- return ""
- end)
- afmblob=gsub(afmblob,"StartFontMetrics%s+([%d%.]+)(.-)EndFontMetrics",function(version,fontmetrics)
- if trace_loading then
- report_afm("loading variables")
- end
- data.afmversion=version
- get_variables(data,fontmetrics)
- data.fontdimens=scan_comment(fontmetrics)
- return ""
- end)
- return data
- else
- if trace_loading then
- report_afm("no valid afm file %a",filename)
- end
- return nil
- end
-end
-local addkerns,addligatures,addtexligatures,unify,normalize
-function afm.load(filename)
- filename=resolvers.findfile(filename,'afm') or ""
- if filename~="" and not fonts.names.ignoredfile(filename) then
- local name=file.removesuffix(file.basename(filename))
- local data=containers.read(afm.cache,name)
- local attr=lfs.attributes(filename)
- local size,time=attr.size or 0,attr.modification or 0
- local pfbfile=file.replacesuffix(name,"pfb")
- local pfbname=resolvers.findfile(pfbfile,"pfb") or ""
- if pfbname=="" then
- pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or ""
- end
- local pfbsize,pfbtime=0,0
- if pfbname~="" then
- local attr=lfs.attributes(pfbname)
- pfbsize=attr.size or 0
- pfbtime=attr.modification or 0
- end
- if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then
- report_afm("reading %a",filename)
- data=readafm(filename)
- if data then
- if pfbname~="" then
- get_indexes(data,pfbname)
- elseif trace_loading then
- report_afm("no pfb file for %a",filename)
- end
- report_afm("unifying %a",filename)
- unify(data,filename)
- if afm.addligatures then
- report_afm("add ligatures")
- addligatures(data)
- end
- if afm.addtexligatures then
- report_afm("add tex ligatures")
- addtexligatures(data)
- end
- if afm.addkerns then
- report_afm("add extra kerns")
- addkerns(data)
- end
- normalize(data)
- report_afm("add tounicode data")
- fonts.mappings.addtounicode(data,filename)
- data.size=size
- data.time=time
- data.pfbsize=pfbsize
- data.pfbtime=pfbtime
- report_afm("saving %a in cache",name)
- data=containers.write(afm.cache,name,data)
- data=containers.read(afm.cache,name)
- end
- if applyruntimefixes and data then
- applyruntimefixes(filename,data)
- end
- end
- return data
- else
- return nil
- end
-end
-local uparser=fonts.mappings.makenameparser()
-unify=function(data,filename)
- local unicodevector=fonts.encodings.agl.unicodes
- local unicodes,names={},{}
- local private=constructors.privateoffset
- local descriptions=data.descriptions
- for name,blob in next,data.characters do
- local code=unicodevector[name]
- if not code then
- code=lpegmatch(uparser,name)
- if not code then
- code=private
- private=private+1
- report_afm("assigning private slot %U for unknown glyph name %a",code,name)
- end
- end
- local index=blob.index
- unicodes[name]=code
- names[name]=index
- blob.name=name
- descriptions[code]={
- boundingbox=blob.boundingbox,
- width=blob.width,
- kerns=blob.kerns,
- index=index,
- name=name,
- }
- end
- for unicode,description in next,descriptions do
- local kerns=description.kerns
- if kerns then
- local krn={}
- for name,kern in next,kerns do
- local unicode=unicodes[name]
- if unicode then
- krn[unicode]=kern
- else
- print(unicode,name)
- end
- end
- description.kerns=krn
- end
- end
- data.characters=nil
- local resources=data.resources
- local filename=resources.filename or file.removesuffix(file.basename(filename))
- resources.filename=resolvers.unresolve(filename)
- resources.unicodes=unicodes
- resources.marks={}
- resources.names=names
- resources.private=private
-end
-normalize=function(data)
-end
-local addthem=function(rawdata,ligatures)
- if ligatures then
- local descriptions=rawdata.descriptions
- local resources=rawdata.resources
- local unicodes=resources.unicodes
- local names=resources.names
- for ligname,ligdata in next,ligatures do
- local one=descriptions[unicodes[ligname]]
- if one then
- for _,pair in next,ligdata do
- local two,three=unicodes[pair[1]],unicodes[pair[2]]
- if two and three then
- local ol=one.ligatures
- if ol then
- if not ol[two] then
- ol[two]=three
- end
- else
- one.ligatures={ [two]=three }
- end
- end
- end
- end
- end
- end
-end
-addligatures=function(rawdata) addthem(rawdata,afm.helpdata.ligatures ) end
-addtexligatures=function(rawdata) addthem(rawdata,afm.helpdata.texligatures) end
-addkerns=function(rawdata)
- local descriptions=rawdata.descriptions
- local resources=rawdata.resources
- local unicodes=resources.unicodes
- local function do_it_left(what)
- if what then
- for unicode,description in next,descriptions do
- local kerns=description.kerns
- if kerns then
- local extrakerns
- for complex,simple in next,what do
- complex=unicodes[complex]
- simple=unicodes[simple]
- if complex and simple then
- local ks=kerns[simple]
- if ks and not kerns[complex] then
- if extrakerns then
- extrakerns[complex]=ks
- else
- extrakerns={ [complex]=ks }
- end
- end
- end
- end
- if extrakerns then
- description.extrakerns=extrakerns
- end
- end
- end
- end
- end
- local function do_it_copy(what)
- if what then
- for complex,simple in next,what do
- complex=unicodes[complex]
- simple=unicodes[simple]
- if complex and simple then
- local complexdescription=descriptions[complex]
- if complexdescription then
- local simpledescription=descriptions[complex]
- if simpledescription then
- local extrakerns
- local kerns=simpledescription.kerns
- if kerns then
- for unicode,kern in next,kerns do
- if extrakerns then
- extrakerns[unicode]=kern
- else
- extrakerns={ [unicode]=kern }
- end
- end
- end
- local extrakerns=simpledescription.extrakerns
- if extrakerns then
- for unicode,kern in next,extrakerns do
- if extrakerns then
- extrakerns[unicode]=kern
- else
- extrakerns={ [unicode]=kern }
- end
- end
- end
- if extrakerns then
- complexdescription.extrakerns=extrakerns
- end
- end
- end
- end
- end
- end
- end
- do_it_left(afm.helpdata.leftkerned)
- do_it_left(afm.helpdata.bothkerned)
- do_it_copy(afm.helpdata.bothkerned)
- do_it_copy(afm.helpdata.rightkerned)
-end
-local function adddimensions(data)
- if data then
- for unicode,description in next,data.descriptions do
- local bb=description.boundingbox
- if bb then
- local ht,dp=bb[4],-bb[2]
- if ht==0 or ht<0 then
- else
- description.height=ht
- end
- if dp==0 or dp<0 then
- else
- description.depth=dp
- end
- end
- end
- end
-end
-local function copytotfm(data)
- if data and data.descriptions then
- local metadata=data.metadata
- local resources=data.resources
- local properties=derivetable(data.properties)
- local descriptions=derivetable(data.descriptions)
- local goodies=derivetable(data.goodies)
- local characters={}
- local parameters={}
- local unicodes=resources.unicodes
- for unicode,description in next,data.descriptions do
- characters[unicode]={}
- end
- local filename=constructors.checkedfilename(resources)
- local fontname=metadata.fontname or metadata.fullname
- local fullname=metadata.fullname or metadata.fontname
- local endash=unicodes['space']
- local emdash=unicodes['emdash']
- local spacer="space"
- local spaceunits=500
- local monospaced=metadata.isfixedpitch
- local charwidth=metadata.charwidth
- local italicangle=metadata.italicangle
- local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight
- properties.monospaced=monospaced
- parameters.italicangle=italicangle
- parameters.charwidth=charwidth
- parameters.charxheight=charxheight
- if properties.monospaced then
- if descriptions[endash] then
- spaceunits,spacer=descriptions[endash].width,"space"
- end
- if not spaceunits and descriptions[emdash] then
- spaceunits,spacer=descriptions[emdash].width,"emdash"
- end
- if not spaceunits and charwidth then
- spaceunits,spacer=charwidth,"charwidth"
- end
- else
- if descriptions[endash] then
- spaceunits,spacer=descriptions[endash].width,"space"
- end
- if not spaceunits and charwidth then
- spaceunits,spacer=charwidth,"charwidth"
- end
- end
- spaceunits=tonumber(spaceunits)
- if spaceunits<200 then
- end
- parameters.slant=0
- parameters.space=spaceunits
- parameters.space_stretch=500
- parameters.space_shrink=333
- parameters.x_height=400
- parameters.quad=1000
- if italicangle and italicangle~=0 then
- parameters.italicangle=italicangle
- parameters.italicfactor=math.cos(math.rad(90+italicangle))
- parameters.slant=- math.tan(italicangle*math.pi/180)
- end
- if monospaced then
- parameters.space_stretch=0
- parameters.space_shrink=0
- elseif afm.syncspace then
- parameters.space_stretch=spaceunits/2
- parameters.space_shrink=spaceunits/3
- end
- parameters.extra_space=parameters.space_shrink
- if charxheight then
- parameters.x_height=charxheight
- else
- local x=unicodes['x']
- if x then
- local x=descriptions[x]
- if x then
- parameters.x_height=x.height
- end
- end
- end
- local fd=data.fontdimens
- if fd and fd[8] and fd[9] and fd[10] then
- for k,v in next,fd do
- parameters[k]=v
- end
- end
- parameters.designsize=(metadata.designsize or 10)*65536
- parameters.ascender=abs(metadata.ascender or 0)
- parameters.descender=abs(metadata.descender or 0)
- parameters.units=1000
- properties.spacer=spacer
- properties.encodingbytes=2
- properties.format=fonts.formats[filename] or "type1"
- properties.filename=filename
- properties.fontname=fontname
- properties.fullname=fullname
- properties.psname=fullname
- properties.name=filename or fullname or fontname
- if next(characters) then
- return {
- characters=characters,
- descriptions=descriptions,
- parameters=parameters,
- resources=resources,
- properties=properties,
- goodies=goodies,
- }
- end
- end
- return nil
-end
-function afm.setfeatures(tfmdata,features)
- local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
- if okay then
- return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm)
- else
- return {}
- end
-end
-local function checkfeatures(specification)
-end
-local function afmtotfm(specification)
- local afmname=specification.filename or specification.name
- if specification.forced=="afm" or specification.format=="afm" then
- if trace_loading then
- report_afm("forcing afm format for %a",afmname)
- end
- else
- local tfmname=findbinfile(afmname,"ofm") or ""
- if tfmname~="" then
- if trace_loading then
- report_afm("fallback from afm to tfm for %a",afmname)
- end
- return
- end
- end
- if afmname~="" then
- local features=constructors.checkedfeatures("afm",specification.features.normal)
- specification.features.normal=features
- constructors.hashinstance(specification,true)
- specification=definers.resolve(specification)
- local cache_id=specification.hash
- local tfmdata=containers.read(constructors.cache,cache_id)
- if not tfmdata then
- local rawdata=afm.load(afmname)
- if rawdata and next(rawdata) then
- adddimensions(rawdata)
- tfmdata=copytotfm(rawdata)
- if tfmdata and next(tfmdata) then
- local shared=tfmdata.shared
- if not shared then
- shared={}
- tfmdata.shared=shared
- end
- shared.rawdata=rawdata
- shared.features=features
- shared.processes=afm.setfeatures(tfmdata,features)
- end
- elseif trace_loading then
- report_afm("no (valid) afm file found with name %a",afmname)
- end
- tfmdata=containers.write(constructors.cache,cache_id,tfmdata)
- end
- return tfmdata
- end
-end
-local function read_from_afm(specification)
- local tfmdata=afmtotfm(specification)
- if tfmdata then
- tfmdata.properties.name=specification.name
- tfmdata=constructors.scale(tfmdata,specification)
- local allfeatures=tfmdata.shared.features or specification.features.normal
- constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm)
- fonts.loggers.register(tfmdata,'afm',specification)
- end
- return tfmdata
-end
-local function prepareligatures(tfmdata,ligatures,value)
- if value then
- local descriptions=tfmdata.descriptions
- for unicode,character in next,tfmdata.characters do
- local description=descriptions[unicode]
- local dligatures=description.ligatures
- if dligatures then
- local cligatures=character.ligatures
- if not cligatures then
- cligatures={}
- character.ligatures=cligatures
- end
- for unicode,ligature in next,dligatures do
- cligatures[unicode]={
- char=ligature,
- type=0
- }
- end
- end
- end
- end
-end
-local function preparekerns(tfmdata,kerns,value)
- if value then
- local rawdata=tfmdata.shared.rawdata
- local resources=rawdata.resources
- local unicodes=resources.unicodes
- local descriptions=tfmdata.descriptions
- for u,chr in next,tfmdata.characters do
- local d=descriptions[u]
- local newkerns=d[kerns]
- if newkerns then
- local kerns=chr.kerns
- if not kerns then
- kerns={}
- chr.kerns=kerns
- end
- for k,v in next,newkerns do
- local uk=unicodes[k]
- if uk then
- kerns[uk]=v
- end
- end
- end
- end
- end
-end
-local list={
- [0x0027]=0x2019,
-}
-local function texreplacements(tfmdata,value)
- local descriptions=tfmdata.descriptions
- local characters=tfmdata.characters
- for k,v in next,list do
- characters [k]=characters [v]
- descriptions[k]=descriptions[v]
- end
-end
-local function ligatures (tfmdata,value) prepareligatures(tfmdata,'ligatures',value) end
-local function texligatures(tfmdata,value) prepareligatures(tfmdata,'texligatures',value) end
-local function kerns (tfmdata,value) preparekerns (tfmdata,'kerns',value) end
-local function extrakerns (tfmdata,value) preparekerns (tfmdata,'extrakerns',value) end
-registerafmfeature {
- name="liga",
- description="traditional ligatures",
- initializers={
- base=ligatures,
- node=ligatures,
- }
-}
-registerafmfeature {
- name="kern",
- description="intercharacter kerning",
- initializers={
- base=kerns,
- node=kerns,
- }
-}
-registerafmfeature {
- name="extrakerns",
- description="additional intercharacter kerning",
- initializers={
- base=extrakerns,
- node=extrakerns,
- }
-}
-registerafmfeature {
- name='tlig',
- description='tex ligatures',
- initializers={
- base=texligatures,
- node=texligatures,
- }
-}
-registerafmfeature {
- name='trep',
- description='tex replacements',
- initializers={
- base=texreplacements,
- node=texreplacements,
- }
-}
-local check_tfm=readers.check_tfm
-fonts.formats.afm="type1"
-fonts.formats.pfb="type1"
-local function check_afm(specification,fullname)
- local foundname=findbinfile(fullname,'afm') or ""
- if foundname=="" then
- foundname=fonts.names.getfilename(fullname,"afm") or ""
- end
- if foundname=="" and afm.autoprefixed then
- local encoding,shortname=match(fullname,"^(.-)%-(.*)$")
- if encoding and shortname and fonts.encodings.known[encoding] then
- shortname=findbinfile(shortname,'afm') or ""
- if shortname~="" then
- foundname=shortname
- if trace_defining then
- report_afm("stripping encoding prefix from filename %a",afmname)
- end
- end
- end
- end
- if foundname~="" then
- specification.filename=foundname
- specification.format="afm"
- return read_from_afm(specification)
- end
-end
-function readers.afm(specification,method)
- local fullname,tfmdata=specification.filename or "",nil
- if fullname=="" then
- local forced=specification.forced or ""
- if forced~="" then
- tfmdata=check_afm(specification,specification.name.."."..forced)
- end
- if not tfmdata then
- method=method or definers.method or "afm or tfm"
- if method=="tfm" then
- tfmdata=check_tfm(specification,specification.name)
- elseif method=="afm" then
- tfmdata=check_afm(specification,specification.name)
- elseif method=="tfm or afm" then
- tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name)
- else
- tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name)
- end
- end
- else
- tfmdata=check_afm(specification,fullname)
- end
- return tfmdata
-end
-function readers.pfb(specification,method)
- local original=specification.specification
- if trace_defining then
- report_afm("using afm reader for %a",original)
- end
- specification.specification=gsub(original,"%.pfb",".afm")
- specification.forced="afm"
- return readers.afm(specification,method)
-end
-
-end -- closure
-
-do -- begin closure to overcome local limits and interference
-
-if not modules then modules={} end modules ['font-afk']={
- version=1.001,
- comment="companion to font-afm.lua",
- author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright="PRAGMA ADE / ConTeXt Development Team",
- license="see context related readme files",
- dataonly=true,
-}
-local allocate=utilities.storage.allocate
-fonts.handlers.afm.helpdata={
- ligatures=allocate {
- ['f']={
- { 'f','ff' },
- { 'i','fi' },
- { 'l','fl' },
- },
- ['ff']={
- { 'i','ffi' }
- },
- ['fi']={
- { 'i','fii' }
- },
- ['fl']={
- { 'i','fli' }
- },
- ['s']={
- { 't','st' }
- },
- ['i']={
- { 'j','ij' }
- },
- },
- texligatures=allocate {
- ['quoteleft']={
- { 'quoteleft','quotedblleft' }
- },
- ['quoteright']={
- { 'quoteright','quotedblright' }
- },
- ['hyphen']={
- { 'hyphen','endash' }
- },
- ['endash']={
- { 'hyphen','emdash' }
- }
- },
- leftkerned=allocate {
- AEligature="A",aeligature="a",
- OEligature="O",oeligature="o",
- IJligature="I",ijligature="i",
- AE="A",ae="a",
- OE="O",oe="o",
- IJ="I",ij="i",
- Ssharp="S",ssharp="s",
- },
- rightkerned=allocate {
- AEligature="E",aeligature="e",
- OEligature="E",oeligature="e",
- IJligature="J",ijligature="j",
- AE="E",ae="e",
- OE="E",oe="e",
- IJ="J",ij="j",
- Ssharp="S",ssharp="s",
- },
- bothkerned=allocate {
- Acircumflex="A",acircumflex="a",
- Ccircumflex="C",ccircumflex="c",
- Ecircumflex="E",ecircumflex="e",
- Gcircumflex="G",gcircumflex="g",
- Hcircumflex="H",hcircumflex="h",
- Icircumflex="I",icircumflex="i",
- Jcircumflex="J",jcircumflex="j",
- Ocircumflex="O",ocircumflex="o",
- Scircumflex="S",scircumflex="s",
- Ucircumflex="U",ucircumflex="u",
- Wcircumflex="W",wcircumflex="w",
- Ycircumflex="Y",ycircumflex="y",
- Agrave="A",agrave="a",
- Egrave="E",egrave="e",
- Igrave="I",igrave="i",
- Ograve="O",ograve="o",
- Ugrave="U",ugrave="u",
- Ygrave="Y",ygrave="y",
- Atilde="A",atilde="a",
- Itilde="I",itilde="i",
- Otilde="O",otilde="o",
- Utilde="U",utilde="u",
- Ntilde="N",ntilde="n",
- Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a",
- Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e",
- Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i",
- Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o",
- Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u",
- Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y",
- Aacute="A",aacute="a",
- Cacute="C",cacute="c",
- Eacute="E",eacute="e",
- Iacute="I",iacute="i",
- Lacute="L",lacute="l",
- Nacute="N",nacute="n",
- Oacute="O",oacute="o",
- Racute="R",racute="r",
- Sacute="S",sacute="s",
- Uacute="U",uacute="u",
- Yacute="Y",yacute="y",
- Zacute="Z",zacute="z",
- Dstroke="D",dstroke="d",
- Hstroke="H",hstroke="h",
- Tstroke="T",tstroke="t",
- Cdotaccent="C",cdotaccent="c",
- Edotaccent="E",edotaccent="e",
- Gdotaccent="G",gdotaccent="g",
- Idotaccent="I",idotaccent="i",
- Zdotaccent="Z",zdotaccent="z",
- Amacron="A",amacron="a",
- Emacron="E",emacron="e",
- Imacron="I",imacron="i",
- Omacron="O",omacron="o",
- Umacron="U",umacron="u",
- Ccedilla="C",ccedilla="c",
- Kcedilla="K",kcedilla="k",
- Lcedilla="L",lcedilla="l",
- Ncedilla="N",ncedilla="n",
- Rcedilla="R",rcedilla="r",
- Scedilla="S",scedilla="s",
- Tcedilla="T",tcedilla="t",
- Ohungarumlaut="O",ohungarumlaut="o",
- Uhungarumlaut="U",uhungarumlaut="u",
- Aogonek="A",aogonek="a",
- Eogonek="E",eogonek="e",
- Iogonek="I",iogonek="i",
- Uogonek="U",uogonek="u",
- Aring="A",aring="a",
- Uring="U",uring="u",
- Abreve="A",abreve="a",
- Ebreve="E",ebreve="e",
- Gbreve="G",gbreve="g",
- Ibreve="I",ibreve="i",
- Obreve="O",obreve="o",
- Ubreve="U",ubreve="u",
- Ccaron="C",ccaron="c",
- Dcaron="D",dcaron="d",
- Ecaron="E",ecaron="e",
- Lcaron="L",lcaron="l",
- Ncaron="N",ncaron="n",
- Rcaron="R",rcaron="r",
- Scaron="S",scaron="s",
- Tcaron="T",tcaron="t",
- Zcaron="Z",zcaron="z",
- dotlessI="I",dotlessi="i",
- dotlessJ="J",dotlessj="j",
- AEligature="AE",aeligature="ae",AE="AE",ae="ae",
- OEligature="OE",oeligature="oe",OE="OE",oe="oe",
- IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij",
- Lstroke="L",lstroke="l",Lslash="L",lslash="l",
- Ostroke="O",ostroke="o",Oslash="O",oslash="o",
- Ssharp="SS",ssharp="ss",
- Aumlaut="A",aumlaut="a",
- Eumlaut="E",eumlaut="e",
- Iumlaut="I",iumlaut="i",
- Oumlaut="O",oumlaut="o",
- Uumlaut="U",uumlaut="u",
- }
-}
end -- closure
@@ -6334,7 +5079,7 @@ local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
otf.glists={ "gsub","gpos" }
-otf.version=2.745
+otf.version=2.743
otf.cache=containers.define("fonts","otf",otf.version,true)
local fontdata=fonts.hashes.identifiers
local chardata=characters and characters.data
@@ -6354,28 +5099,17 @@ local packdata=true
local syncspace=true
local forcenotdef=false
local includesubfonts=false
-local overloadkerns=false
-local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes
local wildcard="*"
local default="dflt"
local fontloaderfields=fontloader.fields
local mainfields=nil
local glyphfields=nil
-local formats=fonts.formats
-formats.otf="opentype"
-formats.ttf="truetype"
-formats.ttc="truetype"
-formats.dfont="truetype"
registerdirective("fonts.otf.loader.cleanup",function(v) cleanup=tonumber(v) or (v and 1) or 0 end)
registerdirective("fonts.otf.loader.force",function(v) forceload=v end)
registerdirective("fonts.otf.loader.usemetatables",function(v) usemetatables=v end)
registerdirective("fonts.otf.loader.pack",function(v) packdata=v end)
registerdirective("fonts.otf.loader.syncspace",function(v) syncspace=v end)
registerdirective("fonts.otf.loader.forcenotdef",function(v) forcenotdef=v end)
-registerdirective("fonts.otf.loader.overloadkerns",function(v) overloadkerns=v end)
-local function otf_format(filename)
- return formats[lower(file.suffix(filename))]
-end
local function load_featurefile(raw,featurefile)
if featurefile and featurefile~="" then
if trace_loading then
@@ -6562,7 +5296,7 @@ end
function enhancers.register(what,action)
actions[what]=action
end
-function otf.load(filename,sub,featurefile)
+function otf.load(filename,format,sub,featurefile)
local base=file.basename(file.removesuffix(filename))
local name=file.removesuffix(base)
local attr=lfs.attributes(filename)
@@ -6660,7 +5394,7 @@ function otf.load(filename,sub,featurefile)
data={
size=size,
time=time,
- format=otf_format(filename),
+ format=format,
featuredata=featurefiles,
resources={
filename=resolvers.unresolve(filename),
@@ -6726,9 +5460,6 @@ function otf.load(filename,sub,featurefile)
report_otf("loading from cache using hash %a",hash)
end
enhance("unpack",data,filename,nil,false)
- if applyruntimefixes then
- applyruntimefixes(filename,data)
- end
enhance("add dimensions",data,filename,nil,false)
if trace_sequences then
showfeatureorder(data,filename)
@@ -7659,93 +6390,74 @@ actions["merge kern classes"]=function(data,filename,raw)
local resources=data.resources
local unicodes=resources.unicodes
local splitter=data.helpers.tounicodetable
- local ignored=0
- local blocked=0
for gp=1,#gposlist do
local gpos=gposlist[gp]
local subtables=gpos.subtables
if subtables then
- local first_done={}
- local split={}
for s=1,#subtables do
local subtable=subtables[s]
local kernclass=subtable.kernclass
- local lookup=subtable.lookup or subtable.name
if kernclass then
- if #kernclass>0 then
- kernclass=kernclass[1]
- lookup=type(kernclass.lookup)=="string" and kernclass.lookup or lookup
- report_otf("fixing kernclass table of lookup %a",lookup)
- end
- local firsts=kernclass.firsts
- local seconds=kernclass.seconds
- local offsets=kernclass.offsets
- for n,s in next,firsts do
- split[s]=split[s] or lpegmatch(splitter,s)
- end
- local maxseconds=0
- for n,s in next,seconds do
- if n>maxseconds then
- maxseconds=n
+ local split={}
+ for k=1,#kernclass do
+ local kcl=kernclass[k]
+ local firsts=kcl.firsts
+ local seconds=kcl.seconds
+ local offsets=kcl.offsets
+ local lookups=kcl.lookup
+ if type(lookups)~="table" then
+ lookups={ lookups }
end
- split[s]=split[s] or lpegmatch(splitter,s)
- end
- for fk=1,#firsts do
- local fv=firsts[fk]
- local splt=split[fv]
- if splt then
- local extrakerns={}
- local baseoffset=(fk-1)*maxseconds
- for sk=2,maxseconds do
- local sv=seconds[sk]
- local splt=split[sv]
- if splt then
- local offset=offsets[baseoffset+sk]
- if offset then
- for i=1,#splt do
- extrakerns[splt[i]]=offset
- end
- end
- end
+ for n,s in next,firsts do
+ split[s]=split[s] or lpegmatch(splitter,s)
+ end
+ local maxseconds=0
+ for n,s in next,seconds do
+ if n>maxseconds then
+ maxseconds=n
end
- for i=1,#splt do
- local first_unicode=splt[i]
- if first_done[first_unicode] then
- report_otf("lookup %a: ignoring further kerns of %C",lookup,first_unicode)
- blocked=blocked+1
- else
- first_done[first_unicode]=true
- local description=descriptions[first_unicode]
- if description then
- local kerns=description.kerns
- if not kerns then
- kerns={}
- description.kerns=kerns
- end
- local lookupkerns=kerns[lookup]
- if not lookupkerns then
- lookupkerns={}
- kerns[lookup]=lookupkerns
+ split[s]=split[s] or lpegmatch(splitter,s)
+ end
+ for l=1,#lookups do
+ local lookup=lookups[l]
+ for fk=1,#firsts do
+ local fv=firsts[fk]
+ local splt=split[fv]
+ if splt then
+ local extrakerns={}
+ local baseoffset=(fk-1)*maxseconds
+ for sk=2,maxseconds do
+ local sv=seconds[sk]
+ local splt=split[sv]
+ if splt then
+ local offset=offsets[baseoffset+sk]
+ if offset then
+ for i=1,#splt do
+ extrakerns[splt[i]]=offset
+ end
+ end
end
- if overloadkerns then
- for second_unicode,kern in next,extrakerns do
- lookupkerns[second_unicode]=kern
+ end
+ for i=1,#splt do
+ local first_unicode=splt[i]
+ local description=descriptions[first_unicode]
+ if description then
+ local kerns=description.kerns
+ if not kerns then
+ kerns={}
+ description.kerns=kerns
+ end
+ local lookupkerns=kerns[lookup]
+ if not lookupkerns then
+ lookupkerns={}
+ kerns[lookup]=lookupkerns
end
- else
for second_unicode,kern in next,extrakerns do
- local k=lookupkerns[second_unicode]
- if not k then
- lookupkerns[second_unicode]=kern
- elseif k~=kern then
- if trace_loading then
- report_otf("lookup %a: ignoring overload of kern between %C and %C, rejecting %a, keeping %a",lookup,first_unicode,second_unicode,k,kern)
- end
- ignored=ignored+1
- end
+ lookupkerns[second_unicode]=kern
end
+ elseif trace_loading then
+ report_otf("no glyph data for %U",first_unicode)
end
- elseif trace_loading then
- report_otf("no glyph data for %U",first_unicode)
end
end
end
@@ -7756,12 +6468,6 @@ actions["merge kern classes"]=function(data,filename,raw)
end
end
end
- if ignored>0 then
- report_otf("%s kern overloads ignored",ignored)
- end
- if blocked>0 then
- report_otf("%s succesive kerns blocked",blocked)
- end
end
end
actions["check glyphs"]=function(data,filename,raw)
@@ -7975,19 +6681,10 @@ local function copytotfm(data,cache_id)
end
end
end
- local filename=constructors.checkedfilename(resources)
- local fontname=metadata.fontname
- local fullname=metadata.fullname or fontname
- local units=metadata.units_per_em or 1000
- if units==0 then
- units=1000
- metadata.units_per_em=1000
- report_otf("changing %a units to %a",0,units)
- end
local monospaced=metadata.isfixedpitch or (pfminfo.panose and pfminfo.panose.proportion=="Monospaced")
local charwidth=pfminfo.avgwidth
- local charxheight=pfminfo.os2_xheight and pfminfo.os2_xheight>0 and pfminfo.os2_xheight
local italicangle=metadata.italicangle
+ local charxheight=pfminfo.os2_xheight and pfminfo.os2_xheight>0 and pfminfo.os2_xheight
properties.monospaced=monospaced
parameters.italicangle=italicangle
parameters.charwidth=charwidth
@@ -8016,6 +6713,14 @@ local function copytotfm(data,cache_id)
end
end
spaceunits=tonumber(spaceunits) or 500
+ local filename=constructors.checkedfilename(resources)
+ local fontname=metadata.fontname
+ local fullname=metadata.fullname or fontname
+ local units=metadata.units_per_em or 1000
+ if units==0 then
+ units=1000
+ metadata.units_per_em=1000
+ end
parameters.slant=0
parameters.space=spaceunits
parameters.space_stretch=units/2
@@ -8024,10 +6729,10 @@ local function copytotfm(data,cache_id)
parameters.quad=units
if spaceunits<2*units/5 then
end
- if italicangle and italicangle~=0 then
+ if italicangle then
parameters.italicangle=italicangle
parameters.italicfactor=math.cos(math.rad(90+italicangle))
- parameters.slant=- math.tan(italicangle*math.pi/180)
+ parameters.slant=- math.round(math.tan(italicangle*math.pi/180))
end
if monospaced then
parameters.space_stretch=0
@@ -8054,7 +6759,7 @@ local function copytotfm(data,cache_id)
parameters.units=units
properties.space=spacer
properties.encodingbytes=2
- properties.format=data.format or otf_format(filename) or formats.otf
+ properties.format=data.format or fonts.formats[filename] or "opentype"
properties.noglyphnames=true
properties.filename=filename
properties.fontname=fontname
@@ -8079,8 +6784,9 @@ local function otftotfm(specification)
local name=specification.name
local sub=specification.sub
local filename=specification.filename
+ local format=specification.format
local features=specification.features.normal
- local rawdata=otf.load(filename,sub,features and features.featurefile)
+ local rawdata=otf.load(filename,format,sub,features and features.featurefile)
if rawdata and next(rawdata) then
rawdata.lookuphash={}
tfmdata=copytotfm(rawdata,cache_id)
@@ -8162,33 +6868,41 @@ function otf.collectlookups(rawdata,kind,script,language)
end
return nil,nil
end
-local function check_otf(forced,specification,suffix)
+local function check_otf(forced,specification,suffix,what)
local name=specification.name
if forced then
- name=specification.forcedname
+ name=file.addsuffix(name,suffix,true)
end
local fullname=findbinfile(name,suffix) or ""
if fullname=="" then
fullname=fonts.names.getfilename(name,suffix) or ""
end
- if fullname~="" and not fonts.names.ignoredfile(fullname) then
+ if fullname~="" then
specification.filename=fullname
+ specification.format=what
return read_from_otf(specification)
end
end
-local function opentypereader(specification,suffix)
+local function opentypereader(specification,suffix,what)
local forced=specification.forced or ""
- if formats[forced] then
- return check_otf(true,specification,forced)
+ if forced=="otf" then
+ return check_otf(true,specification,forced,"opentype")
+ elseif forced=="ttf" or forced=="ttc" or forced=="dfont" then
+ return check_otf(true,specification,forced,"truetype")
else
- return check_otf(false,specification,suffix)
+ return check_otf(false,specification,suffix,what)
end
end
-readers.opentype=opentypereader
-function readers.otf (specification) return opentypereader(specification,"otf") end
-function readers.ttf (specification) return opentypereader(specification,"ttf") end
-function readers.ttc (specification) return opentypereader(specification,"ttf") end
-function readers.dfont(specification) return opentypereader(specification,"ttf") end
+readers.opentype=opentypereader
+local formats=fonts.formats
+formats.otf="opentype"
+formats.ttf="truetype"
+formats.ttc="truetype"
+formats.dfont="truetype"
+function readers.otf (specification) return opentypereader(specification,"otf",formats.otf ) end
+function readers.ttf (specification) return opentypereader(specification,"ttf",formats.ttf ) end
+function readers.ttc (specification) return opentypereader(specification,"ttf",formats.ttc ) end
+function readers.dfont(specification) return opentypereader(specification,"ttf",formats.dfont) end
function otf.scriptandlanguage(tfmdata,attr)
local properties=tfmdata.properties
return properties.script or "dflt",properties.language or "dflt"
@@ -8780,24 +7494,11 @@ local injections=nodes.injections
local nodecodes=nodes.nodecodes
local glyph_code=nodecodes.glyph
local kern_code=nodecodes.kern
-local nuts=nodes.nuts
-local nodepool=nuts.pool
+local nodepool=nodes.pool
local newkern=nodepool.kern
-local tonode=nuts.tonode
-local tonut=nuts.tonut
-local getfield=nuts.getfield
-local getnext=nuts.getnext
-local getprev=nuts.getprev
-local getid=nuts.getid
-local getattr=nuts.getattr
-local getfont=nuts.getfont
-local getsubtype=nuts.getsubtype
-local getchar=nuts.getchar
-local setfield=nuts.setfield
-local setattr=nuts.setattr
-local traverse_id=nuts.traverse_id
-local insert_node_before=nuts.insert_before
-local insert_node_after=nuts.insert_after
+local traverse_id=node.traverse_id
+local insert_node_before=node.insert_before
+local insert_node_after=node.insert_after
local a_kernpair=attributes.private('kernpair')
local a_ligacomp=attributes.private('ligacomp')
local a_markbase=attributes.private('markbase')
@@ -8816,21 +7517,21 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne
local dx,dy=factor*(exit[1]-entry[1]),factor*(exit[2]-entry[2])
local ws,wn=tfmstart.width,tfmnext.width
local bound=#cursives+1
- setattr(start,a_cursbase,bound)
- setattr(nxt,a_curscurs,bound)
+ start[a_cursbase]=bound
+ nxt[a_curscurs]=bound
cursives[bound]={ rlmode,dx,dy,ws,wn }
return dx,dy,bound
end
function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr)
local x,y,w,h=factor*spec[1],factor*spec[2],factor*spec[3],factor*spec[4]
if x~=0 or w~=0 or y~=0 or h~=0 then
- local bound=getattr(current,a_kernpair)
+ local bound=current[a_kernpair]
if bound then
local kb=kerns[bound]
kb[2],kb[3],kb[4],kb[5]=(kb[2] or 0)+x,(kb[3] or 0)+y,(kb[4] or 0)+w,(kb[5] or 0)+h
else
bound=#kerns+1
- setattr(current,a_kernpair,bound)
+ current[a_kernpair]=bound
kerns[bound]={ rlmode,x,y,w,h,r2lflag,tfmchr.width }
end
return x,y,w,h,bound
@@ -8841,35 +7542,35 @@ function injections.setkern(current,factor,rlmode,x,tfmchr)
local dx=factor*x
if dx~=0 then
local bound=#kerns+1
- setattr(current,a_kernpair,bound)
+ current[a_kernpair]=bound
kerns[bound]={ rlmode,dx }
return dx,bound
else
return 0,0
end
end
-function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark)
+function injections.setmark(start,base,factor,rlmode,ba,ma,index)
local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2])
- local bound=getattr(base,a_markbase)
+ local bound=base[a_markbase]
local index=1
if bound then
local mb=marks[bound]
if mb then
index=#mb+1
mb[index]={ dx,dy,rlmode }
- setattr(start,a_markmark,bound)
- setattr(start,a_markdone,index)
+ start[a_markmark]=bound
+ start[a_markdone]=index
return dx,dy,bound
else
- report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound)
+ report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound)
end
end
index=index or 1
bound=#marks+1
- setattr(base,a_markbase,bound)
- setattr(start,a_markmark,bound)
- setattr(start,a_markdone,index)
- marks[bound]={ [index]={ dx,dy,rlmode,baseismark } }
+ base[a_markbase]=bound
+ start[a_markmark]=bound
+ start[a_markdone]=index
+ marks[bound]={ [index]={ dx,dy,rlmode } }
return dx,dy,bound
end
local function dir(n)
@@ -8878,15 +7579,15 @@ end
local function trace(head)
report_injections("begin run")
for n in traverse_id(glyph_code,head) do
- if getsubtype(n)<256 then
- local kp=getattr(n,a_kernpair)
- local mb=getattr(n,a_markbase)
- local mm=getattr(n,a_markmark)
- local md=getattr(n,a_markdone)
- local cb=getattr(n,a_cursbase)
- local cc=getattr(n,a_curscurs)
- local char=getchar(n)
- report_injections("font %s, char %U, glyph %c",getfont(n),char,char)
+ if n.subtype<256 then
+ local kp=n[a_kernpair]
+ local mb=n[a_markbase]
+ local mm=n[a_markmark]
+ local md=n[a_markdone]
+ local cb=n[a_cursbase]
+ local cc=n[a_curscurs]
+ local char=n.char
+ report_injections("font %s, char %U, glyph %c",n.font,char,char)
if kp then
local k=kerns[kp]
if k[3] then
@@ -8927,23 +7628,21 @@ local function show_result(head)
local current=head
local skipping=false
while current do
- local id=getid(current)
+ local id=current.id
if id==glyph_code then
- report_injections("char: %C, width %p, xoffset %p, yoffset %p",
- getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset"))
+ report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset)
skipping=false
elseif id==kern_code then
- report_injections("kern: %p",getfield(current,"kern"))
+ report_injections("kern: %p",current.kern)
skipping=false
elseif not skipping then
report_injections()
skipping=true
end
- current=getnext(current)
+ current=current.next
end
end
function injections.handler(head,where,keep)
- head=tonut(head)
local has_marks,has_cursives,has_kerns=next(marks),next(cursives),next(kerns)
if has_marks or has_cursives then
if trace_injections then
@@ -8953,18 +7652,17 @@ function injections.handler(head,where,keep)
if has_kerns then
local nf,tm=nil,nil
for n in traverse_id(glyph_code,head) do
- if getsubtype(n)<256 then
+ if n.subtype<256 then
nofvalid=nofvalid+1
valid[nofvalid]=n
- local f=getfont(n)
- if f~=nf then
- nf=f
- tm=fontdata[nf].resources.marks
+ if n.font~=nf then
+ nf=n.font
+ tm=fontdata[nf].resources.marks
end
if tm then
- mk[n]=tm[getchar(n)]
+ mk[n]=tm[n.char]
end
- local k=getattr(n,a_kernpair)
+ local k=n[a_kernpair]
if k then
local kk=kerns[k]
if kk then
@@ -8984,16 +7682,15 @@ function injections.handler(head,where,keep)
else
local nf,tm=nil,nil
for n in traverse_id(glyph_code,head) do
- if getsubtype(n)<256 then
+ if n.subtype<256 then
nofvalid=nofvalid+1
valid[nofvalid]=n
- local f=getfont(n)
- if f~=nf then
- nf=f
- tm=fontdata[nf].resources.marks
+ if n.font~=nf then
+ nf=n.font
+ tm=fontdata[nf].resources.marks
end
if tm then
- mk[n]=tm[getchar(n)]
+ mk[n]=tm[n.char]
end
end
end
@@ -9002,7 +7699,7 @@ function injections.handler(head,where,keep)
local cx={}
if has_kerns and next(ky) then
for n,k in next,ky do
- setfield(n,"yoffset",k)
+ n.yoffset=k
end
end
if has_cursives then
@@ -9011,9 +7708,9 @@ function injections.handler(head,where,keep)
for i=1,nofvalid do
local n=valid[i]
if not mk[n] then
- local n_cursbase=getattr(n,a_cursbase)
+ local n_cursbase=n[a_cursbase]
if p_cursbase then
- local n_curscurs=getattr(n,a_curscurs)
+ local n_curscurs=n[a_curscurs]
if p_cursbase==n_curscurs then
local c=cursives[n_curscurs]
if c then
@@ -9036,20 +7733,20 @@ function injections.handler(head,where,keep)
end
end
elseif maxt>0 then
- local ny=getfield(n,"yoffset")
+ local ny=n.yoffset
for i=maxt,1,-1 do
ny=ny+d[i]
local ti=t[i]
- setfield(ti,"yoffset",getfield(ti,"yoffset")+ny)
+ ti.yoffset=ti.yoffset+ny
end
maxt=0
end
if not n_cursbase and maxt>0 then
- local ny=getfield(n,"yoffset")
+ local ny=n.yoffset
for i=maxt,1,-1 do
ny=ny+d[i]
local ti=t[i]
- setfield(ti,"yoffset",ny)
+ ti.yoffset=ny
end
maxt=0
end
@@ -9057,11 +7754,11 @@ function injections.handler(head,where,keep)
end
end
if maxt>0 then
- local ny=getfield(n,"yoffset")
+ local ny=n.yoffset
for i=maxt,1,-1 do
ny=ny+d[i]
local ti=t[i]
- setfield(ti,"yoffset",ny)
+ ti.yoffset=ny
end
maxt=0
end
@@ -9072,66 +7769,52 @@ function injections.handler(head,where,keep)
if has_marks then
for i=1,nofvalid do
local p=valid[i]
- local p_markbase=getattr(p,a_markbase)
+ local p_markbase=p[a_markbase]
if p_markbase then
local mrks=marks[p_markbase]
local nofmarks=#mrks
- for n in traverse_id(glyph_code,getnext(p)) do
- local n_markmark=getattr(n,a_markmark)
+ for n in traverse_id(glyph_code,p.next) do
+ local n_markmark=n[a_markmark]
if p_markbase==n_markmark then
- local index=getattr(n,a_markdone) or 1
+ local index=n[a_markdone] or 1
local d=mrks[index]
if d then
local rlmode=d[3]
local k=wx[p]
- local px=getfield(p,"xoffset")
- local ox=0
if k then
local x=k[2]
local w=k[4]
if w then
if rlmode and rlmode>=0 then
- ox=px-getfield(p,"width")+d[1]-(w-x)
+ n.xoffset=p.xoffset-p.width+d[1]-(w-x)
else
- ox=px-d[1]-x
+ n.xoffset=p.xoffset-d[1]-x
end
else
if rlmode and rlmode>=0 then
- ox=px-getfield(p,"width")+d[1]
+ n.xoffset=p.xoffset-p.width+d[1]
else
- ox=px-d[1]-x
+ n.xoffset=p.xoffset-d[1]-x
end
end
else
- local wp=getfield(p,"width")
- local wn=getfield(n,"width")
if rlmode and rlmode>=0 then
- ox=px-wp+d[1]
+ n.xoffset=p.xoffset-p.width+d[1]
else
- ox=px-d[1]
- end
- if wn~=0 then
- insert_node_before(head,n,newkern(-wn/2))
- insert_node_after(head,n,newkern(-wn/2))
+ n.xoffset=p.xoffset-d[1]
end
end
- setfield(n,"xoffset",ox)
- local py=getfield(p,"yoffset")
- local oy=0
if mk[p] then
- oy=py+d[2]
+ n.yoffset=p.yoffset+d[2]
else
- oy=getfield(n,"yoffset")+py+d[2]
+ n.yoffset=n.yoffset+p.yoffset+d[2]
end
- setfield(n,"yoffset",oy)
if nofmarks==1 then
break
else
nofmarks=nofmarks-1
end
end
- elseif not n_markmark then
- break
else
end
end
@@ -9183,7 +7866,6 @@ function injections.handler(head,where,keep)
if not keep then
kerns={}
end
-head=tonode(head)
return head,true
elseif not keep then
kerns,cursives,marks={},{},{}
@@ -9193,14 +7875,14 @@ head=tonode(head)
trace(head)
end
for n in traverse_id(glyph_code,head) do
- if getsubtype(n)<256 then
- local k=getattr(n,a_kernpair)
+ if n.subtype<256 then
+ local k=n[a_kernpair]
if k then
local kk=kerns[k]
if kk then
local rl,x,y,w=kk[1],kk[2] or 0,kk[3],kk[4]
if y and y~=0 then
- setfield(n,"yoffset",y)
+ n.yoffset=y
end
if w then
local wx=w-x
@@ -9231,10 +7913,10 @@ head=tonode(head)
if not keep then
kerns={}
end
- return tonode(head),true
+ return head,true
else
end
- return tonode(head),false
+ return head,false
end
end -- closure
@@ -9262,7 +7944,6 @@ analyzers.useunicodemarks=false
local a_state=attributes.private('state')
local nodecodes=nodes.nodecodes
local glyph_code=nodecodes.glyph
-local disc_code=nodecodes.disc
local math_code=nodecodes.math
local traverse_id=node.traverse_id
local traverse_node_list=node.traverse
@@ -9295,11 +7976,6 @@ local features={
medi=s_medi,
fina=s_fina,
isol=s_isol,
- rphf=s_rphf,
- half=s_half,
- pref=s_pref,
- blwf=s_blwf,
- pstf=s_pstf,
}
analyzers.states=states
analyzers.features=features
@@ -9334,7 +8010,7 @@ function analyzers.setstate(head,font)
first,last,n=nil,nil,0
end
elseif id==disc_code then
- current[a_state]=s_medi
+ current[a_state]=s_midi
last=current
else
if first and first==last then
@@ -9386,7 +8062,7 @@ local function analyzeprocessor(head,font,attr)
end
registerotffeature {
name="analyze",
- description="analysis of character classes",
+ description="analysis of (for instance) character classes",
default=true,
initializers={
node=analyzeinitializer,
@@ -9649,25 +8325,12 @@ registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive")
registertracker("otf.actions","otf.replacements,otf.positions")
registertracker("otf.injections","nodes.injections")
registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing")
-local nuts=nodes.nuts
-local tonode=nuts.tonode
-local tonut=nuts.tonut
-local getfield=nuts.getfield
-local getnext=nuts.getnext
-local getprev=nuts.getprev
-local getid=nuts.getid
-local getattr=nuts.getattr
-local getfont=nuts.getfont
-local getsubtype=nuts.getsubtype
-local getchar=nuts.getchar
-local setfield=nuts.setfield
-local setattr=nuts.setattr
-local insert_node_after=nuts.insert_after
-local delete_node=nuts.delete
-local copy_node=nuts.copy
-local find_node_tail=nuts.tail
-local flush_node_list=nuts.flush_list
-local end_of_math=nuts.end_of_math
+local insert_node_after=node.insert_after
+local delete_node=nodes.delete
+local copy_node=node.copy
+local find_node_tail=node.tail or node.slide
+local flush_node_list=node.flush_list
+local end_of_math=node.end_of_math
local setmetatableindex=table.setmetatableindex
local zwnj=0x200C
local zwj=0x200D
@@ -9676,7 +8339,6 @@ local default="dflt"
local nodecodes=nodes.nodecodes
local whatcodes=nodes.whatcodes
local glyphcodes=nodes.glyphcodes
-local disccodes=nodes.disccodes
local glyph_code=nodecodes.glyph
local glue_code=nodecodes.glue
local disc_code=nodecodes.disc
@@ -9684,7 +8346,6 @@ local whatsit_code=nodecodes.whatsit
local math_code=nodecodes.math
local dir_code=whatcodes.dir
local localpar_code=whatcodes.localpar
-local discretionary_code=disccodes.discretionary
local ligature_code=glyphcodes.ligature
local privateattribute=attributes.private
local a_state=privateattribute('state')
@@ -9778,83 +8439,83 @@ local function pref(kind,lookupname)
return formatters["feature %a, lookup %a"](kind,lookupname)
end
local function copy_glyph(g)
- local components=getfield(g,"components")
+ local components=g.components
if components then
- setfield(g,"components",nil)
+ g.components=nil
local n=copy_node(g)
- setfield(g,"components",components)
+ g.components=components
return n
else
return copy_node(g)
end
end
local function markstoligature(kind,lookupname,head,start,stop,char)
- if start==stop and getchar(start)==char then
+ if start==stop and start.char==char then
return head,start
else
- local prev=getprev(start)
- local next=getnext(stop)
- setfield(start,"prev",nil)
- setfield(stop,"next",nil)
+ local prev=start.prev
+ local next=stop.next
+ start.prev=nil
+ stop.next=nil
local base=copy_glyph(start)
if head==start then
head=base
end
- setfield(base,"char",char)
- setfield(base,"subtype",ligature_code)
- setfield(base,"components",start)
+ base.char=char
+ base.subtype=ligature_code
+ base.components=start
if prev then
- setfield(prev,"next",base)
+ prev.next=base
end
if next then
- setfield(next,"prev",base)
+ next.prev=base
end
- setfield(base,"next",next)
- setfield(base,"prev",prev)
+ base.next=next
+ base.prev=prev
return head,base
end
end
local function getcomponentindex(start)
- if getid(start)~=glyph_code then
+ if start.id~=glyph_code then
return 0
- elseif getsubtype(start)==ligature_code then
+ elseif start.subtype==ligature_code then
local i=0
- local components=getfield(start,"components")
+ local components=start.components
while components do
i=i+getcomponentindex(components)
- components=getnext(components)
+ components=components.next
end
return i
- elseif not marks[getchar(start)] then
+ elseif not marks[start.char] then
return 1
else
return 0
end
end
local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound)
- if start==stop and getchar(start)==char then
- setfield(start,"char",char)
+ if start==stop and start.char==char then
+ start.char=char
return head,start
end
- local prev=getprev(start)
- local next=getnext(stop)
- setfield(start,"prev",nil)
- setfield(stop,"next",nil)
+ local prev=start.prev
+ local next=stop.next
+ start.prev=nil
+ stop.next=nil
local base=copy_glyph(start)
if start==head then
head=base
end
- setfield(base,"char",char)
- setfield(base,"subtype",ligature_code)
- setfield(base,"components",start)
+ base.char=char
+ base.subtype=ligature_code
+ base.components=start
if prev then
- setfield(prev,"next",base)
+ prev.next=base
end
if next then
- setfield(next,"prev",base)
+ next.prev=base
end
- setfield(base,"next",next)
- setfield(base,"prev",prev)
+ base.next=next
+ base.prev=prev
if not discfound then
local deletemarks=markflag~="mark"
local components=start
@@ -9863,42 +8524,42 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
local head=base
local current=base
while start do
- local char=getchar(start)
+ local char=start.char
if not marks[char] then
baseindex=baseindex+componentindex
componentindex=getcomponentindex(start)
elseif not deletemarks then
- setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex))
+ start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex)
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp))
+ logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp])
end
head,current=insert_node_after(head,current,copy_node(start))
elseif trace_marks then
logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char))
end
- start=getnext(start)
+ start=start.next
end
- local start=getnext(current)
- while start and getid(start)==glyph_code do
- local char=getchar(start)
+ local start=current.next
+ while start and start.id==glyph_code do
+ local char=start.char
if marks[char] then
- setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex))
+ start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex)
if trace_marks then
- logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp))
+ logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp])
end
else
break
end
- start=getnext(start)
+ start=start.next
end
end
return head,base
end
function handlers.gsub_single(head,start,kind,lookupname,replacement)
if trace_singles then
- logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement))
+ logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement))
end
- setfield(start,"char",replacement)
+ start.char=replacement
return head,start,true
end
local function get_alternative_glyph(start,alternatives,value,trace_alternatives)
@@ -9924,7 +8585,7 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives
return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range")
end
elseif value==0 then
- return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
+ return start.char,trace_alternatives and formatters["invalid value %a, %s"](value,"no change")
elseif value<1 then
return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1)
else
@@ -9932,28 +8593,28 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives
end
end
end
-local function multiple_glyphs(head,start,multiple,ignoremarks)
+local function multiple_glyphs(head,start,multiple)
local nofmultiples=#multiple
if nofmultiples>0 then
- setfield(start,"char",multiple[1])
+ start.char=multiple[1]
if nofmultiples>1 then
- local sn=getnext(start)
- for k=2,nofmultiples do
+ local sn=start.next
+ for k=2,nofmultiples do
local n=copy_node(start)
- setfield(n,"char",multiple[k])
- setfield(n,"next",sn)
- setfield(n,"prev",start)
+ n.char=multiple[k]
+ n.next=sn
+ n.prev=start
if sn then
- setfield(sn,"prev",n)
+ sn.prev=n
end
- setfield(start,"next",n)
+ start.next=n
start=n
end
end
return head,start,true
else
if trace_multiples then
- logprocess("no multiple for %s",gref(getchar(start)))
+ logprocess("no multiple for %s",gref(start.char))
end
return head,start,false
end
@@ -9963,34 +8624,34 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence
local choice,comment=get_alternative_glyph(start,alternative,value,trace_alternatives)
if choice then
if trace_alternatives then
- logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment)
+ logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment)
end
- setfield(start,"char",choice)
+ start.char=choice
else
if trace_alternatives then
- logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment)
+ logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment)
end
end
return head,start,true
end
-function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence)
+function handlers.gsub_multiple(head,start,kind,lookupname,multiple)
if trace_multiples then
- logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(getchar(start)),gref(multiple))
+ logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple))
end
- return multiple_glyphs(head,start,multiple,sequence.flags[1])
+ return multiple_glyphs(head,start,multiple)
end
function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
- local s,stop,discfound=getnext(start),nil,false
- local startchar=getchar(start)
+ local s,stop,discfound=start.next,nil,false
+ local startchar=start.char
if marks[startchar] then
while s do
- local id=getid(s)
- if id==glyph_code and getfont(s)==currentfont and getsubtype(s)<256 then
- local lg=ligature[getchar(s)]
+ local id=s.id
+ if id==glyph_code and s.font==currentfont and s.subtype<256 then
+ local lg=ligature[s.char]
if lg then
stop=s
ligature=lg
- s=getnext(s)
+ s=s.next
else
break
end
@@ -10002,9 +8663,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
local lig=ligature.ligature
if lig then
if trace_ligatures then
- local stopchar=getchar(stop)
+ local stopchar=stop.char
head,start=markstoligature(kind,lookupname,head,start,stop,lig)
- logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start)))
+ logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
else
head,start=markstoligature(kind,lookupname,head,start,stop,lig)
end
@@ -10015,18 +8676,18 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
else
local skipmark=sequence.flags[1]
while s do
- local id=getid(s)
- if id==glyph_code and getsubtype(s)<256 then
- if getfont(s)==currentfont then
- local char=getchar(s)
+ local id=s.id
+ if id==glyph_code and s.subtype<256 then
+ if s.font==currentfont then
+ local char=s.char
if skipmark and marks[char] then
- s=getnext(s)
+ s=s.next
else
local lg=ligature[char]
if lg then
stop=s
ligature=lg
- s=getnext(s)
+ s=s.next
else
break
end
@@ -10036,7 +8697,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
end
elseif id==disc_code then
discfound=true
- s=getnext(s)
+ s=s.next
else
break
end
@@ -10045,9 +8706,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
local lig=ligature.ligature
if lig then
if trace_ligatures then
- local stopchar=getchar(stop)
+ local stopchar=stop.char
head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound)
- logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start)))
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char))
else
head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound)
end
@@ -10059,16 +8720,16 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
return head,start,false
end
function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence)
- local markchar=getchar(start)
+ local markchar=start.char
if marks[markchar] then
- local base=getprev(start)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- local basechar=getchar(base)
+ local base=start.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ local basechar=base.char
if marks[basechar] then
while true do
- base=getprev(base)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- basechar=getchar(base)
+ base=base.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ basechar=base.char
if not marks[basechar] then
break
end
@@ -10117,16 +8778,16 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence
return head,start,false
end
function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence)
- local markchar=getchar(start)
+ local markchar=start.char
if marks[markchar] then
- local base=getprev(start)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- local basechar=getchar(base)
+ local base=start.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ local basechar=base.char
if marks[basechar] then
while true do
- base=getprev(base)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- basechar=getchar(base)
+ base=base.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ basechar=base.char
if not marks[basechar] then
break
end
@@ -10138,7 +8799,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ
end
end
end
- local index=getattr(start,a_ligacomp)
+ local index=start[a_ligacomp]
local baseanchors=descriptions[basechar]
if baseanchors then
baseanchors=baseanchors.anchors
@@ -10183,22 +8844,22 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ
return head,start,false
end
function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence)
- local markchar=getchar(start)
+ local markchar=start.char
if marks[markchar] then
- local base=getprev(start)
- local slc=getattr(start,a_ligacomp)
+ local base=start.prev
+ local slc=start[a_ligacomp]
if slc then
while base do
- local blc=getattr(base,a_ligacomp)
+ local blc=base[a_ligacomp]
if blc and blc~=slc then
- base=getprev(base)
+ base=base.prev
else
break
end
end
end
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- local basechar=getchar(base)
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ local basechar=base.char
local baseanchors=descriptions[basechar]
if baseanchors then
baseanchors=baseanchors.anchors
@@ -10210,7 +8871,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence
if al[anchor] then
local ma=markanchors[anchor]
if ma then
- local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true)
+ local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma)
if trace_marks then
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
@@ -10236,20 +8897,20 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence
return head,start,false
end
function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence)
- local alreadydone=cursonce and getattr(start,a_cursbase)
+ local alreadydone=cursonce and start[a_cursbase]
if not alreadydone then
local done=false
- local startchar=getchar(start)
+ local startchar=start.char
if marks[startchar] then
if trace_cursive then
logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar))
end
else
- local nxt=getnext(start)
- while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do
- local nextchar=getchar(nxt)
+ local nxt=start.next
+ while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do
+ local nextchar=nxt.char
if marks[nextchar] then
- nxt=getnext(nxt)
+ nxt=nxt.next
else
local entryanchors=descriptions[nextchar]
if entryanchors then
@@ -10283,13 +8944,13 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence)
return head,start,done
else
if trace_cursive and trace_details then
- logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone)
+ logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
end
return head,start,false
end
end
function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence)
- local startchar=getchar(start)
+ local startchar=start.char
local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar])
if trace_kerns then
logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h)
@@ -10297,33 +8958,34 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence)
return head,start,false
end
function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence)
- local snext=getnext(start)
+ local snext=start.next
if not snext then
return head,start,false
else
local prev,done=start,false
local factor=tfmdata.parameters.factor
local lookuptype=lookuptypes[lookupname]
- while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do
- local nextchar=getchar(snext)
+ while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do
+ local nextchar=snext.char
local krn=kerns[nextchar]
if not krn and marks[nextchar] then
prev=snext
- snext=getnext(snext)
+ snext=snext.next
else
+ local krn=kerns[nextchar]
if not krn then
elseif type(krn)=="table" then
if lookuptype=="pair" then
local a,b=krn[2],krn[3]
if a and #a>0 then
- local startchar=getchar(start)
+ local startchar=start.char
local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar])
if trace_kerns then
logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h)
end
end
if b and #b>0 then
- local startchar=getchar(start)
+ local startchar=start.char
local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar])
if trace_kerns then
logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h)
@@ -10336,7 +8998,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence)
elseif krn~=0 then
local k=setkern(snext,factor,rlmode,krn)
if trace_kerns then
- logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar))
+ logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar))
end
done=true
end
@@ -10371,18 +9033,46 @@ function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,looku
return head,start,false
end
function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements)
- local char=getchar(start)
+ local char=start.char
local replacement=replacements[char]
if replacement then
if trace_singles then
logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement))
end
- setfield(start,"char",replacement)
+ start.char=replacement
return head,start,true
else
return head,start,false
end
end
+local function delete_till_stop(start,stop,ignoremarks)
+ local n=1
+ if start==stop then
+ elseif ignoremarks then
+ repeat
+ local next=start.next
+ if not marks[next.char] then
+ local components=next.components
+ if components then
+ flush_node_list(components)
+ end
+ delete_node(start,next)
+ end
+ n=n+1
+ until next==stop
+ else
+ repeat
+ local next=start.next
+ local components=next.components
+ if components then
+ flush_node_list(components)
+ end
+ delete_node(start,next)
+ n=n+1
+ until next==stop
+ end
+ return n
+end
function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex)
local current=start
local subtables=currentlookup.subtables
@@ -10390,8 +9080,8 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo
logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," "))
end
while current do
- if getid(current)==glyph_code then
- local currentchar=getchar(current)
+ if current.id==glyph_code then
+ local currentchar=current.char
local lookupname=subtables[1]
local replacement=lookuphash[lookupname]
if not replacement then
@@ -10408,21 +9098,22 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo
if trace_singles then
logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement))
end
- setfield(current,"char",replacement)
+ current.char=replacement
end
end
return head,start,true
elseif current==stop then
break
else
- current=getnext(current)
+ current=current.next
end
end
return head,start,false
end
chainmores.gsub_single=chainprocs.gsub_single
function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local startchar=getchar(start)
+ delete_till_stop(start,stop)
+ local startchar=start.char
local subtables=currentlookup.subtables
local lookupname=subtables[1]
local replacements=lookuphash[lookupname]
@@ -10440,7 +9131,7 @@ function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,
if trace_multiples then
logprocess("%s: replacing %s by multiple characters %s",cref(kind,chainname,chainlookupname,lookupname),gref(startchar),gref(replacements))
end
- return multiple_glyphs(head,start,replacements,currentlookup.flags[1])
+ return multiple_glyphs(head,start,replacements)
end
end
return head,start,false
@@ -10451,8 +9142,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext
local subtables=currentlookup.subtables
local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue
while current do
- if getid(current)==glyph_code then
- local currentchar=getchar(current)
+ if current.id==glyph_code then
+ local currentchar=current.char
local lookupname=subtables[1]
local alternatives=lookuphash[lookupname]
if not alternatives then
@@ -10467,7 +9158,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext
if trace_alternatives then
logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment)
end
- setfield(start,"char",choice)
+ start.char=choice
else
if trace_alternatives then
logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment)
@@ -10481,14 +9172,14 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext
elseif current==stop then
break
else
- current=getnext(current)
+ current=current.next
end
end
return head,start,false
end
chainmores.gsub_alternate=chainprocs.gsub_alternate
function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex)
- local startchar=getchar(start)
+ local startchar=start.char
local subtables=currentlookup.subtables
local lookupname=subtables[1]
local ligatures=lookuphash[lookupname]
@@ -10503,20 +9194,20 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,
logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
end
else
- local s=getnext(start)
+ local s=start.next
local discfound=false
local last=stop
local nofreplacements=0
local skipmark=currentlookup.flags[1]
while s do
- local id=getid(s)
+ local id=s.id
if id==disc_code then
- s=getnext(s)
+ s=s.next
discfound=true
else
- local schar=getchar(s)
+ local schar=s.char
if skipmark and marks[schar] then
- s=getnext(s)
+ s=s.next
else
local lg=ligatures[schar]
if lg then
@@ -10524,7 +9215,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,
if s==stop then
break
else
- s=getnext(s)
+ s=s.next
end
else
break
@@ -10541,7 +9232,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,
if start==stop then
logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2))
else
- logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)),gref(l2))
+ logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2))
end
end
head,start=toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound)
@@ -10550,7 +9241,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,
if start==stop then
logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar))
else
- logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)))
+ logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char))
end
end
end
@@ -10559,7 +9250,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,
end
chainmores.gsub_ligature=chainprocs.gsub_ligature
function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local markchar=getchar(start)
+ local markchar=start.char
if marks[markchar] then
local subtables=currentlookup.subtables
local lookupname=subtables[1]
@@ -10568,14 +9259,14 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext
markanchors=markanchors[markchar]
end
if markanchors then
- local base=getprev(start)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- local basechar=getchar(base)
+ local base=start.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ local basechar=base.char
if marks[basechar] then
while true do
- base=getprev(base)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- basechar=getchar(base)
+ base=base.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ basechar=base.char
if not marks[basechar] then
break
end
@@ -10622,7 +9313,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext
return head,start,false
end
function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local markchar=getchar(start)
+ local markchar=start.char
if marks[markchar] then
local subtables=currentlookup.subtables
local lookupname=subtables[1]
@@ -10631,14 +9322,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon
markanchors=markanchors[markchar]
end
if markanchors then
- local base=getprev(start)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- local basechar=getchar(base)
+ local base=start.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ local basechar=base.char
if marks[basechar] then
while true do
- base=getprev(base)
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- basechar=getchar(base)
+ base=base.prev
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ basechar=base.char
if not marks[basechar] then
break
end
@@ -10650,7 +9341,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon
end
end
end
- local index=getattr(start,a_ligacomp)
+ local index=start[a_ligacomp]
local baseanchors=descriptions[basechar].anchors
if baseanchors then
local baseanchors=baseanchors['baselig']
@@ -10689,7 +9380,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon
return head,start,false
end
function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local markchar=getchar(start)
+ local markchar=start.char
if marks[markchar] then
local subtables=currentlookup.subtables
local lookupname=subtables[1]
@@ -10698,20 +9389,20 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext
markanchors=markanchors[markchar]
end
if markanchors then
- local base=getprev(start)
- local slc=getattr(start,a_ligacomp)
+ local base=start.prev
+ local slc=start[a_ligacomp]
if slc then
while base do
- local blc=getattr(base,a_ligacomp)
+ local blc=base[a_ligacomp]
if blc and blc~=slc then
- base=getprev(base)
+ base=base.prev
else
break
end
end
end
- if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then
- local basechar=getchar(base)
+ if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then
+ local basechar=base.char
local baseanchors=descriptions[basechar].anchors
if baseanchors then
baseanchors=baseanchors['basemark']
@@ -10721,7 +9412,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext
if al[anchor] then
local ma=markanchors[anchor]
if ma then
- local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true)
+ local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma)
if trace_marks then
logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)",
cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy)
@@ -10747,9 +9438,9 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext
return head,start,false
end
function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname)
- local alreadydone=cursonce and getattr(start,a_cursbase)
+ local alreadydone=cursonce and start[a_cursbase]
if not alreadydone then
- local startchar=getchar(start)
+ local startchar=start.char
local subtables=currentlookup.subtables
local lookupname=subtables[1]
local exitanchors=lookuphash[lookupname]
@@ -10763,11 +9454,11 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l
logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar))
end
else
- local nxt=getnext(start)
- while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do
- local nextchar=getchar(nxt)
+ local nxt=start.next
+ while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do
+ local nextchar=nxt.char
if marks[nextchar] then
- nxt=getnext(nxt)
+ nxt=nxt.next
else
local entryanchors=descriptions[nextchar]
if entryanchors then
@@ -10801,7 +9492,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l
return head,start,done
else
if trace_cursive and trace_details then
- logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone)
+ logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone)
end
return head,start,false
end
@@ -10809,7 +9500,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l
return head,start,false
end
function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence)
- local startchar=getchar(start)
+ local startchar=start.char
local subtables=currentlookup.subtables
local lookupname=subtables[1]
local kerns=lookuphash[lookupname]
@@ -10824,11 +9515,10 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo
end
return head,start,false
end
-chainmores.gpos_single=chainprocs.gpos_single
function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence)
- local snext=getnext(start)
+ local snext=start.next
if snext then
- local startchar=getchar(start)
+ local startchar=start.char
local subtables=currentlookup.subtables
local lookupname=subtables[1]
local kerns=lookuphash[lookupname]
@@ -10838,26 +9528,26 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look
local lookuptype=lookuptypes[lookupname]
local prev,done=start,false
local factor=tfmdata.parameters.factor
- while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do
- local nextchar=getchar(snext)
+ while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do
+ local nextchar=snext.char
local krn=kerns[nextchar]
if not krn and marks[nextchar] then
prev=snext
- snext=getnext(snext)
+ snext=snext.next
else
if not krn then
elseif type(krn)=="table" then
if lookuptype=="pair" then
local a,b=krn[2],krn[3]
if a and #a>0 then
- local startchar=getchar(start)
+ local startchar=start.char
local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar])
if trace_kerns then
logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h)
end
end
if b and #b>0 then
- local startchar=getchar(start)
+ local startchar=start.char
local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar])
if trace_kerns then
logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h)
@@ -10869,7 +9559,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look
if a and a~=0 then
local k=setkern(snext,factor,rlmode,a)
if trace_kerns then
- logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar))
+ logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar))
end
end
if b and b~=0 then
@@ -10880,7 +9570,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look
elseif krn~=0 then
local k=setkern(snext,factor,rlmode,krn)
if trace_kerns then
- logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar))
+ logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar))
end
done=true
end
@@ -10893,7 +9583,6 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look
end
return head,start,false
end
-chainmores.gpos_pair=chainprocs.gpos_pair
local function show_skip(kind,chainname,char,ck,class)
if ck[9] then
logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a, %a => %a",cref(kind,chainname),gref(char),class,ck[1],ck[2],ck[9],ck[10])
@@ -10918,7 +9607,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
local seq=ck[3]
local s=#seq
if s==1 then
- match=getid(current)==glyph_code and getfont(current)==currentfont and getsubtype(current)<256 and seq[1][getchar(current)]
+ match=current.id==glyph_code and current.font==currentfont and current.subtype<256 and seq[1][current.char]
else
local f,l=ck[4],ck[5]
if f==1 and f==l then
@@ -10926,13 +9615,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
if f==l then
else
local n=f+1
- last=getnext(last)
+ last=last.next
while n<=l do
if last then
- local id=getid(last)
+ local id=last.id
if id==glyph_code then
- if getfont(last)==currentfont and getsubtype(last)<256 then
- local char=getchar(last)
+ if last.font==currentfont and last.subtype<256 then
+ local char=last.char
local ccd=descriptions[char]
if ccd then
local class=ccd.class
@@ -10941,10 +9630,10 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
if trace_skips then
show_skip(kind,chainname,char,ck,class)
end
- last=getnext(last)
+ last=last.next
elseif seq[n][char] then
if n<l then
- last=getnext(last)
+ last=last.next
end
n=n+1
else
@@ -10960,7 +9649,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
break
end
elseif id==disc_code then
- last=getnext(last)
+ last=last.next
else
match=false
break
@@ -10973,15 +9662,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
end
end
if match and f>1 then
- local prev=getprev(start)
+ local prev=start.prev
if prev then
local n=f-1
while n>=1 do
if prev then
- local id=getid(prev)
+ local id=prev.id
if id==glyph_code then
- if getfont(prev)==currentfont and getsubtype(prev)<256 then
- local char=getchar(prev)
+ if prev.font==currentfont and prev.subtype<256 then
+ local char=prev.char
local ccd=descriptions[char]
if ccd then
local class=ccd.class
@@ -11011,7 +9700,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
match=false
break
end
- prev=getprev(prev)
+ prev=prev.prev
elseif seq[n][32] then
n=n -1
else
@@ -11031,15 +9720,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
end
end
if match and s>l then
- local current=last and getnext(last)
+ local current=last and last.next
if current then
local n=l+1
while n<=s do
if current then
- local id=getid(current)
+ local id=current.id
if id==glyph_code then
- if getfont(current)==currentfont and getsubtype(current)<256 then
- local char=getchar(current)
+ if current.font==currentfont and current.subtype<256 then
+ local char=current.char
local ccd=descriptions[char]
if ccd then
local class=ccd.class
@@ -11069,7 +9758,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
match=false
break
end
- current=getnext(current)
+ current=current.next
elseif seq[n][32] then
n=n+1
else
@@ -11092,7 +9781,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
if match then
if trace_contexts then
local rule,lookuptype,f,l=ck[1],ck[2],ck[4],ck[5]
- local char=getchar(start)
+ local char=start.char
if ck[9] then
logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a",
cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10])
@@ -11110,11 +9799,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
if chainlookup then
local cp=chainprocs[chainlookup.type]
if cp then
- local ok
- head,start,ok=cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
- if ok then
- done=true
- end
+ head,start,done=cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
else
logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
end
@@ -11126,12 +9811,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
repeat
if skipped then
while true do
- local char=getchar(start)
+ local char=start.char
local ccd=descriptions[char]
if ccd then
local class=ccd.class
if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then
- start=getnext(start)
+ start=start.next
else
break
end
@@ -11141,27 +9826,22 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq
end
end
local chainlookupname=chainlookups[i]
- local chainlookup=lookuptable[chainlookupname]
- if not chainlookup then
- i=i+1
- else
- local cp=chainmores[chainlookup.type]
- if not cp then
- logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type)
- i=i+1
+ local chainlookup=lookuptable[chainlookupname]
+ local cp=chainlookup and chainmores[chainlookup.type]
+ if cp then
+ local ok,n
+ head,start,ok,n=cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence)
+ if ok then
+ done=true
+ i=i+(n or 1)
else
- local ok,n
- head,start,ok,n=cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence)
- if ok then
- done=true
- i=i+(n or 1)
- else
- i=i+1
- end
+ i=i+1
end
+ else
+ i=i+1
end
if start then
- start=getnext(start)
+ start=start.next
else
end
until i>nofchainlookups
@@ -11288,7 +9968,6 @@ local function featuresprocessor(head,font,attr)
if not lookuphash then
return head,false
end
- head=tonut(head)
if trace_steps then
checkstep(head)
end
@@ -11306,344 +9985,228 @@ local function featuresprocessor(head,font,attr)
local done=false
local datasets=otf.dataset(tfmdata,font,attr)
local dirstack={}
- for s=1,#datasets do
- local dataset=datasets[s]
- featurevalue=dataset[1]
- local sequence=dataset[5]
- local rlparmode=0
- local topstack=0
- local success=false
- local attribute=dataset[2]
- local chain=dataset[3]
- local typ=sequence.type
- local subtables=sequence.subtables
- if chain<0 then
- local handler=handlers[typ]
- local start=find_node_tail(head)
- while start do
- local id=getid(start)
- if id==glyph_code then
- if getfont(start)==font and getsubtype(start)<256 then
- local a=getattr(start,0)
- if a then
- a=a==attr
- else
- a=true
- end
- if a then
- for i=1,#subtables do
- local lookupname=subtables[i]
- local lookupcache=lookuphash[lookupname]
- if lookupcache then
- local lookupmatch=lookupcache[getchar(start)]
- if lookupmatch then
- head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
- if success then
- break
- end
- end
- else
- report_missing_cache(typ,lookupname)
- end
- end
- if start then start=getprev(start) end
- else
- start=getprev(start)
- end
- else
- start=getprev(start)
- end
- else
- start=getprev(start)
- end
- end
- else
- local handler=handlers[typ]
- local ns=#subtables
- local start=head
- rlmode=0
- if ns==1 then
- local lookupname=subtables[1]
- local lookupcache=lookuphash[lookupname]
- if not lookupcache then
- report_missing_cache(typ,lookupname)
- else
- local function subrun(start)
- local head=start
- local done=false
- while start do
- local id=getid(start)
- if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then
- local a=getattr(start,0)
- if a then
- a=(a==attr) and (not attribute or getattr(start,a_state)==attribute)
- else
- a=not attribute or getattr(start,a_state)==attribute
- end
- if a then
- local lookupmatch=lookupcache[getchar(start)]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
- if ok then
- done=true
- end
- end
- if start then start=getnext(start) end
- else
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- end
- if done then
- success=true
- return head
- end
- end
+for s=1,#datasets do
+ local dataset=datasets[s]
+ featurevalue=dataset[1]
+ local sequence=dataset[5]
+ local rlparmode=0
+ local topstack=0
+ local success=false
+ local attribute=dataset[2]
+ local chain=dataset[3]
+ local typ=sequence.type
+ local subtables=sequence.subtables
+ if chain<0 then
+ local handler=handlers[typ]
+ local start=find_node_tail(head)
while start do
- local id=getid(start)
+ local id=start.id
if id==glyph_code then
- if getfont(start)==font and getsubtype(start)<256 then
- local a=getattr(start,0)
+ if start.font==font and start.subtype<256 then
+ local a=start[0]
if a then
- a=(a==attr) and (not attribute or getattr(start,a_state)==attribute)
+ a=a==attr
else
- a=not attribute or getattr(start,a_state)==attribute
+ a=true
end
if a then
- local lookupmatch=lookupcache[getchar(start)]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
- if ok then
- success=true
+ for i=1,#subtables do
+ local lookupname=subtables[i]
+ local lookupcache=lookuphash[lookupname]
+ if lookupcache then
+ local lookupmatch=lookupcache[start.char]
+ if lookupmatch then
+ head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
+ if success then
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
end
end
- if start then start=getnext(start) end
+ if start then start=start.prev end
else
- start=getnext(start)
+ start=start.prev
end
else
- start=getnext(start)
- end
- elseif id==disc_code then
- if getsubtype(start)==discretionary_code then
- local pre=getfield(start,"pre")
- if pre then
- local new=subrun(pre)
- if new then setfield(start,"pre",new) end
- end
- local post=getfield(start,"post")
- if post then
- local new=subrun(post)
- if new then setfield(start,"post",new) end
- end
- local replace=getfield(start,"replace")
- if replace then
- local new=subrun(replace)
- if new then setfield(start,"replace",new) end
- end
- end
- start=getnext(start)
- elseif id==whatsit_code then
- local subtype=getsubtype(start)
- if subtype==dir_code then
- local dir=getfield(start,"dir")
- if dir=="+TRT" or dir=="+TLT" then
- topstack=topstack+1
- dirstack[topstack]=dir
- elseif dir=="-TRT" or dir=="-TLT" then
- topstack=topstack-1
- end
- local newdir=dirstack[topstack]
- if newdir=="+TRT" then
- rlmode=-1
- elseif newdir=="+TLT" then
- rlmode=1
- else
- rlmode=rlparmode
- end
- if trace_directions then
- report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
- end
- elseif subtype==localpar_code then
- local dir=getfield(start,"dir")
- if dir=="TRT" then
- rlparmode=-1
- elseif dir=="TLT" then
- rlparmode=1
- else
- rlparmode=0
- end
- rlmode=rlparmode
- if trace_directions then
- report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
- end
+ start=start.prev
end
- start=getnext(start)
- elseif id==math_code then
- start=getnext(end_of_math(start))
else
- start=getnext(start)
+ start=start.prev
end
end
- end
- else
- local function subrun(start)
- local head=start
- local done=false
- while start do
- local id=getid(start)
- if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then
- local a=getattr(start,0)
- if a then
- a=(a==attr) and (not attribute or getattr(start,a_state)==attribute)
- else
- a=not attribute or getattr(start,a_state)==attribute
- end
- if a then
- for i=1,ns do
- local lookupname=subtables[i]
- local lookupcache=lookuphash[lookupname]
- if lookupcache then
- local lookupmatch=lookupcache[getchar(start)]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
- if ok then
- done=true
- break
- elseif not start then
- break
+ else
+ local handler=handlers[typ]
+ local ns=#subtables
+ local start=head
+ rlmode=0
+ if ns==1 then
+ local lookupname=subtables[1]
+ local lookupcache=lookuphash[lookupname]
+ if not lookupcache then
+ report_missing_cache(typ,lookupname)
+ else
+ while start do
+ local id=start.id
+ if id==glyph_code then
+ if start.font==font and start.subtype<256 then
+ local a=start[0]
+ if a then
+ a=(a==attr) and (not attribute or start[a_state]==attribute)
+ else
+ a=not attribute or start[a_state]==attribute
+ end
+ if a then
+ local lookupmatch=lookupcache[start.char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1)
+ if ok then
+ success=true
+ end
end
+ if start then start=start.next end
+ else
+ start=start.next
end
+ elseif id==math_code then
+ start=end_of_math(start).next
else
- report_missing_cache(typ,lookupname)
+ start=start.next
+ end
+ elseif id==whatsit_code then
+ local subtype=start.subtype
+ if subtype==dir_code then
+ local dir=start.dir
+ if dir=="+TRT" or dir=="+TLT" then
+ topstack=topstack+1
+ dirstack[topstack]=dir
+ elseif dir=="-TRT" or dir=="-TLT" then
+ topstack=topstack-1
+ end
+ local newdir=dirstack[topstack]
+ if newdir=="+TRT" then
+ rlmode=-1
+ elseif newdir=="+TLT" then
+ rlmode=1
+ else
+ rlmode=rlparmode
+ end
+ if trace_directions then
+ report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
+ end
+ elseif subtype==localpar_code then
+ local dir=start.dir
+ if dir=="TRT" then
+ rlparmode=-1
+ elseif dir=="TLT" then
+ rlparmode=1
+ else
+ rlparmode=0
+ end
+ rlmode=rlparmode
+ if trace_directions then
+ report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
+ end
end
+ start=start.next
+ elseif id==math_code then
+ start=end_of_math(start).next
+ else
+ start=start.next
end
- if start then start=getnext(start) end
- else
- start=getnext(start)
end
- else
- start=getnext(start)
end
- end
- if done then
- success=true
- return head
- end
- end
- while start do
- local id=getid(start)
- if id==glyph_code then
- if getfont(start)==font and getsubtype(start)<256 then
- local a=getattr(start,0)
- if a then
- a=(a==attr) and (not attribute or getattr(start,a_state)==attribute)
- else
- a=not attribute or getattr(start,a_state)==attribute
- end
- if a then
- for i=1,ns do
- local lookupname=subtables[i]
- local lookupcache=lookuphash[lookupname]
- if lookupcache then
- local lookupmatch=lookupcache[getchar(start)]
- if lookupmatch then
- local ok
- head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
- if ok then
- success=true
- break
- elseif not start then
- break
+ else
+ while start do
+ local id=start.id
+ if id==glyph_code then
+ if start.font==font and start.subtype<256 then
+ local a=start[0]
+ if a then
+ a=(a==attr) and (not attribute or start[a_state]==attribute)
+ else
+ a=not attribute or start[a_state]==attribute
+ end
+ if a then
+ for i=1,ns do
+ local lookupname=subtables[i]
+ local lookupcache=lookuphash[lookupname]
+ if lookupcache then
+ local lookupmatch=lookupcache[start.char]
+ if lookupmatch then
+ local ok
+ head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i)
+ if ok then
+ success=true
+ break
+ elseif not start then
+ break
+ end
+ end
+ else
+ report_missing_cache(typ,lookupname)
end
end
+ if start then start=start.next end
else
- report_missing_cache(typ,lookupname)
+ start=start.next
end
+ else
+ start=start.next
end
- if start then start=getnext(start) end
- else
- start=getnext(start)
- end
- else
- start=getnext(start)
- end
- elseif id==disc_code then
- if getsubtype(start)==discretionary_code then
- local pre=getfield(start,"pre")
- if pre then
- local new=subrun(pre)
- if new then setfield(start,"pre",new) end
- end
- local post=getfield(start,"post")
- if post then
- local new=subrun(post)
- if new then setfield(start,"post",new) end
- end
- local replace=getfield(start,"replace")
- if replace then
- local new=subrun(replace)
- if new then setfield(start,"replace",new) end
- end
- end
- start=getnext(start)
- elseif id==whatsit_code then
- local subtype=getsubtype(start)
- if subtype==dir_code then
- local dir=getfield(start,"dir")
- if dir=="+TRT" or dir=="+TLT" then
- topstack=topstack+1
- dirstack[topstack]=dir
- elseif dir=="-TRT" or dir=="-TLT" then
- topstack=topstack-1
- end
- local newdir=dirstack[topstack]
- if newdir=="+TRT" then
- rlmode=-1
- elseif newdir=="+TLT" then
- rlmode=1
- else
- rlmode=rlparmode
- end
- if trace_directions then
- report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
- end
- elseif subtype==localpar_code then
- local dir=getfield(start,"dir")
- if dir=="TRT" then
- rlparmode=-1
- elseif dir=="TLT" then
- rlparmode=1
+ elseif id==whatsit_code then
+ local subtype=start.subtype
+ if subtype==dir_code then
+ local dir=start.dir
+ if dir=="+TRT" or dir=="+TLT" then
+ topstack=topstack+1
+ dirstack[topstack]=dir
+ elseif dir=="-TRT" or dir=="-TLT" then
+ topstack=topstack-1
+ end
+ local newdir=dirstack[topstack]
+ if newdir=="+TRT" then
+ rlmode=-1
+ elseif newdir=="+TLT" then
+ rlmode=1
+ else
+ rlmode=rlparmode
+ end
+ if trace_directions then
+ report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir)
+ end
+ elseif subtype==localpar_code then
+ local dir=start.dir
+ if dir=="TRT" then
+ rlparmode=-1
+ elseif dir=="TLT" then
+ rlparmode=1
+ else
+ rlparmode=0
+ end
+ rlmode=rlparmode
+ if trace_directions then
+ report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
+ end
+ end
+ start=start.next
+ elseif id==math_code then
+ start=end_of_math(start).next
else
- rlparmode=0
- end
- rlmode=rlparmode
- if trace_directions then
- report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
+ start=start.next
end
end
- start=getnext(start)
- elseif id==math_code then
- start=getnext(end_of_math(start))
- else
- start=getnext(start)
end
end
- end
- end
- if success then
- done=true
- end
- if trace_steps then
- registerstep(head)
- end
+ if success then
+ done=true
+ end
+ if trace_steps then
+ registerstep(head)
+ end
end
- head=tonode(head)
return head,done
end
local function generic(lookupdata,lookupname,unicode,lookuphash)
@@ -12752,7 +11315,6 @@ if not modules then modules={} end modules ['font-def']={
local format,gmatch,match,find,lower,gsub=string.format,string.gmatch,string.match,string.find,string.lower,string.gsub
local tostring,next=tostring,next
local lpegmatch=lpeg.match
-local suffixonly,removesuffix=file.suffix,file.removesuffix
local allocate=utilities.storage.allocate
local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end)
local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end)
@@ -12800,7 +11362,7 @@ addlookup("file")
addlookup("name")
addlookup("spec")
local function getspecification(str)
- return lpegmatch(splitter,str or "")
+ return lpegmatch(splitter,str)
end
definers.getspecification=getspecification
function definers.registersplit(symbol,action,verbosename)
@@ -12842,11 +11404,10 @@ definers.resolvers=definers.resolvers or {}
local resolvers=definers.resolvers
function resolvers.file(specification)
local name=resolvefile(specification.name)
- local suffix=lower(suffixonly(name))
+ local suffix=file.suffix(name)
if fonts.formats[suffix] then
specification.forced=suffix
- specification.forcedname=name
- specification.name=removesuffix(name)
+ specification.name=file.removesuffix(name)
else
specification.name=name
end
@@ -12858,11 +11419,10 @@ function resolvers.name(specification)
if resolved then
specification.resolved=resolved
specification.sub=sub
- local suffix=lower(suffixonly(resolved))
+ local suffix=file.suffix(resolved)
if fonts.formats[suffix] then
specification.forced=suffix
- specification.forcedname=resolved
- specification.name=removesuffix(resolved)
+ specification.name=file.removesuffix(resolved)
else
specification.name=resolved
end
@@ -12878,9 +11438,8 @@ function resolvers.spec(specification)
if resolved then
specification.resolved=resolved
specification.sub=sub
- specification.forced=lower(suffixonly(resolved))
- specification.forcedname=resolved
- specification.name=removesuffix(resolved)
+ specification.forced=file.suffix(resolved)
+ specification.name=file.removesuffix(resolved)
end
else
resolvers.name(specification)
@@ -12895,7 +11454,8 @@ function definers.resolve(specification)
end
if specification.forced=="" then
specification.forced=nil
- specification.forcedname=nil
+ else
+ specification.forced=specification.forced
end
specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification))
if specification.sub and specification.sub~="" then
@@ -12940,7 +11500,7 @@ function definers.loadfont(specification)
if not tfmdata then
local forced=specification.forced or ""
if forced~="" then
- local reader=readers[lower(forced)]
+ local reader=readers[lower(forced)]
tfmdata=reader and reader(specification)
if not tfmdata then
report_defining("forced type %a of %a not found",forced,specification.name)
diff --git a/tex/generic/context/luatex/luatex-fonts-syn.lua b/tex/generic/context/luatex/luatex-fonts-syn.lua
index 60dd2c063..ea6e3cab5 100644
--- a/tex/generic/context/luatex/luatex-fonts-syn.lua
+++ b/tex/generic/context/luatex/luatex-fonts-syn.lua
@@ -100,7 +100,3 @@ fonts.names.resolvespec = fonts.names.resolve -- only supported in mkiv
function fonts.names.getfilename(askedname,suffix) -- only supported in mkiv
return ""
end
-
-function fonts.names.ignoredfile(filename) -- only supported in mkiv
- return true -- will be overloaded
-end
diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua
index 7995be33e..89592fcac 100644
--- a/tex/generic/context/luatex/luatex-fonts.lua
+++ b/tex/generic/context/luatex/luatex-fonts.lua
@@ -192,7 +192,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
-- with context. The mtx-fonts script can be used to genate this file (using the --names option).
-- In 2013/14 I will merge/move some generic files into luatex-fonts-* files (copies) so that
- -- intermediate updates of context don't interfere. We can then also use the general merger and
+ -- intermediate updates of context not interfere. We can then also use the general merger and
-- consider stripping debug code.
loadmodule('font-ini.lua')
@@ -201,11 +201,6 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-cid.lua')
loadmodule('font-map.lua') -- for loading lum file (will be stripped)
loadmodule('luatex-fonts-syn.lua') -- deals with font names (synonyms)
- -- begin of test
- loadmodule('font-tfm.lua') -- optional
- loadmodule('font-afm.lua') -- optional
- loadmodule('font-afk.lua') -- optional
- -- end of test
loadmodule('luatex-fonts-tfm.lua')
loadmodule('font-oti.lua')
loadmodule('font-otf.lua')
@@ -214,6 +209,7 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-ota.lua')
loadmodule('font-otn.lua')
loadmodule('font-otp.lua') -- optional
+ ----------('luatex-fonts-chr.lua')
loadmodule('luatex-fonts-lua.lua')
loadmodule('font-def.lua')
loadmodule('luatex-fonts-def.lua')
diff --git a/tex/generic/context/luatex/luatex-test.tex b/tex/generic/context/luatex/luatex-test.tex
index fbf8ce3cf..fcc837e70 100644
--- a/tex/generic/context/luatex/luatex-test.tex
+++ b/tex/generic/context/luatex/luatex-test.tex
@@ -80,8 +80,4 @@ $$\left( { {1} \over { {1} \over {x} } } \right) $$
$$\sqrt {2} { { {1} \over { {1} \over {x} } } } $$
-\font\cows=file:koeieletters.afm at 50pt
-
-\cows Hello World!
-
\end