summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2015-12-23 00:12:14 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2015-12-23 00:12:14 +0100
commite7fc73c0cb9a56c394d12f4967dbcffe93923afd (patch)
tree997ecb4230c241159a51d436cba4ffc49fcff8c1
parentbd29de3d14bd6cfeb96111227f153cbccf0527a4 (diff)
parent34a02eaaaf87f6608fc7cb13d60f1217f36f6502 (diff)
downloadluaotfload-e7fc73c0cb9a56c394d12f4967dbcffe93923afd.tar.gz
Merge pull request #315 from phi-gamma/master
third round of fixes
-rwxr-xr-xscripts/mkimport12
-rwxr-xr-xscripts/mkstatus8
-rw-r--r--src/fontloader/misc/fontloader-basics-nod.lua45
-rw-r--r--src/fontloader/misc/fontloader-font-con.lua2
-rw-r--r--src/fontloader/misc/fontloader-font-inj.lua (renamed from src/fontloader/misc/fontloader-fonts-inj.lua)60
-rw-r--r--src/fontloader/misc/fontloader-font-map.lua66
-rw-r--r--src/fontloader/misc/fontloader-font-otf.lua10
-rw-r--r--src/fontloader/misc/fontloader-font-oti.lua69
-rw-r--r--src/fontloader/misc/fontloader-font-otn.lua (renamed from src/fontloader/misc/fontloader-fonts-otn.lua)419
-rw-r--r--src/fontloader/misc/fontloader-fonts-def.lua2
-rw-r--r--src/fontloader/misc/fontloader-fonts-ota.lua30
-rw-r--r--src/fontloader/misc/fontloader-fonts.lua6
-rw-r--r--src/fontloader/misc/fontloader-languages.lua15
-rw-r--r--src/fontloader/misc/fontloader-languages.tex2
-rw-r--r--src/fontloader/runtime/fontloader-reference.lua543
-rw-r--r--src/luaotfload-auxiliary.lua64
-rw-r--r--src/luaotfload-features.lua124
-rw-r--r--src/luaotfload-init.lua47
18 files changed, 1059 insertions, 465 deletions
diff --git a/scripts/mkimport b/scripts/mkimport
index b3c71fe..08537d7 100755
--- a/scripts/mkimport
+++ b/scripts/mkimport
@@ -196,11 +196,9 @@ local imports = {
{ name = "fonts-demo-vf-1" , ours = nil , kind = kind_ignored },
{ name = "fonts-enc" , ours = nil , kind = kind_merged },
{ name = "fonts-ext" , ours = nil , kind = kind_merged },
- { name = "fonts-inj" , ours = nil , kind = kind_merged },
{ name = "fonts-lua" , ours = nil , kind = kind_merged },
{ name = "fonts-merged" , ours = "reference" , kind = kind_essential },
{ name = "fonts-ota" , ours = nil , kind = kind_merged },
- { name = "fonts-otn" , ours = nil , kind = kind_merged },
{ name = "fonts" , ours = nil , kind = kind_merged },
{ name = "fonts" , ours = nil , kind = kind_tex },
{ name = "fonts-syn" , ours = nil , kind = kind_ignored },
@@ -230,10 +228,12 @@ local imports = {
{ name = "font-con" , ours = "font-con" , kind = kind_merged },
{ name = "font-def" , ours = "font-def" , kind = kind_merged },
{ name = "font-ini" , ours = "font-ini" , kind = kind_merged },
+ { name = "font-inj" , ours = "font-inj" , kind = kind_merged },
{ name = "font-map" , ours = "font-map" , kind = kind_merged },
{ name = "font-otb" , ours = "font-otb" , kind = kind_merged },
{ name = "font-otf" , ours = "font-otf" , kind = kind_merged },
{ name = "font-oti" , ours = "font-oti" , kind = kind_merged },
+ { name = "font-otn" , ours = "font-otn" , kind = kind_merged },
{ name = "font-otp" , ours = "font-otp" , kind = kind_merged },
{ name = "font-tfm" , ours = "font-tfm" , kind = kind_merged },
{ name = "l-boolean" , ours = "l-boolean" , kind = kind_lualibs },
@@ -282,9 +282,9 @@ local package = {
--- [24] font-oti.lua
--- [25] font-otf.lua
--- [26] font-otb.lua
---- [27] luatex-fonts-inj.lua
+--- [27] font-inj.lua
--- [28] luatex-fonts-ota.lua
---- [29] luatex-fonts-otn.lua
+--- [30] font-otn.lua
--- [30] font-otp.lua
--- [31] luatex-fonts-lua.lua
--- [32] font-def.lua
@@ -336,9 +336,9 @@ local package = {
"font-oti",
"font-otf",
"font-otb",
- "fonts-inj",
+ "font-inj",
"fonts-ota",
- "fonts-otn",
+ "font-otn",
"font-otp",
"fonts-lua",
"font-def",
diff --git a/scripts/mkstatus b/scripts/mkstatus
index 4b36a9d..c5ded0d 100755
--- a/scripts/mkstatus
+++ b/scripts/mkstatus
@@ -101,11 +101,11 @@ local names = {
{ miscdir, "fontloader-fonts-demo-vf-1.lua", },
{ miscdir, "fontloader-fonts-enc.lua", },
{ miscdir, "fontloader-fonts-ext.lua", },
- { miscdir, "fontloader-fonts-inj.lua", },
+ { miscdir, "fontloader-font-inj.lua", },
{ miscdir, "fontloader-fonts.lua", },
{ miscdir, "fontloader-fonts-lua.lua", },
{ miscdir, "fontloader-fonts-ota.lua", },
- { miscdir, "fontloader-fonts-otn.lua", },
+ { miscdir, "fontloader-font-otn.lua", },
{ miscdir, "fontloader-fonts-syn.lua", },
{ miscdir, "fontloader-fonts-tfm.lua", },
{ miscdir, "fontloader-font-tfm.lua", },
@@ -164,7 +164,9 @@ local git_info = function ()
--io.write "\n"
local desc = readpipe (describecmd)
if not desc then die "cannot parse git information" end
- local desc = string.explode (string.fullstrip (desc), "/")[2]
+ desc = string.fullstrip (desc)
+ local desc = string.explode (desc, "/")[2] or desc
+ if not desc then die "cannot parse sanitized git information" end
local data = readpipe (logcmd)
if data and type (data) == "string" and data ~= "" then
data = load (data)
diff --git a/src/fontloader/misc/fontloader-basics-nod.lua b/src/fontloader/misc/fontloader-basics-nod.lua
index 39400a3..78f1b17 100644
--- a/src/fontloader/misc/fontloader-basics-nod.lua
+++ b/src/fontloader/misc/fontloader-basics-nod.lua
@@ -51,17 +51,23 @@ nodes = { }
nodes.pool = { }
nodes.handlers = { }
-local nodecodes = { } for k,v in next, node.types () do nodecodes[string.gsub(v,"_","")] = k end
-local whatcodes = { } for k,v in next, node.whatsits() do whatcodes[string.gsub(v,"_","")] = k end
-local glyphcodes = { [0] = "character", "glyph", "ligature", "ghost", "left", "right" }
-local disccodes = { [0] = "discretionary", "explicit", "automatic", "regular", "first", "second" }
-
-for i=0,#glyphcodes do glyphcodes[glyphcodes[i]] = i end
-for i=0,#disccodes do disccodes [disccodes [i]] = i end
+local nodecodes = { }
+local glyphcodes = node.subtypes("glyph")
+local disccodes = node.subtypes("disc")
+
+for k, v in next, node.types() do
+ v = string.gsub(v,"_","")
+ nodecodes[k] = v
+ nodecodes[v] = k
+end
+for i=0,#glyphcodes do
+ glyphcodes[glyphcodes[i]] = i
+end
+for i=0,#disccodes do
+ disccodes[disccodes[i]] = i
+end
nodes.nodecodes = nodecodes
-nodes.whatcodes = whatcodes
-nodes.whatsitcodes = whatcodes
nodes.glyphcodes = glyphcodes
nodes.disccodes = disccodes
@@ -140,7 +146,6 @@ 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
@@ -178,20 +183,33 @@ nodes.tonut = tonut
nuts.tonode = tonode
nuts.tonut = tonut
-
local getfield = direct.getfield
local setfield = direct.setfield
nuts.getfield = getfield
nuts.setfield = setfield
nuts.getnext = direct.getnext
+nuts.setnext = direct.setnext
nuts.getprev = direct.getprev
+nuts.setprev = direct.setprev
+nuts.getboth = direct.getboth
+nuts.setboth = direct.setboth
nuts.getid = direct.getid
-nuts.getattr = getfield
+nuts.getattr = direct.get_attribute or direct.has_attribute or getfield
nuts.setattr = setfield
nuts.getfont = direct.getfont
+nuts.setfont = direct.setfont
nuts.getsubtype = direct.getsubtype
+nuts.setsubtype = direct.setsubtype or function(n,s) setfield(n,"subtype",s) end
nuts.getchar = direct.getchar
+nuts.setchar = direct.setchar
+nuts.getdisc = direct.getdisc
+nuts.setdisc = direct.setdisc
+nuts.setlink = direct.setlink
+nuts.getlist = direct.getlist
+nuts.setlist = direct.setlist or function(n,l) setfield(n,"list",l) end
+nuts.getleader = direct.getleader
+nuts.setleader = direct.setleader or function(n,l) setfield(n,"leader",l) end
nuts.insert_before = direct.insert_before
nuts.insert_after = direct.insert_after
@@ -206,6 +224,9 @@ nuts.is_node = direct.is_node
nuts.end_of_math = direct.end_of_math
nuts.traverse = direct.traverse
nuts.traverse_id = direct.traverse_id
+nuts.traverse_char = direct.traverse_char
+nuts.ligaturing = direct.ligaturing
+nuts.kerning = direct.kerning
nuts.getprop = nuts.getattr
nuts.setprop = nuts.setattr
diff --git a/src/fontloader/misc/fontloader-font-con.lua b/src/fontloader/misc/fontloader-font-con.lua
index 55d7793..e5bf9e9 100644
--- a/src/fontloader/misc/fontloader-font-con.lua
+++ b/src/fontloader/misc/fontloader-font-con.lua
@@ -682,6 +682,8 @@ function constructors.scale(tfmdata,specification)
if isunicode then
chr.unicode = isunicode
chr.tounicode = tounicode(isunicode)
+ -- in luatex > 0.85 we can do this:
+ -- chr.tounicode = isunicode
end
if hasquality then
-- we could move these calculations elsewhere (saves calculations)
diff --git a/src/fontloader/misc/fontloader-fonts-inj.lua b/src/fontloader/misc/fontloader-font-inj.lua
index 36781f7..8937021 100644
--- a/src/fontloader/misc/fontloader-fonts-inj.lua
+++ b/src/fontloader/misc/fontloader-font-inj.lua
@@ -74,7 +74,6 @@ local nofregisteredkerns = 0
local nofregisteredpairs = 0
local nofregisteredmarks = 0
local nofregisteredcursives = 0
------ markanchors = { } -- one base can have more marks
local keepregisteredcounts = false
function injections.keepcounts()
@@ -91,10 +90,41 @@ end
-- We need to make sure that a possible metatable will not kick in unexpectedly.
+-- function injections.reset(n)
+-- local p = rawget(properties,n)
+-- if p and rawget(p,"injections") then
+-- p.injections = nil
+-- end
+-- end
+
+-- function injections.copy(target,source)
+-- local sp = rawget(properties,source)
+-- if sp then
+-- local tp = rawget(properties,target)
+-- local si = rawget(sp,"injections")
+-- if si then
+-- si = fastcopy(si)
+-- if tp then
+-- tp.injections = si
+-- else
+-- propertydata[target] = {
+-- injections = si,
+-- }
+-- end
+-- else
+-- if tp then
+-- tp.injections = nil
+-- end
+-- end
+-- end
+-- end
+
function injections.reset(n)
local p = rawget(properties,n)
- if p and rawget(p,"injections") then
- p.injections = nil
+ if p then
+ p.injections = false -- { }
+ else
+ properties[n] = false -- { injections = { } }
end
end
@@ -112,10 +142,17 @@ function injections.copy(target,source)
injections = si,
}
end
+ elseif tp then
+ tp.injections = false -- { }
else
- if tp then
- tp.injections = nil
- end
+ properties[target] = { injections = { } }
+ end
+ else
+ local tp = rawget(properties,target)
+ if tp then
+ tp.injections = false -- { }
+ else
+ properties[target] = false -- { injections = { } }
end
end
end
@@ -367,10 +404,11 @@ local function show(n,what,nested,symbol)
local markx = i.markx or 0
local marky = i.marky or 0
local markdir = i.markdir or 0
- local markbase = i.markbase or 0 -- will be markbasenode
+ local markbase = i.markbase or 0
local cursivex = i.cursivex or 0
local cursivey = i.cursivey or 0
local ligaindex = i.ligaindex or 0
+ local cursbase = i.cursiveanchor
local margin = nested and 4 or 2
--
if rightkern ~= 0 or yoffset ~= 0 then
@@ -382,7 +420,13 @@ local function show(n,what,nested,symbol)
report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase ~= 0 and "yes" or "no")
end
if cursivex ~= 0 or cursivey ~= 0 then
- report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ if cursbase then
+ report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ else
+ report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ end
+ elseif cursbase then
+ report_injections("%w%s curs: base",margin,symbol)
end
if ligaindex ~= 0 then
report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
diff --git a/src/fontloader/misc/fontloader-font-map.lua b/src/fontloader/misc/fontloader-font-map.lua
index b645d9a..dc3f499 100644
--- a/src/fontloader/misc/fontloader-font-map.lua
+++ b/src/fontloader/misc/fontloader-font-map.lua
@@ -74,6 +74,71 @@ end
local f_single = formatters["%04X"]
local f_double = formatters["%04X%04X"]
+-- 0.684 0.661 0,672 0.650 : cache at lua end (more mem)
+-- 0.682 0,672 0.698 0.657 : no cache (moderate mem i.e. lua strings)
+-- 0.644 0.647 0.655 0.645 : convert in c (less mem in theory)
+
+-- local tounicodes = table.setmetatableindex(function(t,unicode)
+-- local s
+-- if unicode < 0x10000 then
+-- s = f_single(unicode)
+-- elseif unicode < 0x1FFFFFFFFF then
+-- s = f_double(floor(unicode/1024),unicode%1024+0xDC00)
+-- else
+-- s = false
+-- end
+-- t[unicode] = s
+-- return s
+-- end)
+--
+-- local function tounicode16(unicode,name)
+-- local s = tounicodes[unicode]
+-- if s then
+-- return s
+-- else
+-- report_fonts("can't convert %a in %a into tounicode",unicode,name)
+-- end
+-- end
+--
+-- local function tounicode16sequence(unicodes,name)
+-- local t = { }
+-- for l=1,#unicodes do
+-- local u = unicodes[l]
+-- local s = tounicodes[u]
+-- if s then
+-- t[l] = s
+-- else
+-- report_fonts ("can't convert %a in %a into tounicode",u,name)
+-- return
+-- end
+-- end
+-- return concat(t)
+-- end
+--
+-- local function tounicode(unicode,name)
+-- if type(unicode) == "table" then
+-- local t = { }
+-- for l=1,#unicode do
+-- local u = unicode[l]
+-- local s = tounicodes[u]
+-- if s then
+-- t[l] = s
+-- else
+-- report_fonts ("can't convert %a in %a into tounicode",u,name)
+-- return
+-- end
+-- end
+-- return concat(t)
+-- else
+-- local s = tounicodes[unicode]
+-- if s then
+-- return s
+-- else
+-- report_fonts("can't convert %a in %a into tounicode",unicode,name)
+-- end
+-- end
+-- end
+
local function tounicode16(unicode,name)
if unicode < 0x10000 then
return f_single(unicode)
@@ -126,7 +191,6 @@ local function tounicode(unicode,name)
end
end
-
local function fromunicode16(str)
if #str == 4 then
return tonumber(str,16)
diff --git a/src/fontloader/misc/fontloader-font-otf.lua b/src/fontloader/misc/fontloader-font-otf.lua
index f709e70..0471c17 100644
--- a/src/fontloader/misc/fontloader-font-otf.lua
+++ b/src/fontloader/misc/fontloader-font-otf.lua
@@ -58,7 +58,7 @@ local otf = fonts.handlers.otf
otf.glists = { "gsub", "gpos" }
-otf.version = 2.819 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 2.820 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otf", otf.version, true)
local hashes = fonts.hashes
@@ -296,7 +296,8 @@ local ordered_enhancers = {
"expand lookups", -- a temp hack awaiting the lua loader
--- "check extra features", -- after metadata and duplicates
+--[[phg-- PATCH: Next line restores font features --phg]]--
+ "check extra features", -- after metadata and duplicates
"cleanup tables",
@@ -600,7 +601,9 @@ function otf.load(filename,sub,featurefile) -- second argument (format) is gone
applyruntimefixes(filename,data)
end
enhance("add dimensions",data,filename,nil,false)
+--[[phg-- This was hand-patched to restore the fontloader
enhance("check extra features",data,filename)
+--phg]]--
if trace_sequences then
showfeatureorder(data,filename)
end
@@ -2959,7 +2962,7 @@ otf.coverup = {
kern = justset,
},
register = function(coverage,lookuptype,format,feature,n,descriptions,resources)
- local name = formatters["ctx_%s_%s"](feature,n)
+ local name = formatters["ctx_%s_%s_%s"](feature,lookuptype,n) -- we can have a mix of types
if lookuptype == "kern" then
resources.lookuptypes[name] = "position"
else
@@ -2973,7 +2976,6 @@ otf.coverup = {
else
description.slookups = { [name] = c }
end
--- inspect(feature,description)
end
return name
end
diff --git a/src/fontloader/misc/fontloader-font-oti.lua b/src/fontloader/misc/fontloader-font-oti.lua
index 06c2a42..bacd001 100644
--- a/src/fontloader/misc/fontloader-font-oti.lua
+++ b/src/fontloader/misc/fontloader-font-oti.lua
@@ -13,9 +13,11 @@ local constructors = fonts.constructors
local otf = constructors.newhandler("otf")
local otffeatures = constructors.newfeatures("otf")
-local otftables = otf.tables
local registerotffeature = otffeatures.register
+local otftables = otf.tables or { }
+otf.tables = otftables
+
local allocate = utilities.storage.allocate
registerotffeature {
@@ -89,3 +91,68 @@ registerotffeature {
}
}
+-- here (as also in generic
+
+otftables.featuretypes = allocate {
+ gpos_single = "position",
+ gpos_pair = "position",
+ gpos_cursive = "position",
+ gpos_mark2base = "position",
+ gpos_mark2ligature = "position",
+ gpos_mark2mark = "position",
+ gpos_context = "position",
+ gpos_contextchain = "position",
+ gsub_single = "substitution",
+ gsub_multiple = "substitution",
+ gsub_alternate = "substitution",
+ gsub_ligature = "substitution",
+ gsub_context = "substitution",
+ gsub_contextchain = "substitution",
+ gsub_reversecontextchain = "substitution",
+ gsub_reversesub = "substitution",
+}
+
+function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
+ if featuretype == "position" then
+ local default = scripts.dflt
+ if default then
+ if autoscript == "position" or autoscript == true then
+ return default
+ else
+ report_otf("script feature %s not applied, enable default positioning")
+ end
+ else
+ -- no positioning at all
+ end
+ elseif featuretype == "substitution" then
+ local default = scripts.dflt
+ if default then
+ if autoscript == "substitution" or autoscript == true then
+ return default
+ end
+ end
+ end
+end
+
+function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
+ if featuretype == "position" then
+ local default = languages.dflt
+ if default then
+ if autolanguage == "position" or autolanguage == true then
+ return default
+ else
+ report_otf("language feature %s not applied, enable default positioning")
+ end
+ else
+ -- no positioning at all
+ end
+ elseif featuretype == "substitution" then
+ local default = languages.dflt
+ if default then
+ if autolanguage == "substitution" or autolanguage == true then
+ return default
+ end
+ end
+ end
+end
+
diff --git a/src/fontloader/misc/fontloader-fonts-otn.lua b/src/fontloader/misc/fontloader-font-otn.lua
index 7fafadb..b48aea7 100644
--- a/src/fontloader/misc/fontloader-fonts-otn.lua
+++ b/src/fontloader/misc/fontloader-font-otn.lua
@@ -132,7 +132,7 @@ results in different tables.</p>
-- gpos_context ok --
-- gpos_contextchain ok --
--
--- todo: contextpos and contextsub and class stuff
+-- todo: contextpos
--
-- actions:
--
@@ -212,7 +212,9 @@ local tonut = nuts.tonut
local getfield = nuts.getfield
local setfield = nuts.setfield
local getnext = nuts.getnext
+local setnext = nuts.setnext
local getprev = nuts.getprev
+local setprev = nuts.setprev
local getid = nuts.getid
local getattr = nuts.getattr
local setattr = nuts.setattr
@@ -220,7 +222,9 @@ local getprop = nuts.getprop
local setprop = nuts.setprop
local getfont = nuts.getfont
local getsubtype = nuts.getsubtype
+local setsubtype = nuts.setsubtype
local getchar = nuts.getchar
+local setchar = nuts.setchar
local insert_node_before = nuts.insert_before
local insert_node_after = nuts.insert_after
@@ -243,7 +247,6 @@ local wildcard = "*"
local default = "dflt"
local nodecodes = nodes.nodecodes
-local whatcodes = nodes.whatcodes
local glyphcodes = nodes.glyphcodes
local disccodes = nodes.disccodes
@@ -251,9 +254,9 @@ local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
local disc_code = nodecodes.disc
local math_code = nodecodes.math
+local dir_code = nodecodes.dir
+local localpar_code = nodecodes.localpar
-local dir_code = whatcodes.dir
-local localpar_code = whatcodes.localpar
local discretionary_code = disccodes.discretionary
local ligature_code = glyphcodes.ligature
@@ -412,8 +415,8 @@ local function flattendisk(head,disc)
if replace then
if next then
local tail = find_node_tail(replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
end
return replace, replace
elseif next then
@@ -427,17 +430,17 @@ local function flattendisk(head,disc)
if replace then
local tail = find_node_tail(replace)
if next then
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
end
- setfield(prev,"next",replace)
- setfield(replace,"prev",prev)
+ setnext(prev,replace)
+ setprev(replace,prev)
return head, replace
else
if next then
- setfield(next,"prev",prev)
+ setprev(next,prev)
end
- setfield(prev,"next",next)
+ setnext(prev,next)
return head, next
end
end
@@ -451,14 +454,14 @@ local function appenddisc(disc,list)
local ptail = find_node_tail(post)
local rtail = find_node_tail(replace)
if post then
- setfield(ptail,"next",phead)
- setfield(phead,"prev",ptail)
+ setnext(ptail,phead)
+ setprev(phead,ptail)
else
setfield(disc,"post",phead)
end
if replace then
- setfield(rtail,"next",rhead)
- setfield(rhead,"prev",rtail)
+ setnext(rtail,rhead)
+ setprev(rhead,rtail)
else
setfield(disc,"replace",rhead)
end
@@ -472,24 +475,24 @@ local function markstoligature(kind,lookupname,head,start,stop,char)
else
local prev = getprev(start)
local next = getnext(stop)
- setfield(start,"prev",nil)
- setfield(stop,"next",nil)
+ setprev(start,nil)
+ setnext(stop,nil)
local base = copy_glyph(start)
if head == start then
head = base
end
resetinjection(base)
- setfield(base,"char",char)
- setfield(base,"subtype",ligature_code)
+ setchar(base,char)
+ setsubtype(base,ligature_code)
setfield(base,"components",start)
if prev then
- setfield(prev,"next",base)
+ setnext(prev,base)
end
if next then
- setfield(next,"prev",base)
+ setprev(next,base)
end
- setfield(base,"next",next)
- setfield(base,"prev",prev)
+ setnext(base,next)
+ setprev(base,prev)
return head, base
end
end
@@ -528,7 +531,7 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
end
if start == stop and getchar(start) == char then
resetinjection(start)
- setfield(start,"char",char)
+ setchar(start,char)
return head, start
end
-- needs testing (side effects):
@@ -541,24 +544,24 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
local prev = getprev(start)
local next = getnext(stop)
local comp = start
- setfield(start,"prev",nil)
- setfield(stop,"next",nil)
+ setprev(start,nil)
+ setnext(stop,nil)
local base = copy_glyph(start)
if start == head then
head = base
end
resetinjection(base)
- setfield(base,"char",char)
- setfield(base,"subtype",ligature_code)
+ setchar(base,char)
+ setsubtype(base,ligature_code)
setfield(base,"components",comp) -- start can have components ... do we need to flush?
if prev then
- setfield(prev,"next",base)
+ setnext(prev,base)
end
if next then
- setfield(next,"prev",base)
+ setprev(next,base)
end
- setfield(base,"prev",prev)
- setfield(base,"next",next)
+ setprev(base,prev)
+ setnext(base,next)
if not discfound then
local deletemarks = markflag ~= "mark"
local components = start
@@ -602,8 +605,8 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
end
else
-- discfound ... forget about marks .. probably no scripts that hyphenate and have marks
- local discprev = getfield(discfound,"prev")
- local discnext = getfield(discfound,"next")
+ local discprev = getprev(discfound)
+ local discnext = getnext(discfound)
if discprev and discnext then
-- we assume normalization in context, and don't care about generic ... especially
-- \- can give problems as there we can have a negative char but that won't match
@@ -612,34 +615,34 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
local post = getfield(discfound,"post")
local replace = getfield(discfound,"replace")
if not replace then -- todo: signal simple hyphen
- local prev = getfield(base,"prev")
+ local prev = getprev(base)
local copied = copy_node_list(comp)
- setfield(discnext,"prev",nil) -- also blocks funny assignments
- setfield(discprev,"next",nil) -- also blocks funny assignments
+ setprev(discnext,nil) -- also blocks funny assignments
+ setnext(discprev,nil) -- also blocks funny assignments
if pre then
- setfield(discprev,"next",pre)
- setfield(pre,"prev",discprev)
+ setnext(discprev,pre)
+ setprev(pre,discprev)
end
pre = comp
if post then
local tail = find_node_tail(post)
- setfield(tail,"next",discnext)
- setfield(discnext,"prev",tail)
- setfield(post,"prev",nil)
+ setnext(tail,discnext)
+ setprev(discnext,tail)
+ setprev(post,nil)
else
post = discnext
end
- setfield(prev,"next",discfound)
- setfield(discfound,"prev",prev)
- setfield(discfound,"next",next)
- setfield(next,"prev",discfound)
- setfield(base,"next",nil)
- setfield(base,"prev",nil)
+ setnext(prev,discfound)
+ setprev(discfound,prev)
+ setnext(discfound,next)
+ setprev(next,discfound)
+ setnext(base,nil)
+ setprev(base,nil)
setfield(base,"components",copied)
setfield(discfound,"pre",pre)
setfield(discfound,"post",post)
setfield(discfound,"replace",base)
- setfield(discfound,"subtype",discretionary_code)
+ setsubtype(discfound,discretionary_code)
base = prev -- restart
end
end
@@ -651,7 +654,7 @@ local function multiple_glyphs(head,start,multiple,ignoremarks)
local nofmultiples = #multiple
if nofmultiples > 0 then
resetinjection(start)
- setfield(start,"char",multiple[1])
+ setchar(start,multiple[1])
if nofmultiples > 1 then
local sn = getnext(start)
for k=2,nofmultiples do -- todo: use insert_node
@@ -662,13 +665,13 @@ local function multiple_glyphs(head,start,multiple,ignoremarks)
-- end
local n = copy_node(start) -- ignore components
resetinjection(n)
- setfield(n,"char",multiple[k])
- setfield(n,"prev",start)
- setfield(n,"next",sn)
+ setchar(n,multiple[k])
+ setprev(n,start)
+ setnext(n,sn)
if sn then
- setfield(sn,"prev",n)
+ setprev(sn,n)
end
- setfield(start,"next",n)
+ setnext(start,n)
start = n
end
end
@@ -720,7 +723,7 @@ function handlers.gsub_single(head,start,kind,lookupname,replacement)
logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement))
end
resetinjection(start)
- setfield(start,"char",replacement)
+ setchar(start,replacement)
return head, start, true
end
@@ -732,7 +735,7 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence
logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment)
end
resetinjection(start)
- setfield(start,"char",choice)
+ setchar(start,choice)
else
if trace_alternatives then
logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment)
@@ -830,7 +833,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
else
-- weird but happens (in some arabic font)
resetinjection(start)
- setfield(start,"char",lig)
+ setchar(start,lig)
if trace_ligatures then
logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig))
end
@@ -1207,7 +1210,7 @@ function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,loo
logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement))
end
resetinjection(start)
- setfield(start,"char",replacement)
+ setchar(start,replacement)
return head, start, true
else
return head, start, false
@@ -1238,7 +1241,7 @@ as less as needed but that would also make the code even more messy.</p>
-- repeat -- start x x m x x stop => start m
-- local next = getnext(start)
-- if not marks[getchar(next)] then
--- local components = getfield(next,"components")
+-- local components = getnext(next,"components")
-- if components then -- probably not needed
-- flush_node_list(components)
-- end
@@ -1291,7 +1294,7 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo
logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement))
end
resetinjection(current)
- setfield(current,"char",replacement)
+ setchar(current,replacement)
end
end
return head, start, true
@@ -1368,7 +1371,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext
logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment)
end
resetinjection(start)
- setfield(start,"char",choice)
+ setchar(start,choice)
else
if trace_alternatives then
logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment)
@@ -1936,13 +1939,13 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
local tail = nil
if prev then
tail = prev
- setfield(current,"prev",sweepnode)
+ setprev(current,sweepnode)
else
tail = find_node_tail(head)
end
- setfield(sweepnode,"next",current)
- setfield(head,"prev",nil)
- setfield(tail,"next",nil)
+ setnext(sweepnode,current)
+ setprev(head,nil)
+ setnext(tail,nil)
appenddisc(sweepnode,head)
end
end
@@ -2036,12 +2039,12 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
cprev = getprev(cprev)
end
- setfield(lookaheaddisc,"prev",cprev)
+ setprev(lookaheaddisc,cprev)
if cprev then
- setfield(cprev,"next",lookaheaddisc)
+ setnext(cprev,lookaheaddisc)
end
- setfield(cf,"prev",nil)
- setfield(cl,"next",nil)
+ setprev(cf,nil)
+ setnext(cl,nil)
if startishead then
head = lookaheaddisc
end
@@ -2064,13 +2067,13 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
new, cnew, ok = chainproc(new,cnew,clast,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
end
if pre then
- setfield(cl,"next",pre)
- setfield(pre,"prev",cl)
+ setnext(cl,pre)
+ setprev(pre,cl)
end
if replace then
local tail = find_node_tail(new)
- setfield(tail,"next",replace)
- setfield(replace,"prev",tail)
+ setnext(tail,replace)
+ setprev(replace,tail)
end
setfield(lookaheaddisc,"pre",cf) -- also updates tail
setfield(lookaheaddisc,"replace",new) -- also updates tail
@@ -2092,11 +2095,11 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
cnext = getnext(cnext)
end
if cnext then
- setfield(cnext,"prev",backtrackdisc)
+ setprev(cnext,backtrackdisc)
end
- setfield(backtrackdisc,"next",cnext)
- setfield(cf,"prev",nil)
- setfield(cl,"next",nil)
+ setnext(backtrackdisc,cnext)
+ setprev(cf,nil)
+ setnext(cl,nil)
local replace = getfield(backtrackdisc,"replace")
local post = getfield(backtrackdisc,"post")
local new = copy_node_list(cf)
@@ -2116,15 +2119,15 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
end
if post then
local tail = find_node_tail(post)
- setfield(tail,"next",cf)
- setfield(cf,"prev",tail)
+ setnext(tail,cf)
+ setprev(cf,tail)
else
post = cf
end
if replace then
local tail = find_node_tail(replace)
- setfield(tail,"next",new)
- setfield(new,"prev",tail)
+ setnext(tail,new)
+ setprev(new,tail)
else
replace = new
end
@@ -2700,26 +2703,49 @@ otf.chainhandlers = {
verbose = verbose_handle_contextchain,
}
+local handle_contextchain = nil
+
+-- normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash)
+
+function chained_contextchain(head,start,stop,...)
+ local steps = currentlookup.steps
+ local nofsteps = currentlookup.nofsteps
+ if nofsteps > 1 then
+ reportmoresteps(dataset,sequence)
+ end
+ return handle_contextchain(head,start,...)
+end
+
function otf.setcontextchain(method)
if not method or method == "normal" or not otf.chainhandlers[method] then
- if handlers.contextchain then -- no need for a message while making the format
+ if handle_contextchain then -- no need for a message while making the format
logwarning("installing normal contextchain handler")
end
- handlers.contextchain = normal_handle_contextchain
+ handle_contextchain = normal_handle_contextchain
else
logwarning("installing contextchain handler %a",method)
local handler = otf.chainhandlers[method]
- handlers.contextchain = function(...)
+ handle_contextchain = function(...)
return handler(currentfont,...) -- hm, get rid of ...
end
end
- handlers.gsub_context = handlers.contextchain
- handlers.gsub_contextchain = handlers.contextchain
- handlers.gsub_reversecontextchain = handlers.contextchain
- handlers.gpos_contextchain = handlers.contextchain
- handlers.gpos_context = handlers.contextchain
+
+ handlers.gsub_context = handle_contextchain
+ handlers.gsub_contextchain = handle_contextchain
+ handlers.gsub_reversecontextchain = handle_contextchain
+ handlers.gpos_contextchain = handle_contextchain
+ handlers.gpos_context = handle_contextchain
+
+ handlers.contextchain = handle_contextchain
+
end
+chainprocs.gsub_context = chained_contextchain
+chainprocs.gsub_contextchain = chained_contextchain
+chainprocs.gsub_reversecontextchain = chained_contextchain
+chainprocs.gpos_contextchain = chained_contextchain
+chainprocs.gpos_context = chained_contextchain
+
otf.setcontextchain()
local missing = { } -- we only report once
@@ -2759,20 +2785,33 @@ end)
-- fonts.hashes.lookups = lookuphashes
-local autofeatures = fonts.analyzers.features -- was: constants
+local autofeatures = fonts.analyzers.features
+local featuretypes = otf.tables.featuretypes
+local defaultscript = otf.features.checkeddefaultscript
+local defaultlanguage = otf.features.checkeddefaultlanguage
-local function initialize(sequence,script,language,enabled)
+local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
local features = sequence.features
if features then
local order = sequence.order
if order then
- for i=1,#order do --
- local kind = order[i] --
+ local featuretype = featuretypes[sequence.type or "unknown"]
+ for i=1,#order do
+ local kind = order[i]
local valid = enabled[kind]
if valid then
- local scripts = features[kind] --
- local languages = scripts[script] or scripts[wildcard]
- if languages and (languages[language] or languages[wildcard]) then
+ local scripts = features[kind]
+ local languages = scripts and (
+ scripts[script] or
+ scripts[wildcard] or
+ (autoscript and defaultscript(featuretype,autoscript,scripts))
+ )
+ local enabled = languages and (
+ languages[language] or
+ languages[wildcard] or
+ (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
+ )
+ if enabled then
return { valid, autofeatures[kind] or false, sequence, kind }
end
end
@@ -2785,11 +2824,13 @@ local function initialize(sequence,script,language,enabled)
end
function otf.dataset(tfmdata,font) -- generic variant, overloaded in context
- local shared = tfmdata.shared
- local properties = tfmdata.properties
- local language = properties.language or "dflt"
- local script = properties.script or "dflt"
- local enabled = shared.features
+ local shared = tfmdata.shared
+ local properties = tfmdata.properties
+ local language = properties.language or "dflt"
+ local script = properties.script or "dflt"
+ local enabled = shared.features
+ local autoscript = enabled and enabled.autoscript
+ local autolanguage = enabled and enabled.autolanguage
local res = resolved[font]
if not res then
res = { }
@@ -2808,7 +2849,7 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context
rs[language] = rl
local sequences = tfmdata.resources.sequences
for s=1,#sequences do
- local v = enabled and initialize(sequences[s],script,language,enabled)
+ local v = enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
if v then
rl[#rl+1] = v
end
@@ -2856,11 +2897,11 @@ local function kernrun(disc,run)
-- go on
elseif prev then
local nest = getprev(pre)
- setfield(pre,"prev",prev)
- setfield(prev,"next",pre)
+ setprev(pre,prev)
+ setnext(prev,pre)
run(prevmarks,"preinjections")
- setfield(pre,"prev",nest)
- setfield(prev,"next",disc)
+ setprev(pre,nest)
+ setnext(prev,disc)
else
run(pre,"preinjections")
end
@@ -2869,48 +2910,48 @@ local function kernrun(disc,run)
-- go on
elseif next then
local tail = find_node_tail(post)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
run(post,"postinjections",next)
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setnext(tail,nil)
+ setprev(next,disc)
else
run(post,"postinjections")
end
--
if not replace and prev and next then
-- this should be already done by discfound
- setfield(prev,"next",next)
- setfield(next,"prev",prev)
+ setnext(prev,next)
+ setprev(next,prev)
run(prevmarks,"injections",next)
- setfield(prev,"next",disc)
- setfield(next,"prev",disc)
+ setnext(prev,disc)
+ setprev(next,disc)
elseif prev and next then
local tail = find_node_tail(replace)
local nest = getprev(replace)
- setfield(replace,"prev",prev)
- setfield(prev,"next",replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setprev(replace,prev)
+ setnext(prev,replace)
+ setnext(tail,next)
+ setprev(next,tail)
run(prevmarks,"replaceinjections",next)
- setfield(replace,"prev",nest)
- setfield(prev,"next",disc)
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setprev(replace,nest)
+ setnext(prev,disc)
+ setnext(tail,nil)
+ setprev(next,disc)
elseif prev then
local nest = getprev(replace)
- setfield(replace,"prev",prev)
- setfield(prev,"next",replace)
+ setprev(replace,prev)
+ setnext(prev,replace)
run(prevmarks,"replaceinjections")
- setfield(replace,"prev",nest)
- setfield(prev,"next",disc)
+ setprev(replace,nest)
+ setnext(prev,disc)
elseif next then
local tail = find_node_tail(replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
run(replace,"replaceinjections",next)
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setnext(tail,nil)
+ setprev(next,disc)
else
run(replace,"replaceinjections")
end
@@ -2967,21 +3008,21 @@ local function testrun(disc,trun,crun) -- use helper
-- only look ahead
local tail = find_node_tail(replace)
-- local nest = getprev(replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
if trun(replace,next) then
setfield(disc,"replace",nil) -- beware, side effects of nest so first
- setfield(prev,"next",replace)
- setfield(replace,"prev",prev)
- setfield(next,"prev",tail)
- setfield(tail,"next",next)
- setfield(disc,"prev",nil)
- setfield(disc,"next",nil)
+ setnext(prev,replace)
+ setprev(replace,prev)
+ setprev(next,tail)
+ setnext(tail,next)
+ setprev(disc,nil)
+ setnext(disc,nil)
flush_node_list(disc)
return replace -- restart
else
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setnext(tail,nil)
+ setprev(next,disc)
end
else
-- weird case
@@ -3003,11 +3044,11 @@ local function discrun(disc,drun,krun)
report_run("disc") -- will be more detailed
end
if next and prev then
- setfield(prev,"next",next)
- -- setfield(next,"prev",prev)
+ setnext(prev,next)
+ -- setprev(next,prev)
drun(prev)
- setfield(prev,"next",disc)
- -- setfield(next,"prev",disc)
+ setnext(prev,disc)
+ -- setprev(next,disc)
end
--
local pre = getfield(disc,"pre")
@@ -3015,11 +3056,11 @@ local function discrun(disc,drun,krun)
-- go on
elseif prev then
local nest = getprev(pre)
- setfield(pre,"prev",prev)
- setfield(prev,"next",pre)
+ setprev(pre,prev)
+ setnext(prev,pre)
krun(prev,"preinjections")
- setfield(pre,"prev",nest)
- setfield(prev,"next",disc)
+ setprev(pre,nest)
+ setnext(prev,disc)
else
krun(pre,"preinjections")
end
@@ -3319,6 +3360,41 @@ local function featuresprocessor(head,font,attr)
end
elseif id == math_code then
start = getnext(end_of_math(start))
+ elseif id == dir_code then
+ local dir = getfield(start,"dir")
+ if dir == "+TLT" then
+ topstack = topstack + 1
+ dirstack[topstack] = dir
+ rlmode = 1
+ elseif dir == "+TRT" then
+ topstack = topstack + 1
+ dirstack[topstack] = dir
+ rlmode = -1
+ elseif dir == "-TLT" or dir == "-TRT" then
+ topstack = topstack - 1
+ rlmode = dirstack[topstack] == "+TRT" and -1 or 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
+ start = getnext(start)
+ elseif id == localpar_code then
+ local dir = getfield(start,"dir")
+ if dir == "TRT" then
+ rlparmode = -1
+ elseif dir == "TLT" then
+ rlparmode = 1
+ else
+ rlparmode = 0
+ end
+ -- one might wonder if the par dir should be looked at, so we might as well drop the next line
+ rlmode = rlparmode
+ if trace_directions then
+ report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode)
+ end
+ start = getnext(start)
else
start = getnext(start)
end
@@ -3554,6 +3630,40 @@ local function featuresprocessor(head,font,attr)
end
elseif id == math_code then
start = getnext(end_of_math(start))
+ elseif id == dir_code then
+ local dir = getfield(start,"dir")
+ if dir == "+TLT" then
+ topstack = topstack + 1
+ dirstack[topstack] = dir
+ rlmode = 1
+ elseif dir == "+TRT" then
+ topstack = topstack + 1
+ dirstack[topstack] = dir
+ rlmode = -1
+ elseif dir == "-TLT" or dir == "-TRT" then
+ topstack = topstack - 1
+ rlmode = dirstack[topstack] == "+TRT" and -1 or 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
+ start = getnext(start)
+ elseif id == 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 = getnext(start)
else
start = getnext(start)
end
@@ -3723,10 +3833,10 @@ local function split(replacement,original)
return result
end
-local valid = {
- coverage = { chainsub = true, chainpos = true, contextsub = true },
+local valid = { -- does contextpos work?
+ coverage = { chainsub = true, chainpos = true, contextsub = true, contextpos = true },
reversecoverage = { reversesub = true },
- glyphs = { chainsub = true, chainpos = true },
+ glyphs = { chainsub = true, chainpos = true, contextsub = true, contextpos = true },
}
local function prepare_contextchains(tfmdata)
@@ -3784,7 +3894,10 @@ local function prepare_contextchains(tfmdata)
sequence[nofsequences] = after[n]
end
end
+--[[phg-- Hard patch: This crashes, see https://github.com/lualatex/luaotfload/issues/303
if sequence[1] then
+--phg]]--
+ if sequence[start] then
-- Replacements only happen with reverse lookups as they are single only. We
-- could pack them into current (replacement value instead of true) and then
-- use sequence[start] instead but it's somewhat ugly.
diff --git a/src/fontloader/misc/fontloader-fonts-def.lua b/src/fontloader/misc/fontloader-fonts-def.lua
index 0c2f0db..f0941ec 100644
--- a/src/fontloader/misc/fontloader-fonts-def.lua
+++ b/src/fontloader/misc/fontloader-fonts-def.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['luatex-font-def'] = {
+if not modules then modules = { } end modules ['luatex-fonts-def'] = {
version = 1.001,
comment = "companion to luatex-*.tex",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
diff --git a/src/fontloader/misc/fontloader-fonts-ota.lua b/src/fontloader/misc/fontloader-fonts-ota.lua
index f083fe0..256ead5 100644
--- a/src/fontloader/misc/fontloader-fonts-ota.lua
+++ b/src/fontloader/misc/fontloader-fonts-ota.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['font-otx'] = {
+if not modules then modules = { } end modules ['luatex-fonts-ota'] = {
version = 1.001,
comment = "companion to font-otf.lua (analysing)",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -24,7 +24,6 @@ local methods = allocate()
analyzers.initializers = initializers
analyzers.methods = methods
-analyzers.useunicodemarks = false
local a_state = attributes.private('state')
@@ -98,8 +97,9 @@ local features = {
pstf = s_pstf,
}
-analyzers.states = states
-analyzers.features = features
+analyzers.states = states
+analyzers.features = features
+analyzers.useunicodemarks = false
-- todo: analyzers per script/lang, cross font, so we need an font id hash -> script
-- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace
@@ -117,7 +117,10 @@ function analyzers.setstate(head,font)
local char = getchar(current)
local d = descriptions[char]
if d then
- if d.class == "mark" or (useunicodemarks and categories[char] == "mn") then
+ if d.class == "mark" then
+ done = true
+ setprop(current,a_state,s_mark)
+ elseif useunicodemarks and categories[char] == "mn" then
done = true
setprop(current,a_state,s_mark)
elseif n == 0 then
@@ -136,7 +139,9 @@ function analyzers.setstate(head,font)
first, last, n = nil, nil, 0
end
elseif id == disc_code then
- -- always in the middle
+ -- always in the middle .. it doesn't make much sense to assign a property
+ -- here ... we might at some point decide to flag the components when present
+ -- but even then it's kind of bogus
setprop(current,a_state,s_medi)
last = current
else -- finish
@@ -213,17 +218,6 @@ registerotffeature {
methods.latn = analyzers.setstate
--- This info eventually can go into char-def and we will have a state
--- table for generic then (unicode recognized all states but in practice
--- only has only
---
--- isolated : isol
--- final : isol_fina
--- medial : isol_fina_medi_init
---
--- so in practice, without analyzer it's rather useless info which is
--- why having it in char-def makes only sense for special purposes (like)
--- like tracing cq. visualizing.
local tatweel = 0x0640
local zwnj = 0x200C
@@ -344,8 +338,6 @@ local medial = { -- isol_fina_medi_init
local arab_warned = { }
--- todo: gref
-
local function warning(current,what)
local char = getchar(current)
if not arab_warned[char] then
diff --git a/src/fontloader/misc/fontloader-fonts.lua b/src/fontloader/misc/fontloader-fonts.lua
index f18ba35..2e34fb8 100644
--- a/src/fontloader/misc/fontloader-fonts.lua
+++ b/src/fontloader/misc/fontloader-fonts.lua
@@ -215,9 +215,11 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-oti.lua')
loadmodule('font-otf.lua')
loadmodule('font-otb.lua')
- loadmodule('luatex-fonts-inj.lua') -- normally the same as font-inj.lua
+ ----------('luatex-fonts-inj.lua') -- normally the same as font-inj.lua / beware loadmodule is parsed
+ loadmodule('font-inj.lua')
loadmodule('luatex-fonts-ota.lua')
- loadmodule('luatex-fonts-otn.lua') -- normally the same as font-otn.lua
+ ----------('luatex-fonts-otn.lua') -- normally the same as font-otn.lua / beware loadmodule is parsed
+ loadmodule('font-otn.lua')
loadmodule('font-otp.lua')
loadmodule('luatex-fonts-lua.lua')
loadmodule('font-def.lua') -- this code (stripped) might end up in luatex-fonts-def.lua
diff --git a/src/fontloader/misc/fontloader-languages.lua b/src/fontloader/misc/fontloader-languages.lua
index 1ea8c1f..cecd60c 100644
--- a/src/fontloader/misc/fontloader-languages.lua
+++ b/src/fontloader/misc/fontloader-languages.lua
@@ -16,28 +16,33 @@ function languages.loadpatterns(tag)
if not loaded[tag] then
loaded[tag] = 0
local filename = kpse.find_file("lang-" .. tag .. ".lua")
- if filename and filename == "" then
- print("<unknown language file for: " .. tag .. ">")
+ if not filename or filename == "" then
+ texio.write("<unknown language file for: " .. tag .. ">")
else
local whatever = loadfile(filename)
if type(whatever) == "function" then
whatever = whatever()
if type(whatever) == "table" then
+ texio.write("<language file: " .. tag .. ">")
local characters = whatever.patterns.characters or ""
local patterns = whatever.patterns.data or ""
local exceptions = whatever.exceptions.data or ""
- local language = lang.new()
for b in string.utfvalues(characters) do
+ -- what about uppercase
+-- lang.sethjcode(b,b)
tex.setlccode(b,b)
end
+ local language = lang.new()
lang.patterns(language, patterns)
lang.hyphenation(language, exceptions)
loaded[tag] = lang.id(language)
else
- print("<invalid language table: " .. tag .. ">")
+ texio.write("<invalid language table: " .. tag .. ">")
+ os.exit()
end
else
- print("<invalid language file: " .. tag .. ">")
+ texio.write("<invalid language file: " .. tag .. ">")
+ os.exit()
end
end
end
diff --git a/src/fontloader/misc/fontloader-languages.tex b/src/fontloader/misc/fontloader-languages.tex
index 9778da3..a087b30 100644
--- a/src/fontloader/misc/fontloader-languages.tex
+++ b/src/fontloader/misc/fontloader-languages.tex
@@ -8,6 +8,8 @@
%D Cf. discussion on \CONTEXT\ list:
+% \savinghyphcodes1
+
\directlua {
dofile(kpse.find_file("luatex-languages.lua","tex"))
}
diff --git a/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua
index ae36617..46de1d0 100644
--- a/src/fontloader/runtime/fontloader-reference.lua
+++ b/src/fontloader/runtime/fontloader-reference.lua
@@ -1,6 +1,6 @@
--- merged file : luatex-fonts-merged.lua
--- parent file : luatex-fonts.lua
--- merge date : 11/19/15 19:13:15
+-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
+-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
+-- merge date : 12/21/15 16:29:15
do -- begin closure to overcome local limits and interference
@@ -3901,15 +3901,21 @@ end
nodes={}
nodes.pool={}
nodes.handlers={}
-local nodecodes={} for k,v in next,node.types () do nodecodes[string.gsub(v,"_","")]=k end
-local whatcodes={} for k,v in next,node.whatsits() do whatcodes[string.gsub(v,"_","")]=k end
-local glyphcodes={ [0]="character","glyph","ligature","ghost","left","right" }
-local disccodes={ [0]="discretionary","explicit","automatic","regular","first","second" }
-for i=0,#glyphcodes do glyphcodes[glyphcodes[i]]=i end
-for i=0,#disccodes do disccodes [disccodes [i]]=i end
+local nodecodes={}
+local glyphcodes=node.subtypes("glyph")
+local disccodes=node.subtypes("disc")
+for k,v in next,node.types() do
+ v=string.gsub(v,"_","")
+ nodecodes[k]=v
+ nodecodes[v]=k
+end
+for i=0,#glyphcodes do
+ glyphcodes[glyphcodes[i]]=i
+end
+for i=0,#disccodes do
+ disccodes[disccodes[i]]=i
+end
nodes.nodecodes=nodecodes
-nodes.whatcodes=whatcodes
-nodes.whatsitcodes=whatcodes
nodes.glyphcodes=glyphcodes
nodes.disccodes=disccodes
local free_node=node.free
@@ -3973,7 +3979,6 @@ 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
@@ -4002,13 +4007,27 @@ local setfield=direct.setfield
nuts.getfield=getfield
nuts.setfield=setfield
nuts.getnext=direct.getnext
+nuts.setnext=direct.setnext
nuts.getprev=direct.getprev
+nuts.setprev=direct.setprev
+nuts.getboth=direct.getboth
+nuts.setboth=direct.setboth
nuts.getid=direct.getid
-nuts.getattr=getfield
+nuts.getattr=direct.get_attribute or direct.has_attribute or getfield
nuts.setattr=setfield
nuts.getfont=direct.getfont
+nuts.setfont=direct.setfont
nuts.getsubtype=direct.getsubtype
+nuts.setsubtype=direct.setsubtype or function(n,s) setfield(n,"subtype",s) end
nuts.getchar=direct.getchar
+nuts.setchar=direct.setchar
+nuts.getdisc=direct.getdisc
+nuts.setdisc=direct.setdisc
+nuts.setlink=direct.setlink
+nuts.getlist=direct.getlist
+nuts.setlist=direct.setlist or function(n,l) setfield(n,"list",l) end
+nuts.getleader=direct.getleader
+nuts.setleader=direct.setleader or function(n,l) setfield(n,"leader",l) end
nuts.insert_before=direct.insert_before
nuts.insert_after=direct.insert_after
nuts.delete=direct.delete
@@ -4022,6 +4041,9 @@ nuts.is_node=direct.is_node
nuts.end_of_math=direct.end_of_math
nuts.traverse=direct.traverse
nuts.traverse_id=direct.traverse_id
+nuts.traverse_char=direct.traverse_char
+nuts.ligaturing=direct.ligaturing
+nuts.kerning=direct.kerning
nuts.getprop=nuts.getattr
nuts.setprop=nuts.setattr
local new_nut=direct.new
@@ -7048,8 +7070,9 @@ local fonts=fonts
local constructors=fonts.constructors
local otf=constructors.newhandler("otf")
local otffeatures=constructors.newfeatures("otf")
-local otftables=otf.tables
local registerotffeature=otffeatures.register
+local otftables=otf.tables or {}
+otf.tables=otftables
local allocate=utilities.storage.allocate
registerotffeature {
name="features",
@@ -7113,6 +7136,64 @@ registerotffeature {
node=setscript,
}
}
+otftables.featuretypes=allocate {
+ gpos_single="position",
+ gpos_pair="position",
+ gpos_cursive="position",
+ gpos_mark2base="position",
+ gpos_mark2ligature="position",
+ gpos_mark2mark="position",
+ gpos_context="position",
+ gpos_contextchain="position",
+ gsub_single="substitution",
+ gsub_multiple="substitution",
+ gsub_alternate="substitution",
+ gsub_ligature="substitution",
+ gsub_context="substitution",
+ gsub_contextchain="substitution",
+ gsub_reversecontextchain="substitution",
+ gsub_reversesub="substitution",
+}
+function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts)
+ if featuretype=="position" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="position" or autoscript==true then
+ return default
+ else
+ report_otf("script feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=scripts.dflt
+ if default then
+ if autoscript=="substitution" or autoscript==true then
+ return default
+ end
+ end
+ end
+end
+function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
+ if featuretype=="position" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="position" or autolanguage==true then
+ return default
+ else
+ report_otf("language feature %s not applied, enable default positioning")
+ end
+ else
+ end
+ elseif featuretype=="substitution" then
+ local default=languages.dflt
+ if default then
+ if autolanguage=="substitution" or autolanguage==true then
+ return default
+ end
+ end
+ end
+end
end -- closure
@@ -7156,7 +7237,7 @@ local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
otf.glists={ "gsub","gpos" }
-otf.version=2.819
+otf.version=2.820
otf.cache=containers.define("fonts","otf",otf.version,true)
local hashes=fonts.hashes
local definers=fonts.definers
@@ -9492,7 +9573,7 @@ otf.coverup={
kern=justset,
},
register=function(coverage,lookuptype,format,feature,n,descriptions,resources)
- local name=formatters["ctx_%s_%s"](feature,n)
+ local name=formatters["ctx_%s_%s_%s"](feature,lookuptype,n)
if lookuptype=="kern" then
resources.lookuptypes[name]="position"
else
@@ -10224,8 +10305,10 @@ function injections.resetcounts()
end
function injections.reset(n)
local p=rawget(properties,n)
- if p and rawget(p,"injections") then
- p.injections=nil
+ if p then
+ p.injections=false
+ else
+ properties[n]=false
end
end
function injections.copy(target,source)
@@ -10242,10 +10325,17 @@ function injections.copy(target,source)
injections=si,
}
end
+ elseif tp then
+ tp.injections=false
else
- if tp then
- tp.injections=nil
- end
+ properties[target]={ injections={} }
+ end
+ else
+ local tp=rawget(properties,target)
+ if tp then
+ tp.injections=false
+ else
+ properties[target]=false
end
end
end
@@ -10480,10 +10570,11 @@ local function show(n,what,nested,symbol)
local markx=i.markx or 0
local marky=i.marky or 0
local markdir=i.markdir or 0
- local markbase=i.markbase or 0
+ local markbase=i.markbase or 0
local cursivex=i.cursivex or 0
local cursivey=i.cursivey or 0
local ligaindex=i.ligaindex or 0
+ local cursbase=i.cursiveanchor
local margin=nested and 4 or 2
if rightkern~=0 or yoffset~=0 then
report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset)
@@ -10494,7 +10585,13 @@ local function show(n,what,nested,symbol)
report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no")
end
if cursivex~=0 or cursivey~=0 then
- report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ if cursbase then
+ report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ else
+ report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey)
+ end
+ elseif cursbase then
+ report_injections("%w%s curs: base",margin,symbol)
end
if ligaindex~=0 then
report_injections("%w%s liga: index %i",margin,symbol,ligaindex)
@@ -11177,7 +11274,7 @@ end -- closure
do -- begin closure to overcome local limits and interference
-if not modules then modules={} end modules ['font-otx']={
+if not modules then modules={} end modules ['luatex-fonts-ota']={
version=1.001,
comment="companion to font-otf.lua (analysing)",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -11194,7 +11291,6 @@ local initializers=allocate()
local methods=allocate()
analyzers.initializers=initializers
analyzers.methods=methods
-analyzers.useunicodemarks=false
local a_state=attributes.private('state')
local nuts=nodes.nuts
local tonut=nuts.tonut
@@ -11250,6 +11346,7 @@ local features={
}
analyzers.states=states
analyzers.features=features
+analyzers.useunicodemarks=false
function analyzers.setstate(head,font)
local useunicodemarks=analyzers.useunicodemarks
local tfmdata=fontdata[font]
@@ -11263,7 +11360,10 @@ function analyzers.setstate(head,font)
local char=getchar(current)
local d=descriptions[char]
if d then
- if d.class=="mark" or (useunicodemarks and categories[char]=="mn") then
+ if d.class=="mark" then
+ done=true
+ setprop(current,a_state,s_mark)
+ elseif useunicodemarks and categories[char]=="mn" then
done=true
setprop(current,a_state,s_mark)
elseif n==0 then
@@ -11612,7 +11712,9 @@ local tonut=nuts.tonut
local getfield=nuts.getfield
local setfield=nuts.setfield
local getnext=nuts.getnext
+local setnext=nuts.setnext
local getprev=nuts.getprev
+local setprev=nuts.setprev
local getid=nuts.getid
local getattr=nuts.getattr
local setattr=nuts.setattr
@@ -11620,7 +11722,9 @@ local getprop=nuts.getprop
local setprop=nuts.setprop
local getfont=nuts.getfont
local getsubtype=nuts.getsubtype
+local setsubtype=nuts.setsubtype
local getchar=nuts.getchar
+local setchar=nuts.setchar
local insert_node_before=nuts.insert_before
local insert_node_after=nuts.insert_after
local delete_node=nuts.delete
@@ -11639,15 +11743,14 @@ local zwj=0x200D
local wildcard="*"
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
local math_code=nodecodes.math
-local dir_code=whatcodes.dir
-local localpar_code=whatcodes.localpar
+local dir_code=nodecodes.dir
+local localpar_code=nodecodes.localpar
local discretionary_code=disccodes.discretionary
local ligature_code=glyphcodes.ligature
local privateattribute=attributes.private
@@ -11767,8 +11870,8 @@ local function flattendisk(head,disc)
if replace then
if next then
local tail=find_node_tail(replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
end
return replace,replace
elseif next then
@@ -11782,17 +11885,17 @@ local function flattendisk(head,disc)
if replace then
local tail=find_node_tail(replace)
if next then
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
end
- setfield(prev,"next",replace)
- setfield(replace,"prev",prev)
+ setnext(prev,replace)
+ setprev(replace,prev)
return head,replace
else
if next then
- setfield(next,"prev",prev)
+ setprev(next,prev)
end
- setfield(prev,"next",next)
+ setnext(prev,next)
return head,next
end
end
@@ -11805,14 +11908,14 @@ local function appenddisc(disc,list)
local ptail=find_node_tail(post)
local rtail=find_node_tail(replace)
if post then
- setfield(ptail,"next",phead)
- setfield(phead,"prev",ptail)
+ setnext(ptail,phead)
+ setprev(phead,ptail)
else
setfield(disc,"post",phead)
end
if replace then
- setfield(rtail,"next",rhead)
- setfield(rhead,"prev",rtail)
+ setnext(rtail,rhead)
+ setprev(rhead,rtail)
else
setfield(disc,"replace",rhead)
end
@@ -11823,24 +11926,24 @@ local function markstoligature(kind,lookupname,head,start,stop,char)
else
local prev=getprev(start)
local next=getnext(stop)
- setfield(start,"prev",nil)
- setfield(stop,"next",nil)
+ setprev(start,nil)
+ setnext(stop,nil)
local base=copy_glyph(start)
if head==start then
head=base
end
resetinjection(base)
- setfield(base,"char",char)
- setfield(base,"subtype",ligature_code)
+ setchar(base,char)
+ setsubtype(base,ligature_code)
setfield(base,"components",start)
if prev then
- setfield(prev,"next",base)
+ setnext(prev,base)
end
if next then
- setfield(next,"prev",base)
+ setprev(next,base)
end
- setfield(base,"next",next)
- setfield(base,"prev",prev)
+ setnext(base,next)
+ setprev(base,prev)
return head,base
end
end
@@ -11868,7 +11971,7 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
end
if start==stop and getchar(start)==char then
resetinjection(start)
- setfield(start,"char",char)
+ setchar(start,char)
return head,start
end
local components=getfield(start,"components")
@@ -11877,24 +11980,24 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
local prev=getprev(start)
local next=getnext(stop)
local comp=start
- setfield(start,"prev",nil)
- setfield(stop,"next",nil)
+ setprev(start,nil)
+ setnext(stop,nil)
local base=copy_glyph(start)
if start==head then
head=base
end
resetinjection(base)
- setfield(base,"char",char)
- setfield(base,"subtype",ligature_code)
+ setchar(base,char)
+ setsubtype(base,ligature_code)
setfield(base,"components",comp)
if prev then
- setfield(prev,"next",base)
+ setnext(prev,base)
end
if next then
- setfield(next,"prev",base)
+ setprev(next,base)
end
- setfield(base,"prev",prev)
- setfield(base,"next",next)
+ setprev(base,prev)
+ setnext(base,next)
if not discfound then
local deletemarks=markflag~="mark"
local components=start
@@ -11934,41 +12037,41 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun
start=getnext(start)
end
else
- local discprev=getfield(discfound,"prev")
- local discnext=getfield(discfound,"next")
+ local discprev=getprev(discfound)
+ local discnext=getnext(discfound)
if discprev and discnext then
local pre=getfield(discfound,"pre")
local post=getfield(discfound,"post")
local replace=getfield(discfound,"replace")
if not replace then
- local prev=getfield(base,"prev")
+ local prev=getprev(base)
local copied=copy_node_list(comp)
- setfield(discnext,"prev",nil)
- setfield(discprev,"next",nil)
+ setprev(discnext,nil)
+ setnext(discprev,nil)
if pre then
- setfield(discprev,"next",pre)
- setfield(pre,"prev",discprev)
+ setnext(discprev,pre)
+ setprev(pre,discprev)
end
pre=comp
if post then
local tail=find_node_tail(post)
- setfield(tail,"next",discnext)
- setfield(discnext,"prev",tail)
- setfield(post,"prev",nil)
+ setnext(tail,discnext)
+ setprev(discnext,tail)
+ setprev(post,nil)
else
post=discnext
end
- setfield(prev,"next",discfound)
- setfield(discfound,"prev",prev)
- setfield(discfound,"next",next)
- setfield(next,"prev",discfound)
- setfield(base,"next",nil)
- setfield(base,"prev",nil)
+ setnext(prev,discfound)
+ setprev(discfound,prev)
+ setnext(discfound,next)
+ setprev(next,discfound)
+ setnext(base,nil)
+ setprev(base,nil)
setfield(base,"components",copied)
setfield(discfound,"pre",pre)
setfield(discfound,"post",post)
setfield(discfound,"replace",base)
- setfield(discfound,"subtype",discretionary_code)
+ setsubtype(discfound,discretionary_code)
base=prev
end
end
@@ -11979,19 +12082,19 @@ local function multiple_glyphs(head,start,multiple,ignoremarks)
local nofmultiples=#multiple
if nofmultiples>0 then
resetinjection(start)
- setfield(start,"char",multiple[1])
+ setchar(start,multiple[1])
if nofmultiples>1 then
local sn=getnext(start)
for k=2,nofmultiples do
local n=copy_node(start)
resetinjection(n)
- setfield(n,"char",multiple[k])
- setfield(n,"prev",start)
- setfield(n,"next",sn)
+ setchar(n,multiple[k])
+ setprev(n,start)
+ setnext(n,sn)
if sn then
- setfield(sn,"prev",n)
+ setprev(sn,n)
end
- setfield(start,"next",n)
+ setnext(start,n)
start=n
end
end
@@ -12039,7 +12142,7 @@ function handlers.gsub_single(head,start,kind,lookupname,replacement)
logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement))
end
resetinjection(start)
- setfield(start,"char",replacement)
+ setchar(start,replacement)
return head,start,true
end
function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence)
@@ -12050,7 +12153,7 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence
logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment)
end
resetinjection(start)
- setfield(start,"char",choice)
+ setchar(start,choice)
else
if trace_alternatives then
logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment)
@@ -12144,7 +12247,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence)
end
else
resetinjection(start)
- setfield(start,"char",lig)
+ setchar(start,lig)
if trace_ligatures then
logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig))
end
@@ -12471,7 +12574,7 @@ function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,loo
logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement))
end
resetinjection(start)
- setfield(start,"char",replacement)
+ setchar(start,replacement)
return head,start,true
else
return head,start,false
@@ -12503,7 +12606,7 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo
logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement))
end
resetinjection(current)
- setfield(current,"char",replacement)
+ setchar(current,replacement)
end
end
return head,start,true
@@ -12561,7 +12664,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext
logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment)
end
resetinjection(start)
- setfield(start,"char",choice)
+ setchar(start,choice)
else
if trace_alternatives then
logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment)
@@ -13056,13 +13159,13 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
local tail=nil
if prev then
tail=prev
- setfield(current,"prev",sweepnode)
+ setprev(current,sweepnode)
else
tail=find_node_tail(head)
end
- setfield(sweepnode,"next",current)
- setfield(head,"prev",nil)
- setfield(tail,"next",nil)
+ setnext(sweepnode,current)
+ setprev(head,nil)
+ setnext(tail,nil)
appenddisc(sweepnode,head)
end
end
@@ -13150,12 +13253,12 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
startishead=cf==head
cprev=getprev(cprev)
end
- setfield(lookaheaddisc,"prev",cprev)
+ setprev(lookaheaddisc,cprev)
if cprev then
- setfield(cprev,"next",lookaheaddisc)
+ setnext(cprev,lookaheaddisc)
end
- setfield(cf,"prev",nil)
- setfield(cl,"next",nil)
+ setprev(cf,nil)
+ setnext(cl,nil)
if startishead then
head=lookaheaddisc
end
@@ -13177,13 +13280,13 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
new,cnew,ok=chainproc(new,cnew,clast,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence)
end
if pre then
- setfield(cl,"next",pre)
- setfield(pre,"prev",cl)
+ setnext(cl,pre)
+ setprev(pre,cl)
end
if replace then
local tail=find_node_tail(new)
- setfield(tail,"next",replace)
- setfield(replace,"prev",tail)
+ setnext(tail,replace)
+ setprev(replace,tail)
end
setfield(lookaheaddisc,"pre",cf)
setfield(lookaheaddisc,"replace",new)
@@ -13201,11 +13304,11 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
cnext=getnext(cnext)
end
if cnext then
- setfield(cnext,"prev",backtrackdisc)
+ setprev(cnext,backtrackdisc)
end
- setfield(backtrackdisc,"next",cnext)
- setfield(cf,"prev",nil)
- setfield(cl,"next",nil)
+ setnext(backtrackdisc,cnext)
+ setprev(cf,nil)
+ setnext(cl,nil)
local replace=getfield(backtrackdisc,"replace")
local post=getfield(backtrackdisc,"post")
local new=copy_node_list(cf)
@@ -13225,15 +13328,15 @@ local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlooku
end
if post then
local tail=find_node_tail(post)
- setfield(tail,"next",cf)
- setfield(cf,"prev",tail)
+ setnext(tail,cf)
+ setprev(cf,tail)
else
post=cf
end
if replace then
local tail=find_node_tail(replace)
- setfield(tail,"next",new)
- setfield(new,"prev",tail)
+ setnext(tail,new)
+ setprev(new,tail)
else
replace=new
end
@@ -13761,25 +13864,40 @@ otf.chainhandlers={
normal=normal_handle_contextchain,
verbose=verbose_handle_contextchain,
}
+local handle_contextchain=nil
+function chained_contextchain(head,start,stop,...)
+ local steps=currentlookup.steps
+ local nofsteps=currentlookup.nofsteps
+ if nofsteps>1 then
+ reportmoresteps(dataset,sequence)
+ end
+ return handle_contextchain(head,start,...)
+end
function otf.setcontextchain(method)
if not method or method=="normal" or not otf.chainhandlers[method] then
- if handlers.contextchain then
+ if handle_contextchain then
logwarning("installing normal contextchain handler")
end
- handlers.contextchain=normal_handle_contextchain
+ handle_contextchain=normal_handle_contextchain
else
logwarning("installing contextchain handler %a",method)
local handler=otf.chainhandlers[method]
- handlers.contextchain=function(...)
+ handle_contextchain=function(...)
return handler(currentfont,...)
end
end
- handlers.gsub_context=handlers.contextchain
- handlers.gsub_contextchain=handlers.contextchain
- handlers.gsub_reversecontextchain=handlers.contextchain
- handlers.gpos_contextchain=handlers.contextchain
- handlers.gpos_context=handlers.contextchain
+ handlers.gsub_context=handle_contextchain
+ handlers.gsub_contextchain=handle_contextchain
+ handlers.gsub_reversecontextchain=handle_contextchain
+ handlers.gpos_contextchain=handle_contextchain
+ handlers.gpos_context=handle_contextchain
+ handlers.contextchain=handle_contextchain
end
+chainprocs.gsub_context=chained_contextchain
+chainprocs.gsub_contextchain=chained_contextchain
+chainprocs.gsub_reversecontextchain=chained_contextchain
+chainprocs.gpos_contextchain=chained_contextchain
+chainprocs.gpos_context=chained_contextchain
otf.setcontextchain()
local missing={}
local function logprocess(...)
@@ -13807,19 +13925,32 @@ setmetatableindex(lookuphashes,function(t,font)
t[font]=lookuphash
return lookuphash
end)
-local autofeatures=fonts.analyzers.features
-local function initialize(sequence,script,language,enabled)
+local autofeatures=fonts.analyzers.features
+local featuretypes=otf.tables.featuretypes
+local defaultscript=otf.features.checkeddefaultscript
+local defaultlanguage=otf.features.checkeddefaultlanguage
+local function initialize(sequence,script,language,enabled,autoscript,autolanguage)
local features=sequence.features
if features then
local order=sequence.order
if order then
- for i=1,#order do
- local kind=order[i]
+ local featuretype=featuretypes[sequence.type or "unknown"]
+ for i=1,#order do
+ local kind=order[i]
local valid=enabled[kind]
if valid then
- local scripts=features[kind]
- local languages=scripts[script] or scripts[wildcard]
- if languages and (languages[language] or languages[wildcard]) then
+ local scripts=features[kind]
+ local languages=scripts and (
+ scripts[script] or
+ scripts[wildcard] or
+ (autoscript and defaultscript(featuretype,autoscript,scripts))
+ )
+ local enabled=languages and (
+ languages[language] or
+ languages[wildcard] or
+ (autolanguage and defaultlanguage(featuretype,autolanguage,languages))
+ )
+ if enabled then
return { valid,autofeatures[kind] or false,sequence,kind }
end
end
@@ -13835,6 +13966,8 @@ function otf.dataset(tfmdata,font)
local language=properties.language or "dflt"
local script=properties.script or "dflt"
local enabled=shared.features
+ local autoscript=enabled and enabled.autoscript
+ local autolanguage=enabled and enabled.autolanguage
local res=resolved[font]
if not res then
res={}
@@ -13852,7 +13985,7 @@ function otf.dataset(tfmdata,font)
rs[language]=rl
local sequences=tfmdata.resources.sequences
for s=1,#sequences do
- local v=enabled and initialize(sequences[s],script,language,enabled)
+ local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage)
if v then
rl[#rl+1]=v
end
@@ -13882,57 +14015,57 @@ local function kernrun(disc,run)
if not pre then
elseif prev then
local nest=getprev(pre)
- setfield(pre,"prev",prev)
- setfield(prev,"next",pre)
+ setprev(pre,prev)
+ setnext(prev,pre)
run(prevmarks,"preinjections")
- setfield(pre,"prev",nest)
- setfield(prev,"next",disc)
+ setprev(pre,nest)
+ setnext(prev,disc)
else
run(pre,"preinjections")
end
if not post then
elseif next then
local tail=find_node_tail(post)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
run(post,"postinjections",next)
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setnext(tail,nil)
+ setprev(next,disc)
else
run(post,"postinjections")
end
if not replace and prev and next then
- setfield(prev,"next",next)
- setfield(next,"prev",prev)
+ setnext(prev,next)
+ setprev(next,prev)
run(prevmarks,"injections",next)
- setfield(prev,"next",disc)
- setfield(next,"prev",disc)
+ setnext(prev,disc)
+ setprev(next,disc)
elseif prev and next then
local tail=find_node_tail(replace)
local nest=getprev(replace)
- setfield(replace,"prev",prev)
- setfield(prev,"next",replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setprev(replace,prev)
+ setnext(prev,replace)
+ setnext(tail,next)
+ setprev(next,tail)
run(prevmarks,"replaceinjections",next)
- setfield(replace,"prev",nest)
- setfield(prev,"next",disc)
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setprev(replace,nest)
+ setnext(prev,disc)
+ setnext(tail,nil)
+ setprev(next,disc)
elseif prev then
local nest=getprev(replace)
- setfield(replace,"prev",prev)
- setfield(prev,"next",replace)
+ setprev(replace,prev)
+ setnext(prev,replace)
run(prevmarks,"replaceinjections")
- setfield(replace,"prev",nest)
- setfield(prev,"next",disc)
+ setprev(replace,nest)
+ setnext(prev,disc)
elseif next then
local tail=find_node_tail(replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
run(replace,"replaceinjections",next)
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setnext(tail,nil)
+ setprev(next,disc)
else
run(replace,"replaceinjections")
end
@@ -13979,21 +14112,21 @@ local function testrun(disc,trun,crun)
local prev=getprev(disc)
if prev then
local tail=find_node_tail(replace)
- setfield(tail,"next",next)
- setfield(next,"prev",tail)
+ setnext(tail,next)
+ setprev(next,tail)
if trun(replace,next) then
setfield(disc,"replace",nil)
- setfield(prev,"next",replace)
- setfield(replace,"prev",prev)
- setfield(next,"prev",tail)
- setfield(tail,"next",next)
- setfield(disc,"prev",nil)
- setfield(disc,"next",nil)
+ setnext(prev,replace)
+ setprev(replace,prev)
+ setprev(next,tail)
+ setnext(tail,next)
+ setprev(disc,nil)
+ setnext(disc,nil)
flush_node_list(disc)
return replace
else
- setfield(tail,"next",nil)
- setfield(next,"prev",disc)
+ setnext(tail,nil)
+ setprev(next,disc)
end
else
end
@@ -14011,19 +14144,19 @@ local function discrun(disc,drun,krun)
report_run("disc")
end
if next and prev then
- setfield(prev,"next",next)
+ setnext(prev,next)
drun(prev)
- setfield(prev,"next",disc)
+ setnext(prev,disc)
end
local pre=getfield(disc,"pre")
if not pre then
elseif prev then
local nest=getprev(pre)
- setfield(pre,"prev",prev)
- setfield(prev,"next",pre)
+ setprev(pre,prev)
+ setnext(prev,pre)
krun(prev,"preinjections")
- setfield(pre,"prev",nest)
- setfield(prev,"next",disc)
+ setprev(pre,nest)
+ setnext(prev,disc)
else
krun(pre,"preinjections")
end
@@ -14281,6 +14414,40 @@ local function featuresprocessor(head,font,attr)
end
elseif id==math_code then
start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ local dir=getfield(start,"dir")
+ if dir=="+TLT" then
+ topstack=topstack+1
+ dirstack[topstack]=dir
+ rlmode=1
+ elseif dir=="+TRT" then
+ topstack=topstack+1
+ dirstack[topstack]=dir
+ rlmode=-1
+ elseif dir=="-TLT" or dir=="-TRT" then
+ topstack=topstack-1
+ rlmode=dirstack[topstack]=="+TRT" and -1 or 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
+ start=getnext(start)
+ elseif id==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=getnext(start)
else
start=getnext(start)
end
@@ -14501,6 +14668,40 @@ local function featuresprocessor(head,font,attr)
end
elseif id==math_code then
start=getnext(end_of_math(start))
+ elseif id==dir_code then
+ local dir=getfield(start,"dir")
+ if dir=="+TLT" then
+ topstack=topstack+1
+ dirstack[topstack]=dir
+ rlmode=1
+ elseif dir=="+TRT" then
+ topstack=topstack+1
+ dirstack[topstack]=dir
+ rlmode=-1
+ elseif dir=="-TLT" or dir=="-TRT" then
+ topstack=topstack-1
+ rlmode=dirstack[topstack]=="+TRT" and -1 or 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
+ start=getnext(start)
+ elseif id==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=getnext(start)
else
start=getnext(start)
end
@@ -14636,10 +14837,10 @@ local function split(replacement,original)
end
return result
end
-local valid={
- coverage={ chainsub=true,chainpos=true,contextsub=true },
+local valid={
+ coverage={ chainsub=true,chainpos=true,contextsub=true,contextpos=true },
reversecoverage={ reversesub=true },
- glyphs={ chainsub=true,chainpos=true },
+ glyphs={ chainsub=true,chainpos=true,contextsub=true,contextpos=true },
}
local function prepare_contextchains(tfmdata)
local rawdata=tfmdata.shared.rawdata
@@ -15952,7 +16153,7 @@ end -- closure
do -- begin closure to overcome local limits and interference
-if not modules then modules={} end modules ['luatex-font-def']={
+if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
comment="companion to luatex-*.tex",
author="Hans Hagen, PRAGMA-ADE, Hasselt NL",
diff --git a/src/luaotfload-auxiliary.lua b/src/luaotfload-auxiliary.lua
index c50e0cd..11d3101 100644
--- a/src/luaotfload-auxiliary.lua
+++ b/src/luaotfload-auxiliary.lua
@@ -15,7 +15,7 @@ luaotfload.aux = luaotfload.aux or { }
local aux = luaotfload.aux
local log = luaotfload.log
-local report = log.report
+local logreport = log.report
local fonthashes = fonts.hashes
local encodings = fonts.encodings
local identifiers = fonthashes.identifiers
@@ -54,8 +54,8 @@ local start_rewrite_fontname = function ()
rewrite_fontname,
"luaotfload.rewrite_fontname")
rewriting = true
- report ("log", 1, "aux",
- "start rewriting tfmdata.name field")
+ logreport ("log", 1, "aux",
+ "start rewriting tfmdata.name field")
end
end
@@ -66,8 +66,8 @@ local stop_rewrite_fontname = function ()
luatexbase.remove_from_callback
("luaotfload.patch_font", "luaotfload.rewrite_fontname")
rewriting = false
- report ("log", 1, "aux",
- "stop rewriting tfmdata.name field")
+ logreport ("log", 1, "aux",
+ "stop rewriting tfmdata.name field")
end
end
@@ -393,7 +393,7 @@ do
local load_chardef = function ()
- report ("both", 1, "aux", "Loading character metadata from %s.", chardef)
+ logreport ("both", 1, "aux", "Loading character metadata from %s.", chardef)
chardata = dofile (kpse.find_file (chardef, "lua"))
if chardata == nil then
@@ -452,18 +452,18 @@ local provides_script = function (font_id, asked_script)
--- where method: "gpos" | "gsub"
for feature, data in next, featuredata do
if data[asked_script] then
- report ("log", 1, "aux",
- "font no %d (%s) defines feature %s for script %s",
- font_id, fontname, feature, asked_script)
+ logreport ("log", 1, "aux",
+ "font no %d (%s) defines feature %s for script %s",
+ font_id, fontname, feature, asked_script)
return true
end
end
end
- report ("log", 0, "aux",
- "font no %d (%s) defines no feature for script %s",
- font_id, fontname, asked_script)
+ logreport ("log", 0, "aux",
+ "font no %d (%s) defines no feature for script %s",
+ font_id, fontname, asked_script)
end
- report ("log", 0, "aux", "no font with id %d", font_id)
+ logreport ("log", 0, "aux", "no font with id %d", font_id)
return false
end
@@ -491,21 +491,21 @@ local provides_language = function (font_id, asked_script, asked_language)
for feature, data in next, featuredata do
local scriptdata = data[asked_script]
if scriptdata and scriptdata[asked_language] then
- report ("log", 1, "aux",
- "font no %d (%s) defines feature %s "
- .. "for script %s with language %s",
- font_id, fontname, feature,
- asked_script, asked_language)
+ logreport ("log", 1, "aux",
+ "font no %d (%s) defines feature %s "
+ .. "for script %s with language %s",
+ font_id, fontname, feature,
+ asked_script, asked_language)
return true
end
end
end
- report ("log", 0, "aux",
- "font no %d (%s) defines no feature "
- .. "for script %s with language %s",
- font_id, fontname, asked_script, asked_language)
+ logreport ("log", 0, "aux",
+ "font no %d (%s) defines no feature "
+ .. "for script %s with language %s",
+ font_id, fontname, asked_script, asked_language)
end
- report ("log", 0, "aux", "no font with id %d", font_id)
+ logreport ("log", 0, "aux", "no font with id %d", font_id)
return false
end
@@ -564,20 +564,20 @@ local provides_feature = function (font_id, asked_script,
if feature then
local scriptdata = feature[asked_script]
if scriptdata and scriptdata[asked_language] then
- report ("log", 1, "aux",
- "font no %d (%s) defines feature %s "
- .. "for script %s with language %s",
- font_id, fontname, asked_feature,
- asked_script, asked_language)
+ logreport ("log", 1, "aux",
+ "font no %d (%s) defines feature %s "
+ .. "for script %s with language %s",
+ font_id, fontname, asked_feature,
+ asked_script, asked_language)
return true
end
end
end
- report ("log", 0, "aux",
- "font no %d (%s) does not define feature %s for script %s with language %s",
- font_id, fontname, asked_feature, asked_script, asked_language)
+ logreport ("log", 0, "aux",
+ "font no %d (%s) does not define feature %s for script %s with language %s",
+ font_id, fontname, asked_feature, asked_script, asked_language)
end
- report ("log", 0, "aux", "no font with id %d", font_id)
+ logreport ("log", 0, "aux", "no font with id %d", font_id)
return false
end
diff --git a/src/luaotfload-features.lua b/src/luaotfload-features.lua
index d212df5..3f9d67a 100644
--- a/src/luaotfload-features.lua
+++ b/src/luaotfload-features.lua
@@ -941,6 +941,7 @@ local report_otf = logs.reporter("fonts","otf loading")
--- start locals for addfeature()
local utfbyte = unicode.utf8.byte
+local utfchar = unicode.utf8.char
local otf = handlers and handlers.otf --- filled in later during initialization
@@ -1158,18 +1159,17 @@ local function current_addfeature(data,feature,specifications)
end
local askedfeatures = specification.features or everywhere
local askedsteps = specifications.steps or specification.subtables or { specification.data } or { }
- local defaulttype = specification.type or "substitution"
+ local featuretype = normalized[specification.type or "substitution"] or "substitution"
local featureflags = specification.flags or noflags
local featureorder = specification.order or { feature }
local added = false
local nofsteps = 0
local steps = { }
for i=1,#askedsteps do
- local list = askedsteps[i]
- local coverage = { }
- local cover = coveractions[featuretype]
- local format = nil
- local featuretype = normalized[list.type or defaulttype] or "substitution"
+ local list = askedsteps[i]
+ local coverage = { }
+ local cover = coveractions[featuretype]
+ local format = nil
if not cover then
-- unknown
elseif featuretype == "substitution" then
@@ -1355,11 +1355,8 @@ local function current_addfeature(data,feature,specifications)
end
end
-
---[[ end snippet from font-otc.lua ]]
-local tlig_order = { "tlig" }
-
local tlig_specification = {
{
type = "substitution",
@@ -1370,7 +1367,7 @@ local tlig_specification = {
[0x0060] = 0x2018, -- quoteright
},
flags = noflags,
- order = tlig_order,
+ order = { "tlig" },
prepend = true,
},
{
@@ -1390,7 +1387,7 @@ local tlig_specification = {
[0x00BB] = {0x003E, 0x003E}, -- RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
},
flags = noflags,
- order = tlig_order,
+ order = { "tlig" },
prepend = true,
},
{
@@ -1403,11 +1400,24 @@ local tlig_specification = {
[0x00BF] = {0x003F, 0x0060}, -- questiondown
},
flags = noflags,
- order = tlig_order,
+ order = { "tlig" },
prepend = true,
},
}
+local tlig_specification = {
+ type = "substitution",
+ features = everywhere,
+ data = {
+ [0x0022] = 0x201D, -- quotedblright
+ [0x0027] = 0x2019, -- quoteleft
+ [0x0060] = 0x2018, -- quoteright
+ },
+ flags = noflags,
+ order = { "tlig" },
+ prepend = true,
+}
+
local anum_arabic = { --- these are the same as in font-otc
[0x0030] = 0x0660,
[0x0031] = 0x0661,
@@ -1466,9 +1476,65 @@ local anum_specification = {
},
}
+local rot13_specification = {
+ type = "substitution",
+ features = everywhere,
+ data = {
+ [65] = 78, [ 97] = 110, [78] = 65, [110] = 97,
+ [66] = 79, [ 98] = 111, [79] = 66, [111] = 98,
+ [67] = 80, [ 99] = 112, [80] = 67, [112] = 99,
+ [68] = 81, [100] = 113, [81] = 68, [113] = 100,
+ [69] = 82, [101] = 114, [82] = 69, [114] = 101,
+ [70] = 83, [102] = 115, [83] = 70, [115] = 102,
+ [71] = 84, [103] = 116, [84] = 71, [116] = 103,
+ [72] = 85, [104] = 117, [85] = 72, [117] = 104,
+ [73] = 86, [105] = 118, [86] = 73, [118] = 105,
+ [74] = 87, [106] = 119, [87] = 74, [119] = 106,
+ [75] = 88, [107] = 120, [88] = 75, [120] = 107,
+ [76] = 89, [108] = 121, [89] = 76, [121] = 108,
+ [77] = 90, [109] = 122, [90] = 77, [122] = 109,
+ },
+ flags = noflags,
+ order = { "rot13" },
+ prepend = true,
+}
+
+local extrafeatures = {
+ tlig = { tlig_specification, "tex ligatures and substitutions" },
+ anum = { anum_specification, "arabic numerals" },
+ rot13 = { rot13_specification, "rot13" },
+}
+
+function add_otf_feature (name, specification)
+ if type (name) == "table" then
+ specification = name
+ name = specification.name
+ end
+ if type (name) == "string" then
+ extrafeatures[name] = specification
+ end
+end
+
+otf.addfeature = add_otf_feature
+
+local install_extra_features = function (data, filename, raw)
+ for feature, specification in next, extrafeatures do
+ logreport ("both", 3, "features",
+ "register synthetic feature “%s” for %s font “%s”(%d)",
+ feature,
+ data.format,
+ tostring (data.metadata and data.metadata.fontname or "<unknown>"),
+ data.subfont or -1)
+ otf.features.register { name = feature, description = specification[2] }
+ otf.enhancers.addfeature (data, feature, specification[1])
+ end
+end
+
return {
init = function ()
+ logreport = luaotfload.log.report
+
if not fonts and fonts.handlers then
logreport ("log", 0, "features",
"OTF mechanisms missing -- did you forget to \z
@@ -1478,41 +1544,13 @@ return {
otf = fonts.handlers.otf
- local extrafeatures = {
- tlig = tlig_specification,
- trep = { },
- anum = anum_specification,
- }
-
--- hack for backwards compat with TL2014 loader
- local addfeature = otf.version < 2.8 and current_addfeature
- or ancient_addfeature
+ otf.enhancers.addfeature = otf.version < 2.8 and ancient_addfeature
+ or current_addfeature
otf.enhancers.register ("check extra features",
- function (data, filename, raw)
- for feature, specification in next, extrafeatures do
- logreport ("both", 3, "features",
- "register synthetic feature “%s” for %s font “%s”(%d)",
- feature,
- data.format,
- tostring (data.metadata and data.metadata.fontname or "<unknown>"),
- data.subfont or -1)
- addfeature (data, feature, specification)
- end
- end)
-
- logreport = luaotfload.log.report
- if not fonts then
- logreport ("log", 0, "features",
- "OTF mechanisms missing -- did you forget to \z
- load a font loader?")
- return false
- end
+ install_extra_features)
- otf.features.register {
- name = "anum",
- description = "arabic digits",
- }
return true
end
}
diff --git a/src/luaotfload-init.lua b/src/luaotfload-init.lua
index 895e32e..d471152 100644
--- a/src/luaotfload-init.lua
+++ b/src/luaotfload-init.lua
@@ -65,6 +65,43 @@ local logreport --- filled in after loading the log module
--doc]]--
+local glyph_codes =
+ { [0] = "character"
+ , [1] = "glyph"
+ , [2] = "ligature"
+ , [3] = "ghost"
+ , [4] = "left"
+ , [5] = "right"
+ }
+
+local disc_codes =
+ { [0] = "discretionary"
+ , [1] = "explicit"
+ , [2] = "automatic"
+ , [3] = "regular"
+ , [4] = "first"
+ , [5] = "second"
+ }
+
+local node_types = { disc = disc_codes, glyph = glyph_codes }
+
+local luatex_stubs = function ()
+ if not node.subtypes then
+ node.subtypes = function (t) return node_types [t] or { } end
+ local direct = node.direct
+
+ local getfield = direct.getfield
+ local setfield = direct.setfield
+
+ direct.setchar = direct.setchar or function (n, ...) setfield (n, "char", ...) end
+ direct.setprev = direct.setprev or function (n, ...) setfield (n, "prev", ...) end
+ direct.setnext = direct.setnext or function (n, ...) setfield (n, "next", ...) end
+
+ direct.getchar = direct.getchar or function (n) getfield (n, "char") end
+ direct.getprev = direct.getprev or function (n) getfield (n, "prev") end
+ direct.getnext = direct.getnext or function (n) getfield (n, "next") end
+ end
+end
local init_early = function ()
@@ -82,6 +119,8 @@ local init_early = function ()
if not lualibs then error "this module requires Luaotfload" end
if not luaotfload then error "this module requires Luaotfload" end
+ luatex_stubs ()
+
--[[doc--
The logger needs to be in place prior to loading the fontloader due
@@ -214,9 +253,9 @@ local context_modules = {
{ ctx, "font-oti" },
{ ctx, "font-otf" },
{ ctx, "font-otb" },
- { ltx, "luatex-fonts-inj" }, --> since 2014-01-07, replaces node-inj.lua
+ { ltx, "font-inj" },
{ ltx, "luatex-fonts-ota" },
- { ltx, "luatex-fonts-otn" }, --> since 2014-01-07, replaces font-otn.lua
+ { ltx, "font-otn" },
{ ctx, "font-otp" }, --> since 2013-04-23
{ ltx, "luatex-fonts-lua" },
{ ctx, "font-def" },
@@ -338,9 +377,9 @@ local init_main = function ()
load_fontloader_module "font-oti"
load_fontloader_module "font-otf"
load_fontloader_module "font-otb"
- load_fontloader_module "fonts-inj" --> since 2014-01-07, replaces node-inj.lua
+ load_fontloader_module "font-inj"
load_fontloader_module "fonts-ota"
- load_fontloader_module "fonts-otn" --> since 2014-01-07, replaces font-otn.lua
+ load_fontloader_module "font-otn"
load_fontloader_module "font-otp" --> since 2013-04-23
load_fontloader_module "fonts-lua"
load_fontloader_module "font-def"